sodiumTest

Libsodium examples, client/server system
git clone https://noulin.net/git/sodiumTest.git
Log | Files | Refs | README

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: