int STS_ServerMain(char **argv) { BIO *bio_listen = BIO_new_accept(argv[0]); argv++; BIO_set_bind_mode(bio_listen, BIO_BIND_REUSEADDR); /* First call to BIO_accept() sets up accept BIO */ if(BIO_do_accept(bio_listen) <= 0) { printf("Ошибка при создании сокета\n"); return 1; } printf("Ждем подключения клиента.\n"); /* Wait for incoming connection */ if(BIO_do_accept(bio_listen) <= 0) { printf("Ошибка подключения!\n"); return 1; } printf("Соединение установлено.\n"); return STS_ServerHandleConnection(BIO_pop(bio_listen), argv); }
int serverMain(char ** argv) { Server server; int i; if (serverReadKey(&server, argv[1])) { fprintf(stderr, "Can't read key from file %s!", argv[1]); return 1; } BIO * bio_listen = BIO_new_accept(argv[0]); BIO_set_bind_mode(bio_listen, BIO_BIND_REUSEADDR); /* First call to BIO_accept() sets up accept BIO */ if(BIO_do_accept(bio_listen) <= 0) { fprintf(stderr, "Error setting up accept\n"); return 1; } /* Wait for incoming connection */ if(BIO_do_accept(bio_listen) <= 0) { fprintf(stderr, "Ошибка подключения!\n"); return 1; } fprintf(stderr, "Соединение установлено.\n"); server.conn = BIO_pop(bio_listen); if(serverHandleClient(&server)) { printf("Клиент не смог доказать знание закрытого ключа RSA!\n\n\n"); } else { printf("Клиент доказал знание закрытого ключа RSA.\n\n\n"); } BIO_free(server.conn); BIO_free(bio_listen); return 0; }
/** Thread body. Accepts SSL connections and adds peers as they connect */ wxThread::ExitCode RAIN::ConnectionListener::Entry() { BIO *listener, *client; SSL *client_ssl; SSL_CTX* ssl_ctx = globalCredentialManager->GetSSLContext(); wxLogVerbose(wxT("starting up RAIN::ConnectionListener; ssl_ctx = %08x"), ssl_ctx); listener = BIO_new_accept(DEFAULT_ACCEPT_STR); if (!listener) { wxLogError("Server socket creation failed"); return NULL; } /* set listener to be non blocking - needed for * this thread's proper behaviour with timely exiting * * also set BIO_BIND_REUSEADDR */ // broken in gcc severely const char a[] = "a"; BIO_ctrl(listener, BIO_C_SET_ACCEPT, 1, (void*)a); BIO_set_bind_mode(listener, BIO_BIND_REUSEADDR); // now bind the port if (BIO_do_accept(listener) <= 0) { wxLogError("Server socket binding failed"); BIO_free_all(listener); return NULL; } while (true) { if (this->GetThread()->TestDestroy()) { wxLogVerbose("RAIN::ConnectionListener thread finishing"); BIO_free_all(listener); return NULL; } else { //wxLogVerbose("RAIN::ConnectionListener thread continuing"); } if (BIO_do_accept(listener) > 0) { // there's a connection waiting to be accepted client = BIO_pop(listener); if (!(client_ssl = SSL_new(ssl_ctx))) { wxLogFatalError("RAIN::ConnectionListener - Error creating new SSL connection from context"); BIO_free_all(client); BIO_free_all(listener); return NULL; } else { SSL_set_bio(client_ssl, client, client); int sa_ret = SSL_accept(client_ssl); int SSLge = SSL_get_error(client_ssl, sa_ret); int runawayGuard = 15; while (runawayGuard-- && sa_ret == -1 && (SSLge == SSL_ERROR_SSL || SSLge == SSL_ERROR_WANT_READ || SSLge == SSL_ERROR_WANT_WRITE)) { /* the handshaking occurs in a non-blocking way, the underlying bio 'client' * inherits the listener's non-blockingness */ sa_ret = SSL_accept(client_ssl); SSLge = SSL_get_error(client_ssl, sa_ret); wxThread::Sleep(1000); } if (runawayGuard < 1 || sa_ret <= 0) { SSL_free(client_ssl); if (runawayGuard < 1) wxLogError("RAIN::ConnectionListener - Timeout while handshaking for new SSL connection"); else wxLogError("RAIN::ConnectionListener - Error accepting new SSL connection: ssl_accept returned %d; ssl_get_error returned %d", sa_ret, SSLge); } else { wxLogVerbose("RAIN::ConnectionListener - SSL_accept succeeded"); RAIN::Connection *nc = new RAIN::Connection(client_ssl); this->connectionPool->AddServedPeer(nc); } } } wxThread::Sleep(2000); } }
/* * This starts a minimal TLS server that only does a * handshake and then closes the connection. This is * strictly used to test TLS session negotiation * behavior with EST. */ static void us1060_start_tls_server (char *cipherstring) { BIO *conn; BIO *listener; BIO *berr; char h_p[25]; SSL *ssl; SSL_CTX *ssl_ctx = NULL; int nid, rv; EC_KEY *ecdh = NULL; berr = BIO_new_fp(stderr, BIO_NOCLOSE); ssl_ctx = SSL_CTX_new(SSLv23_server_method()); if (!ssl_ctx) { printf("Failed to create SSL context\n"); ERR_print_errors(berr); return; } SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); if (SSL_CTX_use_certificate_chain_file(ssl_ctx, US1060_RSA_CERT) != 1) { printf("Failed to load server certificate\n"); ERR_print_errors(berr); return; } if (SSL_CTX_use_PrivateKey_file(ssl_ctx, US1060_RSA_KEY, SSL_FILETYPE_PEM) != 1) { printf("Failed to load server private key\n"); ERR_print_errors(berr); return; } SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_SINGLE_ECDH_USE | SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET); nid = OBJ_sn2nid("prime256v1"); ecdh = EC_KEY_new_by_curve_name(nid); if (ecdh == NULL) { printf("Failed to retreive ECDH curve\n"); ERR_print_errors(berr); return; } SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh); EC_KEY_free(ecdh); if (SSL_CTX_set_cipher_list(ssl_ctx, cipherstring) != 1) { printf("Failed to set server cipher list\n"); ERR_print_errors(berr); return; } SSL_CTX_set_srp_username_callback(ssl_ctx, us1060_srp_cb); sprintf(h_p, "%s:%d", US1060_SERVER_IP, US1060_TLS_PORT); listener = BIO_new_accept(h_p); if (listener == NULL) { printf("IP connection failed\n"); return; } BIO_set_bind_mode(listener, BIO_BIND_REUSEADDR); /* * The first call to do_accept binds the socket */ if (BIO_do_accept(listener) <= 0) { printf("TCP bind failed\n"); BIO_free_all(listener); return; } /* * The second call to do_accept waits for a new * connection request on the listener. * Note that we are in blocking mode for this socket */ if (BIO_do_accept(listener) <= 0) { printf("TCP accept failed\n"); BIO_free_all(listener); return; } conn = BIO_pop(listener); ssl = SSL_new(ssl_ctx); SSL_set_bio(ssl, conn, conn); /* * Now that we have everything ready, let's start waiting for * a client to contact us. Normally we might using a pthread * or some other construct to avoid blocking on the main * thread while waiting for an incoming connection. This * code is simply a contrived example, we will wait on the * main thread for an incoming connection. */ rv = SSL_accept(ssl); if (rv <= 0) { printf("\nFailed to complete TLS handshake %d\n", rv); ERR_print_errors(berr); } SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ssl_ctx); BIO_free(berr); (void)BIO_reset(listener); BIO_free_all(listener); pthread_exit(0); }
/****** * Everything starts here... ******/ int main(int argc, char **argv) { BIO *abio = NULL; BIO *biobuf = NULL; int rc = 0; if (rc = init(argc, argv, &cfg)) goto done; signal(SIGQUIT, SIGQUIThandler); /* We need a BIO to accept connections */ abio = BIO_new_accept(cfg->hostport); if (!abio) { fprintf(stderr, "Unable to create a new accept BIO.\n"); rc = -1; goto done; } BIO_set_bind_mode(abio, BIO_BIND_REUSEADDR); if ((rc = BIO_do_accept(abio)) <= 0) { fprintf(stderr, "Unable to accept connections.\n"); goto done; } /* And we add a buffer BIO that will be duplicated for each created * connections */ biobuf = BIO_new(BIO_f_buffer()); if (!biobuf) { fprintf(stderr, "Unable to create a buffer BIO.\n"); rc = -1; goto done; } BIO_set_accept_bios(abio, biobuf); /* Release all rights and go background */ if (!cfg->debug) { changeidentity(cfg->user, cfg->group); beadaemon(); } while (1) { BIO *cbio = NULL; /* This is a blocking call */ BIO_do_accept(abio); /* A connection has arrived, detach the corresponding BIO and * process the request */ cbio = BIO_pop(abio); processrequest(cbio); } done: BIO_free(abio); return rc; }