/* 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; }
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; }
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); }
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); }