Exemple #1
0
		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;
}
Exemple #4
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;
}
Exemple #6
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);
        }
        
    }
}