void rb_ssl_start_connected(rb_fde_t *F, CNCB * callback, void *data, int timeout) { struct ssl_connect *sconn; if(F == NULL) return; sconn = rb_malloc(sizeof(struct ssl_connect)); sconn->data = data; sconn->callback = callback; sconn->timeout = timeout; F->connect = rb_malloc(sizeof(struct conndata)); F->connect->callback = callback; F->connect->data = data; F->type |= RB_FD_SSL; F->ssl = rb_malloc(sizeof(gnutls_session_t)); gnutls_init(F->ssl, GNUTLS_CLIENT); gnutls_set_default_priority(SSL_P(F)); gnutls_dh_set_prime_bits(SSL_P(F), 1024); gnutls_transport_set_ptr(SSL_P(F), (gnutls_transport_ptr_t) (long int)F->fd); rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn); if(do_ssl_handshake(F, rb_ssl_tryconn_cb)) { rb_ssl_connect_realcb(F, RB_OK, sconn); } }
static void rb_ssl_tryconn(rb_fde_t *F, int status, void *data) { struct ssl_connect *sconn = data; if(status != RB_OK) { rb_ssl_connect_realcb(F, status, sconn); return; } F->type |= RB_FD_SSL; rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn); F->ssl = rb_malloc(sizeof(gnutls_session_t)); gnutls_init(F->ssl, GNUTLS_CLIENT); gnutls_set_default_priority(SSL_P(F)); gnutls_dh_set_prime_bits(SSL_P(F), 1024); gnutls_transport_set_ptr(SSL_P(F), (gnutls_transport_ptr_t) (long int)F->fd); if(do_ssl_handshake(F, rb_ssl_tryconn_cb)) { rb_ssl_connect_realcb(F, RB_OK, sconn); } }
void rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, int addrlen) { new_F->type |= RB_FD_SSL; new_F->ssl = rb_malloc(sizeof(gnutls_session_t)); new_F->accept = rb_malloc(sizeof(struct acceptdata)); new_F->accept->callback = F->accept->callback; new_F->accept->data = F->accept->data; rb_settimeout(new_F, 10, rb_ssl_timeout, NULL); memcpy(&new_F->accept->S, st, addrlen); new_F->accept->addrlen = addrlen; gnutls_init((gnutls_session_t *) new_F->ssl, GNUTLS_SERVER); gnutls_set_default_priority(SSL_P(new_F)); gnutls_credentials_set(SSL_P(new_F), GNUTLS_CRD_CERTIFICATE, x509); gnutls_dh_set_prime_bits(SSL_P(new_F), 1024); gnutls_transport_set_ptr(SSL_P(new_F), (gnutls_transport_ptr_t) (long int)rb_get_fd(new_F)); gnutls_certificate_server_set_request(SSL_P(new_F), GNUTLS_CERT_REQUEST); if(do_ssl_handshake(F, rb_ssl_tryaccept)) { struct acceptdata *ad = F->accept; F->accept = NULL; ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data); rb_free(ad); } }
void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout) { gnutls_session_t *ssl; new_F->type |= RB_FD_SSL; ssl = new_F->ssl = rb_malloc(sizeof(gnutls_session_t)); new_F->accept = rb_malloc(sizeof(struct acceptdata)); new_F->accept->callback = cb; new_F->accept->data = data; rb_settimeout(new_F, timeout, rb_ssl_timeout, NULL); new_F->accept->addrlen = 0; gnutls_init(ssl, GNUTLS_SERVER); gnutls_set_default_priority(*ssl); gnutls_credentials_set(*ssl, GNUTLS_CRD_CERTIFICATE, x509); gnutls_dh_set_prime_bits(*ssl, 1024); gnutls_transport_set_ptr(*ssl, (gnutls_transport_ptr_t) (long int)new_F->fd); gnutls_certificate_server_set_request(*ssl, GNUTLS_CERT_REQUEST); if(do_ssl_handshake(new_F, rb_ssl_tryaccept)) { struct acceptdata *ad = new_F->accept; new_F->accept = NULL; ad->callback(new_F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data); rb_free(ad); } }
static void rb_ssl_tryaccept(rb_fde_t *F, void *data) { int ret; struct acceptdata *ad; lrb_assert(F->accept != NULL); ret = do_ssl_handshake(F, rb_ssl_tryaccept); /* do_ssl_handshake does the rb_setselect */ if(ret == 0) return; ad = F->accept; F->accept = NULL; rb_settimeout(F, 0, NULL, NULL); rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL); if(ret > 0) ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data); else ad->callback(F, RB_ERROR_SSL, NULL, 0, ad->data); rb_free(ad); }
int statcom_main(uint16_t server_port, uint16_t max_clients, char* module_name, int (*call_command_handler_function) (SSL *, int)) { int setupdone=0, connection_id, connectSocket; pid_t pid; /*SSL specific.*/ SSL *ssl; SSL_CTX *ctx; total_clients = 0; ctx = initialize_SSL(server_port, max_clients, module_name); while(1) /*while loop to serve many connections. When one connection arrives, a new process is forked to handle it.*/ { /*and the parent process comes here again to continue listening.*/ if((connectSocket = create_socket_connect_verify(server_port, max_clients, module_name, setupdone, &connection_id)) == ERROR) goto error; switch(pid = fork()) /* here a new child process is created and the parent continues.*/ { case -1:/*something went wrong..*/ mysyslog(LOG_ERR, "Error in forking a new %s connection.\nAborting.....\n", module_name); break; case 0:/*child process*/ signal(SIGCHLD,SIG_IGN); /* to keep track of when a child is terminated.*/ signal(SIGCLD,SIG_IGN); /* to keep track of when a child is terminated.*/ if((ssl = do_ssl_handshake(ctx, connectSocket)) != NULL) /* if OK call function to handle engstation comms.*/ call_command_handler_function(ssl, connection_id); /* this function don't return until the station ends the connection.*/ closeconnection(connectSocket, ssl, ctx, module_name); /* we're done handling this connection, the client will exit now.*/ exit(0); /*when finished handling comms, we kill the child.*/ break; default: /*parent process go on. The parent goes back to the begining of the while loop to continue listening.*/ /*the child handles the new connection.*/ setupdone = 1; mysyslog(LOG_INFO, "Parent saving PID=%d of child in slot=%d\n", pid,connection_id ); used_ports[connection_id].childpid = pid; /*save the PID of the child in the used_port table.*/ break; } error: ; /*an empty statmenent is needed by the compiler.*/ } return 0; /*we should never reach here !*/ }
static void rb_ssl_tryconn(rb_fde_t *F, int status, void *data) { struct ssl_connect *sconn = data; if(status != RB_OK) { rb_ssl_connect_realcb(F, status, sconn); return; } F->type |= RB_FD_SSL; rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn); F->ssl = rb_malloc(sizeof(mbedtls_ssl_context)); rb_ssl_setup_client_context(F); do_ssl_handshake(F, rb_ssl_tryconn_cb, (void *)sconn); }
void rb_ssl_start_connected(rb_fde_t *F, CNCB * callback, void *data, int timeout) { struct ssl_connect *sconn; if(F == NULL) return; sconn = rb_malloc(sizeof(struct ssl_connect)); sconn->data = data; sconn->callback = callback; sconn->timeout = timeout; F->connect = rb_malloc(sizeof(struct conndata)); F->connect->callback = callback; F->connect->data = data; F->type |= RB_FD_SSL; F->ssl = rb_malloc(sizeof(mbedtls_ssl_context)); rb_ssl_setup_client_context(F); rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn); do_ssl_handshake(F, rb_ssl_tryconn_cb, (void *)sconn); }
static void rb_ssl_tryconn_cb(rb_fde_t *F, void *data) { struct ssl_connect *sconn = data; int ret; ret = do_ssl_handshake(F, rb_ssl_tryconn_cb, (void *)sconn); switch (ret) { case -1: rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn); break; case 0: /* do_ssl_handshake does the rb_setselect stuff */ return; default: break; } rb_ssl_connect_realcb(F, RB_OK, sconn); }
void rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, rb_socklen_t addrlen) { new_F->type |= RB_FD_SSL; new_F->ssl = rb_malloc(sizeof(mbedtls_ssl_context)); new_F->accept = rb_malloc(sizeof(struct acceptdata)); new_F->accept->callback = F->accept->callback; new_F->accept->data = F->accept->data; rb_settimeout(new_F, 10, rb_ssl_timeout, NULL); memcpy(&new_F->accept->S, st, addrlen); new_F->accept->addrlen = addrlen; rb_ssl_setup_srv_context(new_F); if(do_ssl_handshake(F, rb_ssl_tryaccept, NULL)) { struct acceptdata *ad = F->accept; F->accept = NULL; ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data); rb_free(ad); } }
void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout) { mbedtls_ssl_context *ssl; new_F->type |= RB_FD_SSL; ssl = new_F->ssl = rb_malloc(sizeof(mbedtls_ssl_context)); new_F->accept = rb_malloc(sizeof(struct acceptdata)); new_F->accept->callback = cb; new_F->accept->data = data; rb_settimeout(new_F, timeout, rb_ssl_timeout, NULL); new_F->accept->addrlen = 0; rb_ssl_setup_srv_context(new_F); if(do_ssl_handshake(new_F, rb_ssl_tryaccept, NULL)) { struct acceptdata *ad = new_F->accept; new_F->accept = NULL; ad->callback(new_F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data); rb_free(ad); } }