static int handle_handshake_request (BlockTxServer *server) { HandshakeRequest req; struct evbuffer *input = server->recv_buf; unsigned char *enc_session_key; if (!server->session_key_len) { if (evbuffer_get_length (input) < sizeof(req)) return 0; evbuffer_remove (input, &req, sizeof(req)); req.version = ntohl (req.version); server->version = MIN (req.version, BLOCK_PROTOCOL_VERSION); if (server->version != 1 && server->version != 2) { seaf_warning ("Bad block protocol version %d.\n", server->version); send_handshake_response (server, STATUS_VERSION_MISMATCH); return -1; } seaf_debug ("Block protocol version %d.\n", server->version); server->session_key_len = ntohl (req.key_len); if (server->session_key_len > MAX_SESSION_KEY_SIZE) { seaf_warning ("Encrypted session key is too long: %d.\n", server->session_key_len); send_handshake_response (server, STATUS_BAD_REQUEST); return -1; } } if (evbuffer_get_length (input) < server->session_key_len) return 0; enc_session_key = g_malloc (server->session_key_len); evbuffer_remove (input, enc_session_key, server->session_key_len); if (process_session_key (server, enc_session_key) < 0) { g_free (enc_session_key); return -1; } g_free (enc_session_key); if (send_handshake_response (server, STATUS_OK) < 0) return -1; seaf_debug ("recv_state set to AUTH.\n"); server->parser.content_cb = handle_auth_req_content_cb; server->recv_state = RECV_STATE_AUTH; return 0; }
static int process_session_key (BlockTxServer *server, unsigned char *enc_session_key) { char *enc_key_b64 = NULL, *key_b64 = NULL; unsigned char *session_key = NULL; gsize len; SearpcClient *client = NULL; int ret = 0; client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "ccnet-rpcserver"); if (!client) { seaf_warning ("Failed to create rpc client.\n"); send_handshake_response (server, STATUS_INTERNAL_SERVER_ERROR); ret = -1; goto out; } enc_key_b64 = g_base64_encode (enc_session_key, server->session_key_len); key_b64 = ccnet_privkey_decrypt (client, enc_key_b64); if (!key_b64) { seaf_warning ("Failed to decrypt session key.\n"); send_handshake_response (server, STATUS_INTERNAL_SERVER_ERROR); ret = -1; goto out; } session_key = g_base64_decode (key_b64, &len); if (server->version == 1) blocktx_generate_encrypt_key (session_key, len, server->key, server->iv); else if (server->version == 2) blocktx_generate_encrypt_key (session_key, len, server->key_v2, server->iv_v2); init_frame_parser (server); out: g_free (enc_key_b64); g_free (key_b64); g_free (session_key); ccnet_rpc_client_free (client); return ret; }
void perform_actions(int sock,char *input_file) { char buffer[169] = {0}; char output_file[300] = {0}; strcpy(output_file,input_file); strcat(output_file,".decrypted"); //printf("Output_file: %s\n",output_file); while(1) { memset(buffer,0,169); int x = receive_msg(sock,buffer); switch(x) { case HANDSHAKE: { //printf("Server handshake has arrived on client\n"); send_handshake_response(sock); FILE *fd = fopen(input_file,"r"); FILE *foutput = fopen(output_file,"w"); // Here come all the requests. while(read_line(fd, buffer)) { //printf("%s\n",buffer); send_decryption_request(sock,buffer,strlen(buffer)); x = receive_msg(sock,buffer); if(x != RESPONSE_MESSAGE) { perror("Wrong server response"); break; } int msg_len = *((int *)(buffer+sizeof(int))); for(int i = 0; i < msg_len; i++) { // printf("%c",buffer[i+2*sizeof(int)]); fprintf(foutput,"%c",buffer[i+2*sizeof(int)]); } fprintf(foutput,"\n"); } fclose(foutput); fclose(fd); send_end_of_request(sock); return; break; } // case RESPONSE_MESSAGE: // { // printf("Server response message has arrived on client\n"); // dump_payload(buffer); // break; // } case ERROR_MESSAGE: { printf("Error message has arrived on client\n"); dump_payload(buffer); return; break; } default: { printf("Unknown %d msg type has arrived on client\n",x); char aux[] = "Unknown msg type has arrived on client"; send_error_message(sock,aux,strlen(aux)); return; break; } } } // End while }