💾 Archived View for gmi.noulin.net › gitRepositories › sodiumTest › file › server4.c.gmi captured on 2023-01-29 at 13:28:36. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
server4.c (3876B)
1 #! /usr/bin/env sheepy 2 3 #include "libsheepyObject.h" 4 5 #include <sys/socket.h> 6 #include <netinet/in.h> 7 8 #include "sel.h" 9 10 int main(int ac, char **av){ 11 12 setLogMode(LOG_FUNC); 13 14 if (not selInit()) ret 1; 15 16 // generate id keys 17 newSignKeys(); 18 // public key 19 newKeys(); 20 21 22 const char* clientPublicFilename = "client4Public.bin"; 23 u8 knownClientPublicKey[crypto_box_PUBLICKEYBYTES]; 24 if (isPath(clientPublicFilename)) { 25 logI("Server found known client session key"); 26 pError0(bLReadFile(clientPublicFilename, knownClientPublicKey, sizeof(knownClientPublicKey))); 27 } 28 else { 29 logE("known client key not found, run client4.c once before starting the server"); 30 } 31 32 33 // start event loop 34 int sock; 35 struct sockaddr_in server; 36 int mysock; 37 char buf[128*1024]; 38 int rval; 39 40 sock = socket(AF_INET, SOCK_STREAM, 0); 41 if (sock < 0){ 42 perror("Failed to create socket"); 43 ret 1; 44 } 45 46 server.sin_family = AF_INET; 47 server.sin_addr.s_addr = INADDR_ANY; 48 server.sin_port = htons(5000); 49 50 if (bind(sock, (struct sockaddr *) &server, sizeof(server))){ 51 perror("bind failed"); 52 ret 1; 53 } 54 55 listen(sock, 5); 56 57 logI("Server started"); 58 forever { 59 mysock = accept(sock, (struct sockaddr *)0, 0); 60 if (mysock == -1) 61 perror("accept failed"); 62 else { 63 64 bool snd(void *buf, size_t sz) { 65 logVarG(sz); 66 if(send(mysock, buf, sz, 0) < 0){ 67 perror("send failed"); 68 close(mysock); 69 ret no; 70 } 71 ret yes; 72 } 73 74 bool rcv(void *buf, size_t sz) { 75 while (sz > 0) { 76 // TODO add timeout 77 rval = recv(mysock, buf, sz, MSG_WAITALL); 78 if (rval < 0) { 79 perror("reading message"); 80 ret no; 81 } 82 else if (rval == 0) { 83 logI("Ending connection"); 84 close(mysock); 85 ret no; 86 } 87 sz -= rval; 88 } 89 ret yes; 90 } 91 92 // store remote public key 93 u8 clientInfo[1 + sizeof(keys.remotePublicKey) + sizeof(keys.nonce)] = init0Var; 94 rcv(clientInfo, sizeof(clientInfo)); 95 96 // check if client public key is known 97 if (memcmp(knownClientPublicKey, clientInfo +1, sizeof(knownClientPublicKey))) { 98 logE("unknown client"); 99 } 100 101 memcpy(keys.remotePublicKey, clientInfo + 1, sizeof(keys.remotePublicKey)); 102 memcpy(keys.nonce, clientInfo + 1 + sizeof(keys.remotePublicKey), sizeof(keys.nonce)); 103 104 logD("Remote public key"); 105 loghex(keys.remotePublicKey, sizeof(keys.remotePublicKey)); 106 put; 107 108 // send public key 109 if (clientInfo[0] == 0) { 110 logD("command 0 - send server public key"); 111 u8 exchange[sizeof(keys.publicKey)] = init0Var; 112 memcpy(exchange, keys.publicKey, sizeof(keys.publicKey)); 113 if (!snd(exchange, sizeof(exchange))) continue; 114 } 115 116 // key exchange 117 if (not computeSharedKeys(SERVER_SESSION_KEYS)) { 118 logE("Invalid client key"); 119 exit(1); 120 } 121 122 // get encrypted message 123 int len; 124 // *nonce is incremented by after sending or receiving a message 125 // *nonce is allowed to wrap from the max value 126 u64 *nonce = (u64*)keys.nonce; 127 if (!rcv(&len, sizeof(len))) continue; 128 rcv(buf, len); 129 130 u8 decrypted[1000]; 131 logVarG(*nonce); 132 len = selDecrypt(decrypted, sizeof(decrypted), buf, len); 133 inc *nonce; 134 135 if (!len) { 136 logE("failed to decrypt"); 137 close(mysock); 138 continue; 139 } 140 141 decrypted[len] = 0; 142 143 logI("decrypted: %s", decrypted); 144 145 // send encrypted response 146 147 char *msg = "OK"; 148 149 logVarG(*nonce); 150 len = selEncrypt(buf, sizeof(buf), msg, strlen(msg)); 151 inc *nonce; 152 153 logVarG(len); 154 155 snd(&len, sizeof(len)); 156 snd(buf, len); 157 158 close(mysock); 159 } 160 } 161 } 162 // vim: set expandtab ts=2 sw=2: