link;
This commit is contained in:
		
							parent
							
								
									bbc0516191
								
							
						
					
					
						commit
						10aec3c447
					
				
							
								
								
									
										199
									
								
								lib/sntllv2.c
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								lib/sntllv2.c
									
									
									
									
									
								
							| @ -480,13 +480,14 @@ static void *__sntll_thread(void *b) | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| /* FIXME: AWARE coc and co - fix it */ | ||||
| int connection_create_fapi_m(conn_sys_t *ssys, conn_t *co, int sck, | ||||
|                              struct in_addr *addr) | ||||
| { | ||||
|   void *buf = NULL; | ||||
|   char *bbuf; | ||||
|   conn_t *coc = __connection_minimal_alloc(addr); | ||||
|   sx_msg_t *msg = NULL; | ||||
|   sxmsg_t *msg = NULL; | ||||
|   sntllv2_head_t *head; | ||||
|   sntllv2_bundle_t *bundle; | ||||
|   size_t rd; | ||||
| @ -547,9 +548,9 @@ int connection_create_fapi_m(conn_sys_t *ssys, conn_t *co, int sck, | ||||
|   buf = mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||||
|   if(buf == MAP_FAILED) { r = SNE_ENOMEM; goto __fail2; } | ||||
|   /* allocate first message */ | ||||
|   if(!(msg = malloc(sizeof(sx_msg_t)))) { r = SNE_ENOMEM; goto __fail2; } | ||||
|   if(!(msg = malloc(sizeof(sxmsg_t)))) { r = SNE_ENOMEM; goto __fail2; } | ||||
|   else { | ||||
|     memset(msg, 0, sizeof(sx_msg_t)); | ||||
|     memset(msg, 0, sizeof(sxmsg_t)); | ||||
|     coc->messages[0] = msg; | ||||
|   } | ||||
|   bbuf = (char *)buf; | ||||
| @ -641,3 +642,195 @@ int connection_create_fapi_m(conn_sys_t *ssys, conn_t *co, int sck, | ||||
|   close(sck); | ||||
|   return r; | ||||
| } | ||||
| 
 | ||||
| conn_t *connection_link(conn_sys_t *ssys, const char *host, | ||||
|                         int port, const char *SSL_cert, const char *login, | ||||
|                         const char *passwd) | ||||
| { | ||||
|   conn_t *co = __connection_minimal_alloc(addr); | ||||
|   struct hostent *host_; | ||||
|   struct sockaddr_in addr; | ||||
|   int r = SNE_SUCCESS, sck; | ||||
| #ifdef WIN32 | ||||
|   WSADATA wsaData; | ||||
| #endif | ||||
|   char hostbuf[2048]; | ||||
|   void *buf = NULL; | ||||
|   char *bbuf; | ||||
|   sntllv2_head_t *head; | ||||
|   sntllv2_bundle_t *bundle; | ||||
|   size_t rd; | ||||
| 
 | ||||
|   r = SNE_IGNORED; | ||||
|   if(!host || !SSL_cert) goto __fail; | ||||
|   if(!co) { r = SNE_ENOMEM; goto __fail; } | ||||
| 
 | ||||
| #ifdef WIN32 | ||||
|   WSAStartup(MAKEWORD(2, 2), &wsaData); | ||||
| #endif | ||||
| 
 | ||||
|   /* ok, now we need to init ssl stuff */ | ||||
|   co->ssys = ssys; | ||||
| 
 | ||||
|   /* init SSL certificates and context */ | ||||
|   co->ctx = SSL_CTX_new(TLSv1_2_client_method()); | ||||
|   if(!co->ctx) { r = SNE_ENOMEM; goto __fail; } | ||||
|   else { | ||||
|     /* set verify context */ | ||||
|     SSL_CTX_set_verify(co->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, | ||||
|                        __verify_certcall_dummy); | ||||
|     /* set verify depth */ | ||||
|     SSL_CTX_set_verify_depth(co->ctx, VERIFY_DEPTH); | ||||
|   } | ||||
| 
 | ||||
|   /* load certificates */ | ||||
|   SSL_CTX_load_verify_locations(co->ctx, ssys->rootca, NULL); | ||||
|   /* set the local certificate from CertFile */ | ||||
|   if(SSL_CTX_use_certificate_file(co->ctx, SSL_cert, | ||||
|                                   SSL_FILETYPE_PEM)<=0) { | ||||
|     ERR_print_errors_fp(stderr); | ||||
|     r = SNE_ESSL; | ||||
|     goto __fail; | ||||
|   } | ||||
|   /* set the private key from KeyFile (may be the same as CertFile) */ | ||||
|   if(SSL_CTX_use_PrivateKey_file(co->ctx, SSL_cert, | ||||
|                                  SSL_FILETYPE_PEM)<=0) { | ||||
|     r = SNE_ESSL; | ||||
|     goto __fail; | ||||
|   } | ||||
|   /* verify private key */ | ||||
|   if (!SSL_CTX_check_private_key(co->ctx)) { | ||||
|     r = SNE_ESSL; | ||||
|     goto __fail; | ||||
|   } | ||||
| 
 | ||||
|   /* resolve host */ | ||||
| #ifdef WIN32 | ||||
|   host_ = gethostbyname(host); | ||||
| #else | ||||
|   r = __resolvehost(host, hostbuf, 2048, &host_); | ||||
| #endif | ||||
|   if(r) { | ||||
|     r = SNE_FAILED; | ||||
|     goto __fail; | ||||
|   } | ||||
| 
 | ||||
|   /* create a socket */ | ||||
|   sck = socket(PF_INET, SOCK_STREAM, 0); | ||||
|   bzero(&addr, sizeof(addr)); | ||||
| 
 | ||||
|   /* try to connect it */ | ||||
|   addr.sin_family = AF_INET; | ||||
|   addr.sin_port = htons(port); | ||||
|   addr.sin_addr.s_addr = *(uint32_t*)(host_->h_addr); | ||||
|   r = connect(sck, (struct sockaddr*)&addr, sizeof(addr)); | ||||
|   if(r) { | ||||
|     close(sck); | ||||
|     r = SNE_FAILED; /* couldn't connect to the desired host */ | ||||
|     goto __fail; | ||||
|   } | ||||
| 
 | ||||
|   /* SSL handshake */ | ||||
|   co->ssl = SSL_new(co->ctx); /* TODO: checkout for it */ | ||||
|   SSL_set_fd(co->ssl, sck); /* attach connected socket */ | ||||
|   SSL_set_connect_state(co->ssl); | ||||
|   if(SSL_connect(co->ssl) == -1) { | ||||
|     r = SNE_EPERM; | ||||
|     /* shutdown connection */ | ||||
|     goto __fail; | ||||
|   } /* if success we're ready to use established SSL channel */ | ||||
| 
 | ||||
|   /* set connection to the batch mode */ | ||||
|   co->flags |= SNSX_BATCHMODE; | ||||
| 
 | ||||
|   /* allocate our first buffer */ | ||||
|   buf = mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||||
|   if(buf == MAP_FAILED) { r = SNE_ENOMEM; goto __fail2; } | ||||
|   /* allocate first message */ | ||||
|   if(!(msg = malloc(sizeof(sxmsg_t)))) { r = SNE_ENOMEM; goto __fail2; } | ||||
|   else { | ||||
|     memset(msg, 0, sizeof(sxmsg_t)); | ||||
|     co->messages[0] = msg; | ||||
|   } | ||||
|   bbuf = (char *)buf; | ||||
|   bbuf += sizeof(sntllv2_head_t); | ||||
|   head = (sntllv2_head_t *)buf; | ||||
| 
 | ||||
|   sexp_t *sx; | ||||
|   size_t ln; | ||||
|   while(co->flags & SNSX_BATCHMODE) { | ||||
|     /* form a message -- credentials */ | ||||
|     ln = snprintf(bbuf, 65535 - sizeof(sntllv2_head_t), "(auth-set-credentials \"%s\" \"%s\")", | ||||
|                   login ? login : "nil", passwd ? passwd : "nil"); | ||||
|     head->opcode = SNE_SUCCESS; | ||||
|     head->payload_length = ln; | ||||
|     wr = __conn_write(co, buf, ln + sizeof(sntllv2_head_t)); | ||||
|     if(wr < 0) goto __fail2; | ||||
| 
 | ||||
|     rd = __conn_read(co, head, sizeof(sntllv2_head_t)); | ||||
|     if(rd < 0) goto __fail2; | ||||
|     if(head->opcode != SNE_SUCCESS) goto __fail2; | ||||
| 
 | ||||
|     /* ok, get available channels */ | ||||
|     head->opcode = SNE_SUCCESS; | ||||
|     head->payload_length = ln; | ||||
|     ln = snprintf(bbuf, 65535 - sizeof(sntllv2_head_t), "(get-channels-list)"); | ||||
|     wr = __conn_write(co, buf, ln + sizeof(sntllv2_head_t)); | ||||
|     if(wr < 0) goto __fail2; | ||||
| 
 | ||||
|     rd = __conn_read(co, head, sizeof(sntllv2_head_t)); | ||||
|     if(rd < 0) goto __fail2; | ||||
|     if(head->opcode != SNE_SUCCESS) goto __fail2; | ||||
|     if(!head->payload_length) goto __fail2; | ||||
|     rd = __conn_read(co, bbuf, head->payload_length); | ||||
|     if(rd < 0) goto __fail2; | ||||
| 
 | ||||
|     /* perform a parsing of the desired message */ | ||||
|     bbuf[rd] = '\0'; | ||||
|     sx = parse_sexp(bbuf, rd); | ||||
|     r = __eval_syssexp(co, sx); | ||||
|     destroy_sexp(sx); | ||||
|     head->opcode = r; | ||||
|     head->payload_length = 0; | ||||
|     wr = __conn_write(co, head, sizeof(sntllv2_head_t)); | ||||
|     if(wr < 0) goto __fail2; | ||||
|     if(r != SNE_SUCCESS) goto __fail2; | ||||
|   } | ||||
| 
 | ||||
|   /* if we're there - negotiation is done, going to init messaging mode */ | ||||
|   r = __connection_second_alloc(co); | ||||
|   if(r != SNE_SUCCESS)  goto __fail3; | ||||
| 
 | ||||
|   /* and now we're need to create a thread poll */ | ||||
|   if(!(bundle = malloc(sizeof(sntllv2_bundle_t)))) { r = SNE_ENOMEM; goto __fail4; } | ||||
|   else { | ||||
|     bundle->buf = buf; | ||||
|     bundle->conn = co; | ||||
|   } | ||||
|   for(i = 0; i < 8; i++) { | ||||
|     if(bundle == 0xdead) bundle = __sntll_bundle_create(co); | ||||
|     if(!bundle) goto __fail5; | ||||
|     r = pthread_create(&thrd_poll[i], NULL, __sntll_thread, bundle); | ||||
|     if(r) goto __fail5; | ||||
|     else bundle = 0xdead; | ||||
|   } | ||||
| 
 | ||||
|   /* all is done, connection now ready */ | ||||
|   co->flags |= SNSX_ALIVE; | ||||
| 
 | ||||
|   return co; | ||||
| 
 | ||||
|  __fail2: | ||||
|   if(buf != MAP_FAILED) munmap(buf, 65536); | ||||
|   SSL_shutdown(co->ssl); | ||||
|   close(sck); | ||||
|  __fail: | ||||
|   if(co) { | ||||
|     if(co->ssl) SSL_free(co->ssl); | ||||
|     if(co->ctx) SSL_CTX_free(co->ctx); | ||||
|     __connection_minimal_free(co); | ||||
|   } | ||||
|   errno = r; | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user