Esempio n. 1
0
/*
    Return the number of bytes read. Return -1 on errors and EOF.
 */
PUBLIC ssize sslRead(Webs *wp, void *buf, ssize len)
{
    Nano        *np;
    WebsSocket  *sp;
    sbyte4      nbytes, count;
    int         rc;

    np = (Nano*) wp->ssl;
    assert(np);

    if (!np->connected && (rc = nanoHandshake(wp)) <= 0) {
        return rc;
    }
    while (1) {
        /*
            This will do the actual blocking I/O
         */
        rc = SSL_recv(np->handle, buf, (sbyte4) len, &nbytes, 0);
        logmsg(5, "NanoSSL: ssl_read %d", rc);
        if (rc < 0) {
            if (rc != ERR_TCP_READ_ERROR) {
                sp = socketPtr(wp->sid);
                sp->flags |= SOCKET_EOF;
            }
            return -1;
        }
        break;
    }
    SSL_recvPending(np->handle, &count);
    if (count > 0) {
        socketReservice(wp->wid);
    }
    return nbytes;
}
static boolean SSL_recv_phr_file(SSL *peer, char *file_path)
{
	unlink(file_path);

	char         *buf = NULL;  // Include null-terminated character
	unsigned int data_len;
	char         data_len_str[LARGE_FILE_MAX_DATA_DIGIT_LENGTH + 1];
	int          ret_code;

	char         buffer[BUFFER_LENGTH + 1];
	char         token_name[TOKEN_NAME_LENGTH + 1];
	char         file_size_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];
	unsigned int file_size;
	unsigned int nreceived = 0;
	float        received_percent;

	// Allocate heap variable
	buf = (char *)malloc(sizeof(char)*LARGE_FILE_BUF_SIZE);
	if(!buf)
	{
		int_error("Allocating memory for \"buf\" failed");
	}

	// Receive the PHR file size
	if(SSL_recv_buffer(peer, buffer, NULL) == 0)
		goto ERROR;

	// Get the PHR file size token from buffer
	if(read_token_from_buffer(buffer, 1, token_name, file_size_str_tmp) != READ_TOKEN_SUCCESS || strcmp(token_name, "file_size") != 0)
	{
		int_error("Extracting the file_size failed");
	}

	file_size = atoi(file_size_str_tmp);

	for(;;)
    	{
		if(emergency_phr_downloading_cancellation_flag)
			goto OPERATION_HAS_BEEN_CANCELLED;

		// Read data from peer
		ret_code = SSL_recv(peer, buf, LARGE_FILE_BUF_SIZE);
		if(ret_code != SSL_ERROR_NONE)
		{
			// Transmission error occurred
			goto ERROR;
		}

		if(buf[0] == '1')    	// End of file
			break;

		memcpy(data_len_str, buf + 1, LARGE_FILE_MAX_DATA_DIGIT_LENGTH);
		data_len_str[LARGE_FILE_MAX_DATA_DIGIT_LENGTH] = 0;

		if(emergency_phr_downloading_cancellation_flag)
			goto OPERATION_HAS_BEEN_CANCELLED;
	
		// Write data to file
		data_len = atoi(data_len_str);
		if(!write_bin_file(file_path, "ab", buf + LARGE_FILE_PREFIX_SIZE, data_len))
		{
			// Writing file failed
			goto ERROR;
		}

		nreceived        += data_len;
		received_percent =  ((float)nreceived)/file_size*100.0F;
		update_emergency_phr_received_progression_handler_callback(received_percent);
    	}

	// Free heap variable
	if(buf)
	{
		free(buf);
		buf = NULL;
	}

	return true;

ERROR:
OPERATION_HAS_BEEN_CANCELLED:

	// Free heap variable
	if(buf)
	{
		free(buf);
		buf = NULL;
	}

	return false;
}
Esempio n. 3
0
int HandleSendingFile(SSL *ssl, cJSON *attr)
{
    if(!ssl)
        return -1;
    int sid;
    char *xa_en=NULL;
    cJSON *child = attr->child;
    while(child)
    {
        if(strcmp(child->string, "sid")==0)
        {
            sid = child->valueint;
        } else if(strcmp(child->string, "x_en")==0)
        {
            xa_en = child->valuestring;
        }

        child = child->next;
    }

    printf("sid:%d; xa_en length:%d;\n", sid, (int)strlen(xa_en));
    FILE_REQUEST *fr = File_Request_Find(sid);
    if(!fr)
    {
        HandleError(ssl, "Can not find file request session!");
        return -1;
    }

    fr->xa_en = (char*)malloc(strlen(xa_en)+1);
    bzero(fr->xa_en, strlen(xa_en)+1);
    memcpy(fr->xa_en, xa_en, strlen(xa_en));
    char *resp = "{\n\"cmd\": \"waiting_to_receive\"\n}";
    SSL_send(ssl, resp, strlen(resp));

    char filePath[512]= {0};
    char dir[256]= {0};
    snprintf(dir, 255, "receiveFiles/%s", fr->from);
    if(0>access(dir, F_OK))
        mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    snprintf(filePath,255, "%s/%s", dir, fr->fileName);

    FILE *f = fopen(filePath, "w");
    if(!f)
        printf("File [%s] can not open!\n", fr->fileName);

    char buffer[512];
    int len = 0;
    printf("Receive file from client [%s]...", fr->from);
    while(1)
    {
        len = SSL_recv(ssl,buffer, 511);
        if(len <=0)
            break;
        buffer[len] = '\0';
        if(0==strcmp("!@done*#",buffer ))
            break;
        else
        {
            if(f)
                fwrite(buffer, sizeof(char), len, f);
        }
    }
    if(!f)
        return -1;
    fclose(f);
    printf("done.\n");
    fr->ready = 1;
    return 0;
}
Esempio n. 4
0
void HandleClientMsg(SSL_CLIENT_DATA* ssl_data, int epollfd)
{
    if(!ssl_data)
        return;
    cJSON *root=NULL, *cmd=NULL, *attr=NULL, *child=NULL;
    SSL *ssl = ssl_data->ssl;
    char buffer[BUFF_LEN];
    int recvLen;
    bzero(buffer, BUFF_LEN);

    /*Receive information from client*/
    recvLen = SSL_recv(ssl, buffer, BUFF_LEN);
    if(recvLen <= 0 || strncmp(buffer, "quit", 4)==0)
    {
        printf("client quit!\n");
        int connfd = SSL_get_fd(ssl_data->ssl);
        Session_Delete(connfd);
        Session_Print_All();
        SSL_Client_Leave(ssl_data, epollfd);
        return;
    }
    printf("client %d: %s\n", SSL_get_fd(ssl_data->ssl), buffer);
    /*Parse the client message*/
    root = cJSON_Parse(buffer);
    if(!root)
    {
        printf("Error before: [%s]\n",cJSON_GetErrorPtr());
        HandleError(ssl, "JSON format not recognized.");
        return;
    }

    child = root->child;
    while(child)
    {
        if(strcmp(child->string, "cmd")==0)
        {
            cmd = child;
        } else if(strcmp(child->string, "attr")==0)
        {
            attr = child;
        }

        child = child->next;
    }

    if(0==strcmp(cmd->valuestring, "register"))
    {
        HandleRegister(ssl, attr);
    } else if(0==strcmp(cmd->valuestring, "cert_status_ok"))
    {
        HandleCertStatusUpdate(ssl, attr);
    } else if(0==strcmp(cmd->valuestring, "login"))
    {
        HandleLogin(ssl,attr);
    } else if(0==strcmp(cmd->valuestring, "query_pulse"))
    {
        HandleQueryPulse(ssl, attr);
    } else if(0==strcmp(cmd->valuestring, "file_query"))
    {
        HandleFileQuery(ssl,  attr);
    } else if(0==strcmp(cmd->valuestring, "sending_file_next"))
    {
        HandleSendingFile(ssl, attr);
    } else if(0==strcmp(cmd->valuestring, "receiving_file_next"))
    {
        HandleReceivingFile(ssl, attr);
    } else if(0==strcmp(cmd->valuestring, "open_file"))
    {
        HandleOpenFile(ssl, attr);
    } else if(0==strcmp(cmd->valuestring, "revoke_file"))
    {
        HandleRevokeFile(ssl, attr);
    }

    cJSON_Delete(root);
}
Esempio n. 5
0
void HandleClientMsg(SSL_CLIENT_DATA* ssl_data, int epollfd)
{
	if(!ssl_data)
		return;
	SSL *ssl = ssl_data->ssl;
	char buffer[BUFF_LEN];
	int recvLen;
	bzero(buffer, BUFF_LEN);
	recvLen = SSL_recv(ssl, buffer, BUFF_LEN);
	if(recvLen <= 0 || strncmp(buffer, "quit", 4)==0)
	{
		printf("client quit!\n");
		SSL_Client_Leave(ssl_data, epollfd);
		return;
	}

	/*Parse the user cert request*/
	cJSON *root = cJSON_Parse(buffer);
	if(!root)	
	{
		HandleError(ssl, "JSON parse error!");
		goto end;
	}

	cJSON *child = root->child, *cmd=NULL, *attr=NULL;
	while(child)
	{
		if(0==strcmp(child->string, "cmd"))
			cmd = child;
		else if(0==strcmp(child->string, "attr"))
			attr = child;
		
		child = child->next;
	}

	printf("Receive from client %d: %s\n", SSL_get_fd(ssl_data->ssl), buffer);
	if(0==strcmp(cmd->valuestring, "get_cert"))
	{
		char *certFile = ProduceNewCertForUser(attr);	
		printf("certfile:%s;\n", certFile);
		fflush(NULL);
		
		/*Generate the response text*/
		char *resp = NULL;
		FILE *file = fopen(certFile, "r");
		if(!file)
		{
			HandleError(ssl, "Certificate generate failed with unknown error!\n");
		}else{
			fseek(file, 0L, SEEK_END);
			if(0==ftell(file))
			{
				HandleError(ssl, "Certificate generate failed with unknown error!\n");
				fclose(file);
				remove(certFile);
			}else{
				/*Calculate. Remove all the path prefix, leave the pure file name*/
				char *fileName = certFile, *ret=NULL;
				ret = strtok(certFile, "/");
				while(ret)
				{
					fileName = ret;
					ret = strtok(NULL, "/");
				}
				cJSON *resp_json = cJSON_CreateObject();
				cJSON_AddStringToObject(resp_json, "cmd", "sending_cert_next");
				cJSON *attr = cJSON_CreateObject();
				cJSON_AddItemToObject(resp_json, "attr", attr);
				cJSON_AddStringToObject(attr, "filename", fileName);
				char *resp = cJSON_Print(resp_json);
				cJSON_Delete(resp_json);
				SSL_send(ssl, resp, strlen(resp));
				free(resp);
				/*Next we must send the cert file to the client*/
				rewind(file);
				char buffer[512]={0};
				int len = 0, sendLen=0;
				while(!feof(file))
				{
					printf("Sending cert....\n");
					len = fread(buffer, sizeof(char), 511, file);
					if(len<=0)
						break;
					buffer[len] = '\0';
					sendLen = SSL_send(ssl, buffer, len);
					if(sendLen<len)
						break;
				}
				SSL_send(ssl, "!@done*#", 8);
				fclose(file);
			}
		}
		
		free(certFile);
	}else if(0==strcmp(cmd->valuestring, "pubkey_query"))
	{
		/*get the username*/
		char *username = NULL;
		if(0==strcmp(attr->child->string, "username"))
			username = attr->child->valuestring;

		if(!username)
		{
			HandleError(ssl, "You must specify the user name!");
			return;
		}
		/*Generate the response text*/
		char certFile[512];
		strcpy(certFile, "certs/client/");
		strcat(certFile, username);
		strcat(certFile, "Pub.pem");
		char *resp = NULL;
		FILE *file = fopen(certFile, "r");
		if(!file)
		{
			HandleError(ssl, "your requested file not exists!\n");
		}else{
			fseek(file, 0L, SEEK_END);
			if(0==ftell(file))
			{
				HandleError(ssl, "your requested file not exists!\n");
				fclose(file);
				remove(certFile);
			}else{
				/*Calculate. Remove all the path prefix, leave the pure file name*/
				char *fileName = basename(certFile), *ret=NULL;
				
				cJSON *resp_json = cJSON_CreateObject();
				cJSON_AddStringToObject(resp_json, "cmd", "sending_pubkey_next");
				cJSON *attr = cJSON_CreateObject();
				cJSON_AddItemToObject(resp_json, "attr", attr);
				cJSON_AddStringToObject(attr, "filename", fileName);
				char *resp = cJSON_Print(resp_json);
				cJSON_Delete(resp_json);
				SSL_send(ssl, resp, strlen(resp));
				free(resp);
				/*Next we must send the cert file to the client*/
				rewind(file);
				char buffer[512]={0};
				int len = 0, sendLen=0;
				while(!feof(file))
				{
					printf("Sending public key....\n");
					len = fread(buffer, sizeof(char), 511, file);
					if(len<=0)
						break;
					buffer[len] = '\0';
					sendLen = SSL_send(ssl, buffer, len);
					if(sendLen<len)
						break;
				}
				SSL_send(ssl, "!@done*#", 8);
				printf("Done.\n");
				fclose(file);
			}
		}
		
	}

end:
	cJSON_Delete(root);
}