inline buffer rsa_key::private_decrypt(const buffer& buf, int padding) const { buffer result(size()); result.data().resize(private_decrypt(buffer_cast<uint8_t>(result), buffer_size(result), buffer_cast<uint8_t>(buf), buffer_size(buf), padding)); return result; }
void read_client_msg(Client* client, int read_fd) { rb_red_blk_node* transfer = RBExactQuery(client->transfers, &read_fd); File_msg* file_msg = (File_msg*)(transfer->info); int valread = read(read_fd, file_msg->msg.buffer+file_msg->msg.offset, BUFFER_SIZE-file_msg->msg.offset); if(valread == 0) { logger("<Client><read_client_msg>client disconnected\n"); RBDelete(client->transfers, transfer); close(read_fd); FD_CLR(read_fd, &(client->fd_read_set)); FD_CLR(read_fd, &(client->fd_write_set)); return; } file_msg->msg.offset += valread; if(file_msg->msg.offset == BUFFER_SIZE) { if(file_msg->aes_key[0] == '\0') { if(ENCRYPTION_ENABLED) { logger("<Client><read_client_msg>got a full RSA message from another client\n"); char encrypted[BUFFER_SIZE]; for(int i = 0; i<BUFFER_SIZE; ++i) encrypted[i] = file_msg->msg.buffer[i]; private_decrypt(encrypted,BUFFER_SIZE,client->keypair,file_msg->msg.buffer); } char command = file_msg->msg.buffer[0]; if(command == 'r') { logger("<Client><read_client_msg>got a request message\n"); /*rname token AES => cname ip token*/ sscanf(file_msg->msg.buffer+1, "%s %s %s", file_msg->file_name, file_msg->token, file_msg->aes_key); struct sockaddr address; int add_len = sizeof(address); getpeername(read_fd, (struct sockaddr*)&(address), (socklen_t*)&(add_len)); struct in_addr ip_struct; inet_aton(address.sa_data, & ip_struct); int ip = ip_struct.s_addr; RBTreeInsert(client->waiting_list, file_msg->token, &read_fd); sprintf(client->server_msg.buffer, "c%s %d %s", file_msg->file_name, ip, file_msg->token); FD_SET(client->maintainer_fd, &(client->fd_write_set)); file_msg->msg.offset=0; } else { exit(1); } } else { if(ENCRYPTION_ENABLED) { char partial_msg[128]; for(int i = 0; i < (BUFFER_SIZE/128); ++i) { for(int j=0; j<128; ++j) partial_msg[j] = file_msg->msg.buffer[i*128+j]; AES128_ECB_decrypt(partial_msg,file_msg->aes_key,file_msg->msg.buffer+i*128); } logger("<Client><read_client_msg>AES decrypted the message\n"); } if(file_msg->file_fd == -1) { /*ttoken size => in data mode*/ char token[8]; sscanf(file_msg->msg.buffer, "t%s %d", token, file_msg->msg.total_len); logger("<Client><read_client_msg>got a transfer message with %s for and with size %d\n", token, file_msg->msg.total_len); file_msg->token[0] = '\0'; file_msg->msg.offset=0; } else { /*read data mode (write to file)*/ if(ENCRYPTION_ENABLED) { char file_write_buffer[BUFFER_SIZE]; AES128_ECB_decrypt(file_msg->msg.buffer, file_msg->aes_key, file_write_buffer); file_msg->msg.offset += write(file_msg->file_fd, file_write_buffer, (file_msg->msg.total_len-file_msg->msg.offset) > 0 ? BUFFER_SIZE : (file_msg->msg.total_len-file_msg->msg.offset)); } else file_msg->msg.offset += write(file_msg->file_fd, file_msg->msg.buffer, (file_msg->msg.total_len-file_msg->msg.offset) > 0 ? BUFFER_SIZE : (file_msg->msg.total_len-file_msg->msg.offset)); logger("<Client><read_client_msg>wrote to file\n"); if(file_msg->msg.offset == file_msg->msg.total_len) close(file_msg->file_fd); } } } }
int main() { char sendline[_MAX_BUFF] = ""; string return_value; int pid; string user_name, item_price; /* Create a TCP socket */ char *ptr_price, *ptr_dprice, *ptr_de1, *ptr_en, *ptr_de2; char recvline[_MAX_BUFF]; listenfd = socket(AF_INET, SOCK_STREAM, 0); /* Initialize server's address and well-known port */ bzero(&servaddr, sizeof (servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(1200); /* daytime server */ /* Bind server’s address and port to the socket */ bind(listenfd, (struct sockaddr *) &servaddr, sizeof (servaddr)); /* Convert socket to a listening socket – max 100 pending clients*/ listen(listenfd, 100); cout << "bank hello" << endl; /* Wait for client connections and accept them */ while (true) { clilen = sizeof (cliaddr); connfd = accept(listenfd, (struct sockaddr *) &cliaddr, (socklen_t*) & clilen); if (connfd < 0) { perror("ERROR on accept"); exit(5); } if ((pid = fork()) == 0) { close(listenfd); //Child server; bzero(recvline, sizeof (recvline)); //read card number from psystem if (read(connfd, recvline, sizeof (recvline)) > 0) { ptr_en = recvline; ptr_de1 = public_decrypt(ptr_en, PSYS_PUB_K); if (ptr_de1 != NULL) { cout << "Verfiy the psystem digital signature" << endl; } ptr_de2 = private_decrypt(ptr_de1, BANK_PRI_K); bzero(recvline, sizeof (recvline)); } if (read(connfd, recvline, sizeof (recvline)) > 0) { ptr_price = recvline; ptr_dprice = public_decrypt(ptr_price, PSYS_PUB_K); item_price = ptr_dprice; return_value = renew_account(ptr_de2, ptr_dprice); strncat(sendline, return_value.c_str(), return_value.size()); write(connfd, sendline, strlen(sendline)); bzero(recvline, sizeof (recvline)); } if (read(connfd, recvline, sizeof (recvline)) > 0) { cout << "Customer:" << recvline << endl; user_name = recvline; if (return_value == str_success) { renew_activity(user_name, item_price); } bzero(recvline, sizeof (recvline)); } close(connfd); exit(0); } close(connfd); //Parent server; } return 0; }
void* SomeAwesomeThings(void* Param){ Client* theClient = (Client*)Param; char* message = (char*)malloc(4086); char sendMessage[4086]; char encrypt[4086]; char* receiver; char* tmp; char* ender; char* err; Client* ClientCounter; int msgSize; int usernameSet = 0; int nameLength; int sub_msg_len; int encrypt_len; //RC4 component RC4Container RC4key; int iter1; int iter2; RC4key.iter1 = &iter1; RC4key.iter2 = &iter2; int RC4KeySet = 0; // unsigned char hash_out[SHA_DIGEST_LENGTH + 1]; char hash_string[SHA_DIGEST_LENGTH * 2 + 1]; int iterator; memset(sendMessage, '\0', sizeof(sendMessage)); err = (char*) malloc(130); // if((msgSize = read(theClient->sockfd, message, sizeof(message) - 1)) > 0){ // message[msgSize] = '\0'; // int nameLength = strstr(message, "\r\n.\r\n") - message; // for(msgSize = 0; msgSize < nameLength; msgSize++){ // theClient->Name[msgSize] = message[msgSize]; // } // theClient->Name[nameLength] = '\0'; // printf("%s has connected\n", theClient->Name); // } while((msgSize = read(theClient->sockfd, message, 4086 - 1)) > 0){ message[msgSize] = '\0'; sub_msg_len = 0; while((ender = strstr(message, "\r\n.\r\n")) != NULL){ // *ender = '\0'; sub_msg_len += ender - message + 5; if(sub_msg_len > msgSize) break; // printf("%s\n", message); //Do things here tmp = strstr(message, "\r\n"); *tmp = '\0'; printf("%s\n", message); if(strcmp(message, "Mode: Public") == 0){ tmp = tmp + 2; nameLength = strstr(tmp, "\r\n.\r\n") - tmp + 5; sprintf(sendMessage,"%s\r\nUser: %s\r\n", message, theClient->Name); strncat(sendMessage, tmp, nameLength); for(ClientCounter = head; ClientCounter != NULL; ClientCounter = ClientCounter->Next){ if(ClientCounter == theClient) continue; write(ClientCounter->sockfd, sendMessage, sizeof(sendMessage)); } } else if((strcmp(message, "Mode: Private") == 0) || (strcmp(message, "Mode: InitPriv") == 0) || (strcmp(message, "Mode: AccPriv") == 0) ){ tmp = tmp + 2; tmp = strstr(tmp, " ") + 1; receiver = tmp; tmp = strstr(tmp, "\r\n"); *tmp = '\0'; tmp = tmp + 2; nameLength = strstr(tmp, "\r\n.\r\n") - tmp + 5; sprintf(sendMessage,"%s\r\nUser: %s\r\n", message, theClient->Name); strncat(sendMessage, tmp, nameLength); for(ClientCounter = head; ClientCounter != NULL; ClientCounter = ClientCounter->Next){ if(strcmp(receiver, ClientCounter->Name) == 0){ write(ClientCounter->sockfd, sendMessage, sizeof(sendMessage)); break; } } } else if(strcmp(message, "Mode: GetList") == 0){ sprintf(sendMessage, "Mode: List\r\n"); for(ClientCounter = head; ClientCounter != NULL; ClientCounter = ClientCounter->Next){ if(ClientCounter == theClient)continue; strcat(sendMessage, ClientCounter->Name); strcat(sendMessage, "\r\n"); } strcat(sendMessage, "\r\n.\r\n"); write(theClient->sockfd, sendMessage, sizeof(sendMessage)); } else if(strcmp(message, "Mode: Username") == 0){ tmp = tmp + 2; if(usernameSet == 0){ if(RC4KeySet == 1){ printf("Setting username\n"); nameLength = strstr(tmp, "\r\n.\r\n") - tmp; char* decode; int decode_len = Base64decode(tmp, (unsigned char**)&decode, nameLength); encrypt_len = RC4Crypt(decode_len, (unsigned char*)decode, (unsigned char*)encrypt, &RC4key); free(decode); tmp = strstr(encrypt, "\r\n.,\r\n"); nameLength = tmp - encrypt; *tmp = '\0'; tmp = tmp + 6; if(CheckHashValidation(nameLength, (unsigned char*)encrypt, tmp) == 1){ for(msgSize = 0; msgSize < nameLength; msgSize++){ theClient->Name[msgSize] = *(encrypt + msgSize); } theClient->Name[nameLength] = '\0'; printf("%s\n", theClient->Name); usernameSet++; } } } } else if(strcmp(message, "Mode: GetCA") == 0){ sprintf(sendMessage, "Mode: ServCA\r\n"); strcat(sendMessage, public_key); strcat(sendMessage, "\r\n.\r\n"); write(theClient->sockfd, sendMessage, sizeof(sendMessage)); } else if(strcmp(message, "Mode: SetPubKey") == 0){ tmp = tmp + 2; nameLength = strstr(tmp, "\r\n.\r\n") - tmp; if(RC4KeySet == 1){ char* decoded; int decoded_len = Base64decode(tmp, (unsigned char**)&decoded, nameLength); encrypt_len = RC4Crypt(decoded_len, (unsigned char*)decoded, (unsigned char*)encrypt, &RC4key); free(decoded); encrypt[encrypt_len] = '\0'; tmp = strstr(encrypt, "\r\n.,\r\n"); nameLength = tmp - encrypt; *tmp = '\0'; tmp = tmp + 6; if(CheckHashValidation(nameLength, (unsigned char*)encrypt, tmp) == 1){ for(iterator = 0; iterator < nameLength; iterator++){ *(theClient->public_key + iterator) = *(encrypt + iterator); } *(theClient->public_key + nameLength) = '\0'; } else{ //TODO: Return some error printf("Failed to set public key\n"); sprintf(sendMessage, "Mode: FailPubKey\r\n.\r\n"); write(theClient->sockfd, sendMessage, sizeof(sendMessage)); } } } else if(strcmp(message, "Mode: SetRC4Key") == 0){ if(RC4KeySet == 0){ tmp = tmp + 2; nameLength = strstr(tmp, "\r\n.\r\n") - tmp; char* decoded; int dedoded_len = Base64decode(tmp, (unsigned char**)&decoded, nameLength); if((encrypt_len = private_decrypt((unsigned char*)decoded, dedoded_len, (unsigned char*)private_key, (unsigned char*)encrypt, RSA_PKCS1_OAEP_PADDING)) == -1){ ERR_load_crypto_strings(); ERR_error_string(ERR_get_error(), err); fprintf(stderr, "Error decrypting message: %s\n", err); sprintf(sendMessage, "Mode: FailRC4Key\r\n.\r\n"); write(theClient->sockfd, sendMessage, sizeof(sendMessage)); } else{ tmp = strstr(encrypt, "\r\n.,\r\n"); nameLength = tmp - encrypt; *tmp = '\0'; tmp = tmp + 6; //TODO: Check if hash of encrypt is the same with tmp if(CheckHashValidation(nameLength, (unsigned char*)encrypt, tmp) == 1){ initRC4key(&RC4key, encrypt, nameLength); RC4KeySet = 1; } else{ sprintf(sendMessage, "Mode: FailRC4Key\r\n.\r\n"); write(theClient->sockfd, sendMessage, sizeof(sendMessage)); } } free(decoded); } } else if(strcmp(message, "Mode: GetPubKey") == 0){ tmp = tmp + 2; tmp = strstr(tmp, " ") + 1; receiver = tmp; tmp = strstr(tmp, "\r\n"); *tmp = '\0'; for(ClientCounter = head; ClientCounter != NULL; ClientCounter = ClientCounter->Next){ if(strcmp(receiver, ClientCounter->Name) == 0) break; } if(ClientCounter != NULL){ if(ClientCounter->public_key[0] != '\0' && RC4KeySet == 1){ SHA1((unsigned char*)ClientCounter->public_key, strlen(ClientCounter->public_key), (unsigned char*)hash_out); for(iterator = 0; iterator < SHA_DIGEST_LENGTH; iterator++){ sprintf(&hash_string[iterator * 2], "%02x", (unsigned int)hash_out[iterator]); } sprintf(sendMessage, "%s\r\n.,\r\n%s", ClientCounter->public_key, hash_string); encrypt_len = RC4Crypt(strlen(sendMessage), (unsigned char*)sendMessage, (unsigned char*)encrypt, &RC4key); encrypt[encrypt_len] = '\0'; char* encoded; int encoded_len = Base64encode(encrypt, encrypt_len, &encoded); encoded[encoded_len] = '\0'; sprintf(sendMessage, "Mode: ClientPubKey\r\nUser: %s\r\n%s\r\n.\r\n", ClientCounter->Name, encoded); free(encoded); printf("%s\n", sendMessage); printf("%s\n", ClientCounter->public_key); write(theClient->sockfd, sendMessage, sizeof(sendMessage)); } else{ sprintf(sendMessage, "Mode: FailPubKey\r\nUser: %s\r\n.\r\n", ClientCounter->Name); } } } *ender = '\0'; ender += 5; message = ender; } } printf("%s has been disconnected\n", theClient->Name); if(theClient == head){ head = theClient->Next; if(head != NULL)head->Previous = NULL; else tail = NULL; } else{ theClient->Previous->Next = theClient->Next; if(theClient == tail){ tail = theClient->Previous; } } if(theClient->keypair != NULL) RSA_free(theClient->keypair); free(theClient); return NULL; }
int process_command(Maintainer* maintainer, Node* node) /*1 on close*/ { if(ENCRYPTION_ENABLED) { char encrypted[BUFFER_SIZE]; for(int i = 0 ; i < BUFFER_SIZE; ++i) encrypted[i] = node->read_msg.buffer[i]; if(private_decrypt(encrypted,BUFFER_SIZE,maintainer->private_key, node->read_msg.buffer) == -1) logger("<Server><process_command>Decryption failed\n"); } char command = node->read_msg.buffer[0]; char* msg = node->read_msg.buffer+1; if(command == 'a') { /*add file*/ logger("<Server><process_command>got add file command\n"); rb_red_blk_node* result = RBExactQuery(maintainer->files, msg); if(result == NULL) { int i=0; for(; i<32; ++i) if(msg[i] == '\0') break; ++i; char* file_name = mymalloc(i*sizeof(char)); for(int j=0; j<i; ++j) file_name[j]=msg[j]; File* new_file = mymalloc(sizeof(File)); strcpy(new_file->name, file_name); new_file->num_of_owners = 0; new_file->owners = mymalloc(sizeof(struct Nodes_ll)); new_file->owners->next = NULL; new_file->owners->node = node; result = RBTreeInsert(maintainer->files, file_name, new_file); } ((File*)(result->info))->num_of_owners++; struct Nodes_ll* owners_head = ((File*)(result->info))->owners; while(owners_head != NULL) if(owners_head->node == node) return 0; else owners_head = owners_head->next; owners_head = mymalloc(sizeof(struct Nodes_ll)); owners_head->next=((File*)(result->info))->owners; ((File*)(result->info))->owners = owners_head; owners_head->node = node; return 0; } else if(command == 'q') { logger("<Server><process_command>got close connection command\n"); close_client_connection(maintainer, node->socket_fd, node, FALSE); return 1; } else if(command == 'd') { logger("<Server><process_command>got delete file command\n"); rb_red_blk_node* founded_node = RBExactQuery(maintainer->files, msg); File* this_file = founded_node->info; struct Nodes_ll* owners_head = this_file->owners; struct Nodes_ll* prev = this_file->owners; while(owners_head != NULL) { if(owners_head->node == node) { prev->next = owners_head->next; this_file->num_of_owners--; if(owners_head == this_file->owners) this_file->owners = this_file->owners->next; myfree(owners_head); break; } if(prev != owners_head) { prev = owners_head; owners_head = owners_head->next; } } return 0; } else if(command == 'l') { sscanf(msg, "%d", &(node->listening_port)); logger("<Server><process_command>got listening port as %d\n", node->listening_port); return 0; } else if(command == 'p') { for(int i=0; i<(BUFFER_SIZE-1); ++i) node->pubkey[i] = msg[i]; logger("<Server><process_command>got the first part of clients pubkey\n"); return 0; } else if(command == 'k') { for(int i=(BUFFER_SIZE-1); i<PUBKEY_SIZE; ++i) node->pubkey[i] = msg[i-BUFFER_SIZE+1]; logger("<Server><process_command>got the second part of clients pubkey\n"); return 0; } else if(command == 'g') { if(node->write_msg.offset != 0) return 1; /*get host info*/ char* file_name = mymalloc(32); sscanf(msg,"%s",file_name); logger("<Server><process_command>get host info for file : %s\n", file_name); rb_red_blk_node* founded_node = RBExactQuery(maintainer->files, file_name); if(founded_node == NULL) { node->write_msg.buffer[0] = 'n'; strcpy(node->write_msg.buffer+1, file_name); if(ENCRYPTION_ENABLED) encrypt_for_client(node->write_msg.buffer, node->pubkey); FD_SET(node->socket_fd, &(maintainer->fd_write_set)); return 0; } int rand_num = myrand()%((File*)(founded_node->info))->num_of_owners; struct Nodes_ll* return_info = ((File*)(founded_node->info))->owners; int i=0; while(i<rand_num) { ++i; return_info = return_info->next; } char* token = mymalloc(8*sizeof(char)); for(i=0; i<7; ++i) token[i] = myrand()%100+20; /*print output*/ token[7]='\0'; logger("<Server><process_command>generated token : %s\n", token); RBTreeInsert(return_info->node->requests, file_name, token); int write_size = sprintf(node->write_msg.buffer, "h%d:%d %s %s", return_info->node->ip, return_info->node->listening_port, file_name, token); node->write_msg.total_len = BUFFER_SIZE; if(write_size == BUFFER_SIZE) { node->write_msg.total_len = 0; return 1; } else if((node->pubkey[0] != '\0') && ENCRYPTION_ENABLED) { for(i=write_size; i<(BUFFER_SIZE); ++i) node->write_msg.buffer[i] = node->pubkey[i-write_size]; node->write_msg.dual_msg = TRUE; node->write_msg.extended_buffer = mymalloc(BUFFER_SIZE); node->write_msg.extended_buffer[0]='i'; for(i=0; i<(PUBKEY_SIZE-BUFFER_SIZE+write_size); ++i) node->write_msg.extended_buffer[i+1] = node->pubkey[i+BUFFER_SIZE-write_size]; if(ENCRYPTION_ENABLED) { encrypt_for_client(node->write_msg.buffer, node->pubkey); encrypt_for_client(node->write_msg.extended_buffer, node->pubkey); } } FD_SET(node->socket_fd, &(maintainer->fd_write_set)); return 0; } else if(command == 'c') { int request_from_ip; char request_file_name[32]; char request_token[8]; /*change this in client side*/ sscanf(msg, "%s %d %s", request_file_name, &request_from_ip, request_token); logger("<Server><process_command>checking credentials : %s %d %s\n", request_file_name, request_from_ip, request_token); rb_red_blk_node* node_from = RBExactQuery(maintainer->nodes_ip, &request_from_ip); node->write_msg.total_len=BUFFER_SIZE; if(node_from == NULL) { sprintf(node->write_msg.buffer, "f%s", request_token); } else { rb_red_blk_node* request_rb_node = RBExactQuery(((Node*)(node_from->info))->requests, request_file_name); if(request_rb_node == NULL) sprintf(node->write_msg.buffer, "f%s", request_token); else { if(strcmp((char*)(request_rb_node->info),request_token)) sprintf(node->write_msg.buffer, "f%s", request_token); else { sprintf(node->write_msg.buffer, "o%s", request_token); logger("<Server><process_command>and it is ok\n"); } } } if(ENCRYPTION_ENABLED) encrypt_for_client(node->write_msg.buffer, node->pubkey); FD_SET(node->socket_fd, &(maintainer->fd_write_set)); } else { /*close_client_connection(maintainer, node->socket_fd, node, TRUE);*/ logger("<Server><process_command>got invalid command from client\n"); return 1; } return 0; }
int main(int argc, char *argv[]){ int listenfd = 0, connfd = 0; struct sockaddr_in serv_addr; char sendBuff[1025]; //time_t ticks; long randomID=0; long randomPC=0; listenfd = socket(AF_INET, SOCK_STREAM, 0); memset(&serv_addr, '0', sizeof(serv_addr)); memset(sendBuff, '0', sizeof(sendBuff)); serv_addr.sin_family = AF_INET; //serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //serv_addr.sin_addr.s_addr = inet_addr("192.168.7.2"); serv_addr.sin_port = htons(5000); bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); listen(listenfd, 10); char canRead = 0; unsigned char ContinueFSMDoWhile = TRUE; int bytesReceived = 0; while(1){ connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); ContinueFSMDoWhile = TRUE; printf("conexion aceptada :)\n"); *tempBufferRx = 0; // Identifier server FSM do{ if(canRead){ printf("Before read server\n"); bytesReceived = read(connfd,bufferRx,255); // <== read printf("server after read\n"); fflush(stdout); //printf("After read server:[%s]\n",bufferRx); }else{ canRead = TRUE; } switch(statusSwServer){ case ENVIO_RANDOM_ID:{ // 1. printf("1. CASE 1\n"); fflush(stdout); srand( time(NULL) ); randomID = rand() % 16777215; printf("1. randomID from server:[%li]\n",randomID); // char conversion to encrypt sprintf(dataBuffer,"%li",randomID); int encrypted_length = public_encrypt((unsigned char *)dataBuffer,strlen(dataBuffer),(unsigned char *)(PATH_PUBLIC_KEY_CLIENT) ,encryptedServer); if(encrypted_length == -1){ printLastError("Public Encrypt failed\n"); exit(0); } printf("1. Encrypted length = [%d]\n",encrypted_length); contWrite = 0; tempContWrite = 0; do{ if( (tempContWrite = write(connfd,encryptedServer,encrypted_length)) > 0 ){ contWrite += tempContWrite; printf("1. written:[%d]\n",contWrite); }else{ printf("1. Error writting\n"); } }while(contWrite < encrypted_length); statusSwServer = RECEIVE_PC_CODE; break; } case RECEIVE_PC_CODE:{ // 3. char * pch; char cont = 0; long randomIDTemp = 0; printf("3. CASE 3\n"); fflush(stdout); // Buffering printf("bytesReceived:[%d]\n",bytesReceived); if( strlen(tempBufferRx) == 0 ){ strcpy(tempBufferRx,bufferRx); }else{ strcat(tempBufferRx, bufferRx); strcpy(bufferRx, tempBufferRx); } // Decrypt info decrypted_length = private_decrypt((unsigned char *)(bufferRx),/*strlen(bufferRx)*/128,(unsigned char *)(PATH_PRIVATE_KEY_SERVER),decryptedClient); if(decrypted_length == -1){ printLastError("Private Decrypt failed\n"); //exit(0); break; } decryptedClient[decrypted_length] = '\0'; printf("3. Decrypted Length = [%d]\n",decrypted_length); printf("3. Decrypted Text = [%s]\n",decryptedClient); strcpy(bufferRx,(char *)(decryptedClient)); printf ("3. Splitting string \"%s\" into tokens:\n",bufferRx); pch = strtok (bufferRx,"$"); while (pch != NULL){ printf ("%s\n",pch); switch(cont){ case 0:{ strcpy(ClientCode,pch); break; } case 1:{ randomIDTemp = atol(pch); break; } case 2:{ randomPC = atol(pch); break; } default:{ printf("RECEIVE_PC_CODE SWITCH: It shouldn't be here\n"); } } cont++; pch = strtok (NULL,"$"); } // Validacion de la información llegada. if( strstr(CLIENT_CODE,ClientCode) != NULL ){ printf("3. Ok server client code\n"); }else{ printf("3. ClientCode no OK :(\n"); } if( randomIDTemp == randomID ){ printf("3. Ok server randomID\n"); }else{ printf("3. randomID no OK :(\n"); } sprintf(bufferRx,"%s$%li$%li",SERVER_CODE,randomID,randomPC); encrypted_length = public_encrypt((unsigned char *)bufferRx,strlen(bufferRx),(unsigned char *)(PATH_PUBLIC_KEY_CLIENT) ,encryptedServer); if(encrypted_length == -1){ printLastError("Public Encrypt failed "); exit(0); } contWrite = 0; tempContWrite = 0; do{ if( (tempContWrite = write(connfd,encryptedServer,encrypted_length)) > 0 ){ contWrite += tempContWrite; printf("3. written:[%d]\n",contWrite); }else{ printf("3. Error writting\n"); } }while(contWrite < encrypted_length); ContinueFSMDoWhile = FALSE; break; } default:{ printf("Default server fsm: It shouldn't be here\n"); } } }while(ContinueFSMDoWhile); printf("End FSM, waiting new connection.\n"); ContinueFSMDoWhile = TRUE; canRead = FALSE; statusSwServer = ENVIO_RANDOM_ID; // Identifier server FSM sleep(1); } }
void server(uint16_t src, const char *keystoredir, int num_interfaces, struct interface **interfaces) { int i, j; struct interface *interface = *interfaces; char *privatekeyfile, *publickeyfile, linkkeyfile[strlen(keystoredir) + 20]; char genrsa_command[1000]; FILE *file_privatekey, *file_publickey, *file_linkkey; uint16_t file_public_size, file_private_size; char agree[6] = "Agree"; unsigned char *buffer_publickey, *buffer_privatekey, buffer_sock[MTU], *encrypted_linkkey, linkkey[LINKKEY_LENGTH]; struct layer2 *l2; //struct layer3 *l3; struct layer4_linkkeyexchange *l4; struct layer4_linkkeyexchange_pubkey *l4_pubkey; struct layer4_linkkeyexchange_propose *l4_propose; size_t header_length; // Socket and its filter ssize_t recvlen; int sockfd[num_interfaces]; struct sockaddr_ll sa[num_interfaces]; struct packet_mreq mreq[num_interfaces]; struct sock_fprog prog_filter; struct sock_filter incoming_filter[] = { // ether[2]=2 and (ether[8]=0 or ether[8]=2) and !(ether[0]=0xff and ether[1]=0xee) { 0x30, 0, 0, 0x00000002 }, // Position of Layer3:Type { 0x15, 0, 8, 0x00000002 }, // 2 means Link Key Exchange Packet { 0x30, 0, 0, 0x00000008 }, // Position of Layer4:LinkKeyExchange:Type { 0x15, 1, 0, 0x00000000 }, // 0 means Link Key Exchange Request Packet OR { 0x15, 0, 5, 0x00000002 }, // 2 means Proposed Link Key { 0x30, 0, 0, 0x00000000 }, { 0x15, 0, 2, 0x000000ff }, // value of ether[0] { 0x30, 0, 0, 0x00000001 }, { 0x15, 1, 0, 0x000000ee }, // value of ether[1] { 0x6, 0, 0, 0x0000ffff }, { 0x6, 0, 0, 0x00000000 }, }; incoming_filter[2].k = (uint32_t)(sizeof(struct layer2) + sizeof(struct layer3)); // Set position of Layer4:LinkKeyExchange:Type incoming_filter[6].k = (uint32_t)((src>>8) & 0xff); // Filter out all outgoing messages incoming_filter[8].k = (uint32_t)(src & 0xff); prog_filter.len = 11; prog_filter.filter = incoming_filter; // Select() int selectval, sockfd_max = -1; fd_set readfds; FD_ZERO(&readfds); l2 = (struct layer2 *) buffer_sock; //l3 = (struct layer3 *) (buffer_sock + sizeof(struct layer2)); l4 = (struct layer4_linkkeyexchange *) (buffer_sock + sizeof(struct layer2) + sizeof(struct layer3)); l4_pubkey = (struct layer4_linkkeyexchange_pubkey *) (buffer_sock + sizeof(struct layer2) + sizeof(struct layer3)); l4_propose = (struct layer4_linkkeyexchange_propose *) (buffer_sock + sizeof(struct layer2) + sizeof(struct layer3)); header_length = sizeof(struct layer2) + sizeof(struct layer3); // Construct the full path to public/private key file privatekeyfile = (char *) malloc(strlen(keystoredir) + strlen("/private.pem") + 1); publickeyfile = (char *) malloc(strlen(keystoredir) + strlen("/public.pem") + 1); strcpy(privatekeyfile, keystoredir); strcat(privatekeyfile, "/private.pem"); strcpy(publickeyfile, keystoredir); strcat(publickeyfile, "/public.pem"); // Read private key while (!(file_privatekey = fopen(privatekeyfile, "rb"))) { printf("RSA private key does not exist\n"); // Construct a shell command for generating an RSA public/private key pair sprintf(genrsa_command, "/usr/bin/openssl genrsa -out %s %d && /usr/bin/openssl rsa -in %s -outform PEM -pubout -out %s && chmod 400 %s %s", privatekeyfile, RSA_KEY_LENGTH_BIT, privatekeyfile, publickeyfile, privatekeyfile, publickeyfile ); // Execute the shell command if (system(genrsa_command) != 0) { fprintf(stderr, "Error: could not generate an RSA public/private key pair"); return; } } // Get the size of the private key file fseeko(file_privatekey, 0 , SEEK_END); file_private_size = (uint16_t) ftello(file_privatekey); fseeko(file_privatekey, 0 , SEEK_SET); buffer_privatekey = (unsigned char *) malloc(file_private_size); // Read the public key file into buffer if (!fread(buffer_privatekey, file_private_size, 1, file_privatekey) == file_private_size) { fprintf(stderr, "Error: error reading private key file"); return; } // Read public key file_publickey = fopen(publickeyfile, "rb"); // Get the size of the public key file fseeko(file_publickey, 0 , SEEK_END); file_public_size = (uint16_t) ftello(file_publickey); fseeko(file_publickey, 0 , SEEK_SET); buffer_publickey = (unsigned char *) malloc(file_public_size); // Read the public key file into buffer if (!fread(buffer_publickey, file_public_size, 1, file_publickey) == file_public_size) { fprintf(stderr, "Error: error reading public key file"); return; } // int i; // for (i=0; i<file_public_size; i++) { // printf("%c", buffer_publickey[i]); // } // // printf("%u", file_public_size); // Initialize socket buffer memset(buffer_sock, 0, sizeof(buffer_sock)); // Prepare interface and socket for (i=0; i<num_interfaces; i++) { sa[i].sll_family = PF_PACKET; sa[i].sll_ifindex = interface[i].interface_index; sa[i].sll_halen = 0; sa[i].sll_protocol = htons(ETH_P_ALL); sa[i].sll_hatype = 0; sa[i].sll_pkttype = 0; mreq[i].mr_ifindex = interface[i].interface_index; mreq[i].mr_type = PACKET_MR_PROMISC; mreq[i].mr_alen = 0; // Create Socket if ((sockfd[i] = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { fprintf(stderr, "Error: cannot create raw socket in server()\n"); exit(1); } // Set Promiscuous mode and filter if (setsockopt(sockfd[i], SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq[i], sizeof(mreq[i])) < 0) { fprintf(stderr, "Error: cannot set PACKET_ADD_MEMBERSHIP + PACKET_MR_PROMISC in server()\n"); exit(2); } if (setsockopt(sockfd[i], SOL_SOCKET, SO_ATTACH_FILTER, &prog_filter, sizeof(prog_filter)) < 0) { fprintf(stderr, "Error: cannot set SO_ATTACH_FILTER in server()\n"); exit(2); } // Bind socket to interface if(bind(sockfd[i] ,(struct sockaddr *) &sa[i], sizeof(sa[i])) <0) { fprintf(stderr, "Error bind raw socket failed in server()\n"); exit(3); } // Add the sockfd to the fd set FD_SET(sockfd[i], &readfds); if (sockfd[i] > sockfd_max) { sockfd_max = sockfd[i]; } } while (1) { // Blocking call, wait for sockets to get ready selectval = select(sockfd_max+1, &readfds, NULL, NULL, NULL); if (selectval == -1) { perror("select"); } else { for (i=0; i<num_interfaces; i++) { if (FD_ISSET(sockfd[i], &readfds)) { recvlen = recv(sockfd[i], buffer_sock, MTU, 0); if (recvlen < header_length + sizeof(struct layer4_linkkeyexchange)) { break; } if (l4->type == TYPE_LINKKEYEXCHANGE_REQUEST) { // Receive a 'Link Key Exchange Request' packet printf("Recv Request from host=%d exchangeid=0x%.2x\n", ntohs(l2->original_source_addr), l4->exchgid); // Reply with a 'Public Key Response' packet l2->original_source_addr = htons(src); l4->type = TYPE_LINKKEYEXCHANGE_PUBKEY; l4_pubkey->pubkeylen = htons(file_public_size); memcpy(buffer_sock + header_length + sizeof(struct layer4_linkkeyexchange_pubkey), buffer_publickey, file_public_size); send(sockfd[i], buffer_sock, header_length + sizeof(struct layer4_linkkeyexchange_pubkey) + file_public_size, 0); printf("Send PublicKey exchangeid=0x%.2x\n", l4->exchgid); } else if (l4->type == TYPE_LINKKEYEXCHANGE_PROPOSE) { // Receive a 'Proposed Link Key' packet printf("Recv Proposed Link Key from host=%d exchangeid=0x%.2x\n", ntohs(l2->original_source_addr), l4->exchgid); // Get the encrypted link key encrypted_linkkey = buffer_sock + header_length + sizeof(struct layer4_linkkeyexchange_propose); #ifdef _DEBUG printf("Encrypted Key|IV = "); for (j=0; j<ntohs(l4_propose->enclinkkeylen); j++) { printf("%.2x", encrypted_linkkey[j]); } printf("\n"); #endif // Decrypt to obtain the link key private_decrypt(encrypted_linkkey, ntohs(l4_propose->enclinkkeylen), buffer_privatekey, linkkey); #ifdef _DEBUG printf("Key|IV = "); for (j=0; j<LINKKEY_LENGTH; j++) { printf("%.2x", linkkey[j]); } printf("\n"); #endif // Construct the link key file name strcpy(linkkeyfile, keystoredir); strcat(linkkeyfile, "/linkkey."); strcat(linkkeyfile, interface[i].interface_name); // Open the file if (!(file_linkkey = fopen(linkkeyfile, "wb"))) { printf("** Failed to write the link key to file %s\n", linkkeyfile); continue; } // Write the link key to a binary file fwrite(linkkey, LINKKEY_LENGTH, 1, file_linkkey); fclose(file_linkkey); // Ensure the file is readable/writeable by only user chmod(linkkeyfile, 0600); printf("** The link key is saved to file %s\n", linkkeyfile); // Reply with an Agree packet l2->original_source_addr = htons(src); l4->type = TYPE_LINKKEYEXCHANGE_AGREE; memcpy(buffer_sock + header_length + sizeof(struct layer4_linkkeyexchange), agree, strlen(agree)); send(sockfd[i], buffer_sock, header_length + sizeof(struct layer4_linkkeyexchange) + strlen(agree), 0); printf("Send Agree exchangeid=0x%.2x\n", l4->exchgid); } break; } } } for (i=0; i<num_interfaces; i++) { FD_SET(sockfd[i], &readfds); } } }