server.c (6199B)
1 #include "packet.h" 2 #include "notification.h" 3 #include <pthread.h> 4 5 socklen_t clilen; 6 struct sockaddr_in cli_address; 7 uint8_t shared_key[SHARED_KEY_SIZE]; 8 int clientfd; 9 10 /* 11 * Initialise socket server 12 */ 13 int socket_init() 14 { 15 int serverfd = socket(AF_INET, SOCK_STREAM, 0); 16 if (serverfd < 0) { 17 error(1, "Error on opening socket"); 18 } 19 20 /* Reuse addr(for debug) */ 21 int optval = 1; 22 if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { 23 24 error(1, "Error at setting SO_REUSEADDR"); 25 } 26 27 struct sockaddr_in sv_addr; 28 memset(&sv_addr, 0, sizeof(sv_addr)); 29 sv_addr.sin_family = AF_INET; 30 sv_addr.sin_addr.s_addr = INADDR_ANY; 31 sv_addr.sin_port = htons(PORT); 32 33 if (bind(serverfd, (struct sockaddr *) &sv_addr, sizeof(sv_addr)) < 0) { 34 error(1, "Error on bind"); 35 } 36 37 if (listen(serverfd, MAX_CONNECTION) < 0) { 38 error(1, "Error on listen"); 39 } 40 41 printf("Listening on port %d\n", PORT); 42 clilen = sizeof(cli_address); 43 return serverfd; 44 } 45 46 /* 47 * Performs key exchange with client 48 */ 49 int key_exchange(int clientfd) 50 { 51 /* Generate the server's key pair */ 52 uint8_t sv_pk[PUBLIC_KEY_SIZE], sv_sk[PRIVATE_KEY_SIZE]; 53 crypto_kx_keypair(sv_pk, sv_sk); 54 55 /* Get public key from client */ 56 uint8_t *pk; 57 if ((pk = get_public_key(clientfd)) == NULL) { 58 return -1; 59 } 60 61 /* Send our public key */ 62 if (send_public_key(clientfd, sv_pk) < 0) { 63 free(pk); 64 return -1; 65 } 66 67 /* Compute a shared key using the client's public key and our secret key. */ 68 if (crypto_kx_server_session_keys(NULL, shared_key, sv_pk, sv_sk, pk) != 0) { 69 error(0, "Client public key is not acceptable"); 70 free(pk); 71 close(clientfd); 72 return -1; 73 } 74 75 free(pk); 76 return 0; 77 } 78 79 void signal_handler(int signal) 80 { 81 switch (signal) { 82 case SIGPIPE: 83 error(0, "SIGPIPE received"); 84 break; 85 case SIGABRT: 86 case SIGINT: 87 case SIGTERM: 88 notify_uninit(); 89 error(1, "Shutdown signal received"); 90 break; 91 } 92 } 93 94 void *receiver() 95 { 96 int serverfd = socket_init(); 97 clientfd = accept(serverfd, (struct sockaddr *) &cli_address, &clilen); 98 if (clientfd < 0) { 99 error(0, "Error on accepting client"); 100 /* Continue accpeting connections */ 101 /* continue; */ 102 } 103 104 if (key_exchange(clientfd) < 0) { 105 error(0, "Error performing key exchange with client"); 106 /* continue; */ 107 } 108 while (1) { 109 message msg; 110 memset(&msg, 0, sizeof(msg)); 111 if (recv_packet(&msg, clientfd) != ZSM_STA_SUCCESS) { 112 close(clientfd); 113 break; 114 /* continue; */ 115 } 116 117 size_t encrypted_len = msg.length - NONCE_SIZE; 118 size_t msg_len = encrypted_len - ADDITIONAL_SIZE; 119 uint8_t nonce[NONCE_SIZE]; 120 uint8_t encrypted[encrypted_len]; 121 uint8_t decrypted[msg_len + 1]; 122 unsigned long long decrypted_len; 123 memcpy(nonce, msg.data, NONCE_SIZE); 124 memcpy(encrypted, msg.data + NONCE_SIZE, encrypted_len); 125 126 free(msg.data); 127 if (crypto_aead_xchacha20poly1305_ietf_decrypt(decrypted, &decrypted_len, 128 NULL, 129 encrypted, encrypted_len, 130 NULL, 0, 131 nonce, shared_key) != 0) { 132 error(0, "Cannot decrypt message"); 133 } else { 134 /* Decrypted message */ 135 decrypted[msg_len] = '\0'; 136 printf("Decrypted: %s\n", decrypted); 137 send_notification(decrypted); 138 msg.data = malloc(14); 139 strcpy(msg.data, "Received data"); 140 msg.length = 14; 141 send_packet(&msg, clientfd); 142 free(msg.data); 143 } 144 } 145 close(clientfd); 146 close(serverfd); 147 return NULL; 148 } 149 150 void *sender() 151 { 152 while (1) { 153 printf("Enter message to send to client: "); 154 fflush(stdout); 155 char line[1024]; 156 line[0] = '\0'; 157 size_t length = strlen(line); 158 while (length <= 1) { 159 fgets(line, sizeof(line), stdin); 160 length = strlen(line); 161 } 162 length -= 1; 163 line[length] = '\0'; 164 165 uint8_t nonce[NONCE_SIZE]; 166 uint8_t encrypted[length + ADDITIONAL_SIZE]; 167 unsigned long long encrypted_len; 168 169 randombytes_buf(nonce, sizeof(nonce)); 170 crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_len, 171 line, length, 172 NULL, 0, NULL, nonce, shared_key); 173 size_t payload_t = NONCE_SIZE + encrypted_len; 174 uint8_t encryptedwithnonce[payload_t]; 175 memcpy(encryptedwithnonce, nonce, NONCE_SIZE); 176 memcpy(encryptedwithnonce + NONCE_SIZE, encrypted, encrypted_len); 177 178 message *msg = create_packet(1, 0x10, payload_t, encryptedwithnonce); 179 if (send_packet(msg, clientfd) != ZSM_STA_SUCCESS) { 180 close(clientfd); 181 } 182 free_packet(msg); 183 } 184 close(clientfd); 185 return NULL; 186 } 187 188 int main() 189 { 190 if (sodium_init() < 0) { 191 error(1, "Error initializing libsodium"); 192 } 193 /* Init libnotify with app name */ 194 if (notify_init("zsm") < 0) { 195 error(1, "Error initializing libnotify"); 196 } 197 signal(SIGPIPE, signal_handler); 198 signal(SIGABRT, signal_handler); 199 signal(SIGINT, signal_handler); 200 signal(SIGTERM, signal_handler); 201 202 pthread_t recv_worker, send_worker; 203 if (pthread_create(&recv_worker, NULL, sender, NULL) != 0) { 204 fprintf(stderr, "Error creating incoming thread\n"); 205 return 1; 206 } 207 208 if (pthread_create(&send_worker, NULL, receiver, NULL) != 0) { 209 fprintf(stderr, "Error creating outgoing thread\n"); 210 return 1; 211 } 212 213 // Join threads 214 pthread_join(recv_worker, NULL); 215 pthread_join(send_worker, NULL); 216 217 return 0; 218 }