int main(int argc, char *argv[]) { BIO *acc, *client; pthread_t pid; init_OpenSSL(); acc = BIO_new_accept(PORT); if(!acc) int_error("Error creating server socket"); if(BIO_do_accept(acc)<=0) int_error("Error binding server socket"); for(;;) { if(BIO_do_accept(acc)<=0) int_error("Error accepting connection"); client=BIO_pop(acc); pthread_create(&pid, NULL, server_thread, client); } BIO_free(acc); return 0; }
int receiveFile(char *socket, char *outfile) { BIO *receive = BIO_new_accept(socket); BIO *fileout = BIO_new_file(outfile,"w"); // it seems you need to do this twice.. not sure why, but we do // guess I'll try figure out why at some point if (BIO_do_accept(receive) <= 0) { fprintf(stderr, "Error setting up accept\n"); exit(0); } if (BIO_do_accept(receive) <= 0) { fprintf(stderr, "Error setting up accept\n"); exit(0); } char tmpbuf[BUFSIZ]; // magic wrapper BIO *bufbio = BIO_new(BIO_f_buffer()); BIO_push(bufbio, receive); //read in the file length and store BIO_gets(bufbio, tmpbuf, BUFSIZ); printf("Getting file length: %s\n", tmpbuf); unsigned int size = atoi(tmpbuf); transmit(bufbio, fileout, size); BIO_flush(fileout); BIO_free(bufbio); return 1; }
int main(int argc, char **argv) { BIO *acc, *client; THREAD_TYPE tid; init_OpenSSL(); acc = BIO_new_accept(SERV_PORT); if(!acc) { int_error("Error creating server socket.\n"); } if(BIO_do_accept(acc) <= 0) { int_error("Error binding server socket.\n"); } for(;;) { if(BIO_do_accept(acc) <= 0) { int_error("Error accepting connection from client.\n"); } client = BIO_pop(acc); THREAD_CREATE(tid, server_thread, client); } BIO_free(acc); return 0; }
int main(int argc, char **argv) { BIO *acc, *client; SSL *ssl; SSL_CTX *ctx; pthread_t tid; init_openssl(); seed_prng(64); ctx = setup_server_ctx(); acc = BIO_new_accept(PORT); if(!acc) log_err("Error creating server socket."); /* first call BIO_do_accept() setup accept BIO */ if(BIO_do_accept(acc) <= 0) log_err("Error binding server socket."); for(;;) { if(BIO_do_accept(acc) <= 0) log_err("Error accepting connection."); client = BIO_pop(acc); if(!(ssl = SSL_new(ctx))) log_err("Error creating SSL context."); SSL_set_bio(ssl, client, client); pthread_create(&tid, NULL, server_thread, ssl); } SSL_CTX_free(ctx); BIO_free(acc); return 0; }
int main(int argc, char *argv[]) { BIO *server, *client; SSL *ssl; SSL_CTX *ctx; pthread_t tid; init_OpenSSL(); /* * It creates a new accept BIO with port host_port */ server = BIO_new_accept("9104"); if (!server) error("Error creating server socket"); /* * BIO_do_accept() serves two functions. When it is first called, after the accept * BIO has been setup, it will attempt to create the accept socket and bind an * address to it. Second and subsequent calls to BIO_do_accept() will await an * incoming connection,or request a retry in non blocking mode */ if (BIO_do_accept(server) <= 0) error("Setup BIO in Accepting Mode\n"); for (;;) { if (BIO_do_accept(server) <= 0) error("Error Accepting Connection\n"); /* * When a connection is established a new socket BIO is created for the * connection and appended to the chain. * BIO_pop removes the BIO b from a chain and returns the next BIO in the * chain. */ client = BIO_pop(server); /* *Now client here is containing a BIO for the recently established connection *and server will now be a single BIO again which can be used to await further *incoming connections */ pthread_create(&tid, NULL, (void *)server_thread, client); } /* * Close the connection */ BIO_free(server); return 0; }
/* The first line specifiy some settings in the ctx and ssl object: SSL_OP_ALL: enables all work around codes SSL_OP_NO_SSLv2: no SSLv2 connections are allowed (this should fail anyway because only TLSv1 connection are allowed) SSL_OP_SINGLE_DH_USE: the server generates a new private key for each new connection SSL_VERIFY_PEER: asks the client for a certificate SSL_VERIFY_FAIL_IF_NO_PEER_CERT: if the client doesn't present a cert the connection gets terminated CIPHER_LIST: is defined in ssl_server.h (look there for a detailed description) After setting up these things the bio object will be created and a ssl object assigned. Then the ssl engine mode is set to SSL_MODE_AUTO_RETRY. All available modes are: SSL_MODE_ENABLE_PARTIAL_WRITE: Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success when just a single record has been written). When not set (the default), SSL_write() will only report success once the complete chunk was written. Once SSL_write() returns with r, r bytes have been successfully written and the next call to SSL_write() must only send the n-r bytes left, imitating the behaviour of write(). SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER: Make it possible to retry SSL_write() with changed buffer location (the buffer contents must stay the same). This is not the default to avoid the misconception that non-blocking SSL_write() behaves like non-blocking write(). SSL_MODE_AUTO_RETRY: Never bother the application with retries if the transport is blocking. If a renegotiation take place during normal operation, a ssl_read(3) or ssl_write(3) would return with -1 and indicate the need to retry with SSL_ERROR_WANT_READ . In a non-blocking environment applications must be prepared to handle incomplete read/write operations. In a blocking environment, applications are not always prepared to deal with read/write operations returning without success report. The flag SSL_MODE_AUTO_RETRY will cause read/write operations to only return after the handshake and successful completion. The server contains 3 bio objects: bio, abio and out. 'bio' contains the context, 'abio' binds to the socket and 'out' is the established connection. */ void SSL_Server::bind(){ SSL_CTX_set_verify(getCTX(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); SSL_CTX_set_options(getCTX(), SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE); SSL_CTX_set_tmp_dh_callback(getCTX(), tmp_dh_callback); if(SSL_CTX_set_cipher_list(getCTX(), CIPHER_LIST) != 1) msgHandler->error("setting cipher list failed (no valid ciphers)", CRITICAL); msgHandler->debug("trying to set context to bio"); bio = BIO_new_ssl(getCTX(), 0); if(bio == NULL){ string error("Cannot set context to bio "); error.append(getSocket()); error.append("\nSSL_ERROR: "); error.append(ERR_reason_error_string(ERR_get_error())); msgHandler->error(error, CRITICAL); } else msgHandler->debug("set context to bio successful"); BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); msgHandler->debug("trying to bind to socket"); abio = BIO_new_accept((char*)getSocket().c_str()); BIO_set_accept_bios(abio, bio); if(BIO_do_accept(abio) <= 0){ string error("Bind to socket "); error.append(getSocket()); error.append(" failed.\nSSL_ERROR: "); error.append(ERR_reason_error_string(ERR_get_error())); msgHandler->error(error, CRITICAL); } else msgHandler->log("bind to socket successful"); }
static LUA_FUNCTION(openssl_bio_accept) { BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); int first = lua_isnoneornil(L, 2) ? 0 : lua_toboolean(L, 2); int ret = BIO_do_accept(bio); if (ret == 1) { if (!first) { BIO *nb = BIO_pop(bio); PUSH_OBJECT(nb, "openssl.bio"); openssl_newvalue(L, nb); lua_pushboolean(L, 1); openssl_setvalue(L, nb, "free_all"); return 1; } else return openssl_pushresult(L, ret); } else luaL_error(L, "BIO_do_accept fail"); return 0; }
void *cliserver(void *arg) { struct srv_ctx *srv = (struct srv_ctx *)arg; struct freeq_ctx *freeqctx = srv->freeqctx; struct conn_ctx *conn_ctx; int res; pthread_t tid; BIO *acc, *client; static stralloc aggport = {0}; res = control_readline(&aggport, "control/aggport"); if (!res) { err(freeqctx, "unable to read control/aggport"); exit(FREEQ_ERR); } stralloc_0(&aggport); dbg(freeqctx, "starting aggregation listener on %s\n", (char *)aggport.s); acc = BIO_new_accept((char *)aggport.s); if (!acc) { int_error("Error creating server socket"); exit(FREEQ_ERR); } if (BIO_do_accept(acc) <= 0) int_error("Error binding server socket"); for (;;) { dbg(freeqctx, "waiting for connection\n"); if (BIO_do_accept(acc) <= 0) int_error("Error accepting connection"); dbg(freeqctx, "accepted connection, setting up ssl\n"); //bio_peername(acc); client = BIO_pop(acc); conn_ctx = malloc(sizeof(struct conn_ctx)); conn_ctx->srvctx = srv; conn_ctx->client = client; pthread_create(&tid, 0, &conn_handler, (void *)conn_ctx); } }
void *sqlserver(void *arg) { struct srv_ctx *srv = (struct srv_ctx *)arg; struct freeq_ctx *freeqctx = srv->freeqctx; int res; pthread_t thread; BIO *acc, *client; signal(SIGINT, cleanup); signal(SIGTERM, cleanup); signal(SIGPIPE, SIG_IGN); static stralloc sqlport = {0}; res = control_readline(&sqlport, "control/sqlport"); if (!res) { err(freeqctx, "unable to read control/sqlport\n"); exit(FREEQ_ERR); } stralloc_0(&sqlport); dbg(freeqctx, "starting query listener on %s\n", (char *)sqlport.s); acc = BIO_new_accept((char *)sqlport.s); if (!acc) { int_error("Error creating server socket"); exit(FREEQ_ERR); } if (BIO_do_accept(acc) <= 0) int_error("Error binding server socket"); for (;;) { if (BIO_do_accept(acc) <= 0) int_error("Error accepting connection"); client = BIO_pop(acc); struct conn_ctx *conn = malloc(sizeof(struct conn_ctx)); conn->srvctx = srv; conn->client = client; pthread_create(&thread, 0, &sqlhandler, (void *)conn); } BIO_free(acc); pthread_exit(FREEQ_OK);; }
int main(int argc, char * argv[]) { BIO * acc, * client; THREAD_TYPE tid; SSL * ssl; SSL_CTX * ctx; init_OpenSSL(); seed_prng(); ctx = setup_server_ctx(); acc = BIO_new_accept(PORT); if (!acc) int_error("Error creating server socket"); if (BIO_do_accept(acc) <= 0) int_error("Error binding server socket"); // BIO_do_accept() will block and wait for a remote connection. while (1) { if (BIO_do_accept(acc) <= 0) int_error("Error accepting connection"); // get the client BIO client = BIO_pop(acc); if (!(ssl = SSL_new(ctx))) int_error("Error creating SSL context"); SSL_set_accept_state(ssl); SSL_set_bio(ssl, client, client); // create a new thread to handle the new connection, // The thread will call do_server_loop with the client BIO. // THREAD_CREATE(tid, entry, arg); // tid is the id of the new thread. // server_thread is the function defined above, which will call // do_server_loop() with the client BIO. THREAD_CREATE(tid, server_thread, ssl); } SSL_CTX_free(ctx); BIO_free(acc); return 0; }
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 main(int argc, char *argv[]) { BIO *acc, *client; SSL *ssl; SSL_CTX *ctx; THREAD_TYPE tid; init_OpenSSL( ); seed_prng(); ctx = setup_server_ctx( ); acc = BIO_new_accept(PORT); if (!acc) int_error("Error creating server socket"); if (BIO_do_accept(acc) <= 0) int_error("Error binding server socket"); while(1) { if (BIO_do_accept(acc) <= 0) int_error("Error accepting connection"); client = BIO_pop(acc); if (!(ssl = SSL_new(ctx))) int_error("Error creating SSL context"); SSL_set_accept_state(ssl); SSL_set_bio(ssl, client, client); THREAD_CREATE(tid, (void *)server_thread, ssl); } SSL_CTX_free(ctx); BIO_free(acc); return 0; }
int main(int argc, char *argv[]) { BIO *acc, *client; SSL *ssl; SSL_CTX *ctx; THREAD_TYPE tid; void* (*func)(void*) = &server_thread; std::cout << "before init\n"; init_OpenSSL(); //seed_prng(); std::cout << "after init\n"; ctx = setup_server_ctx(); acc = BIO_new_accept(PORT); if(!acc) int_error("Error creating socket"); if(BIO_do_accept(acc) <= 0) int_error("Error binding socket"); for(;;) { if(BIO_do_accept(acc) <= 0) int_error("Error accepting connection"); client = BIO_pop(acc); if(!(ssl = SSL_new(ctx))) int_error("Error creating ssl object"); SSL_set_bio(ssl,client,client); THREAD_CREATE(tid,func,ssl); } BIO_free(acc); SSL_CTX_free(ctx); return 0; }
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; }
/* The server goes into the listening mode (BIO_do_accept(abio)). If an incoming connection appears it will be passed to a ConnectionHandler. For this the bio object 'out' pops the first bio from 'abio' (the latest connection). */ void SSL_Server::listen(){ msgHandler->log("entering listening mode now"); while(true){ if(BIO_do_accept(abio) <= 0){ string error("Entering listening mode failed.\nSSL_ERROR: "); error.append(ERR_reason_error_string(ERR_get_error())); msgHandler->error(error, CRITICAL); } out = BIO_pop(abio); msgHandler->log("incoming connection"); connHandler->addConnection(out); msgHandler->log("entering listening mode again."); } }
/** 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); } }
int main(int argc, char *argv[]) { char *port = "*:4433"; BIO *ssl_bio, *tmp; SSL_CTX *ctx; SSL_CONF_CTX *cctx; char buf[512]; BIO *in = NULL; int ret = 1, i; char **args = argv + 1; int nargs = argc - 1; SSL_load_error_strings(); /* Add ciphers and message digests */ OpenSSL_add_ssl_algorithms(); ctx = SSL_CTX_new(SSLv23_server_method()); cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); while (*args && **args == '-') { int rv; /* Parse standard arguments */ rv = SSL_CONF_cmd_argv(cctx, &nargs, &args); if (rv == -3) { fprintf(stderr, "Missing argument for %s\n", *args); goto err; } if (rv < 0) { fprintf(stderr, "Error in command %s\n", *args); ERR_print_errors_fp(stderr); goto err; } /* If rv > 0 we processed something so proceed to next arg */ if (rv > 0) continue; /* Otherwise application specific argument processing */ if (strcmp(*args, "-port") == 0) { port = args[1]; if (port == NULL) { fprintf(stderr, "Missing -port argument\n"); goto err; } args += 2; nargs -= 2; continue; } else { fprintf(stderr, "Unknown argument %s\n", *args); goto err; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } #ifdef ITERATE_CERTS /* * Demo of how to iterate over all certificates in an SSL_CTX structure. */ { X509 *x; int rv; rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST); while (rv) { X509 *x = SSL_CTX_get0_certificate(ctx); X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); printf("\n"); rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT); } fflush(stdout); } #endif /* Setup server side SSL bio */ ssl_bio = BIO_new_ssl(ctx, 0); if ((in = BIO_new_accept(port)) == NULL) goto err; /* * This means that when a new connection is accepted on 'in', The ssl_bio * will be 'duplicated' and have the new socket BIO push into it. * Basically it means the SSL BIO will be automatically setup */ BIO_set_accept_bios(in, ssl_bio); again: /* * The first call will setup the accept socket, and the second will get a * socket. In this loop, the first actual accept will occur in the * BIO_read() function. */ if (BIO_do_accept(in) <= 0) goto err; for (;;) { i = BIO_read(in, buf, 512); if (i == 0) { /* * If we have finished, remove the underlying BIO stack so the * next time we call any function for this BIO, it will attempt * to do an accept */ printf("Done\n"); tmp = BIO_pop(in); BIO_free_all(tmp); goto again; } if (i < 0) goto err; fwrite(buf, 1, i, stdout); fflush(stdout); } ret = 0; err: if (ret) { ERR_print_errors_fp(stderr); } BIO_free(in); exit(ret); return (!ret); }
int main(){ int len = 1024; //buffer length char buf[len]; //read buffer /* Initializing OpenSSL */ SSL_load_error_strings(); ERR_load_BIO_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); BIO *bio, *abio, *out; //the sockets SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); SSL *ssl; if( ctx == NULL ){ fprintf(stderr, "DEBUG ctx is null\n"); fprintf(stderr, "ERROR::OpenSLL: %s\n", ERR_reason_error_string(ERR_get_error())); exit(1); } //get password for private key // SSL_CTX_set_default_passwd_cb( ctx, &pem_passwd_cb ); //load certificate (with public key) SSL_CTX_use_certificate_file( ctx, "/home/mml/Develop/ca/certs/01.pem", SSL_FILETYPE_PEM); //load private key SSL_CTX_use_PrivateKey_file( ctx, "/home/mml/Develop/ca/testkey.pem", SSL_FILETYPE_PEM); bio = BIO_new_ssl(ctx, 0); if( bio == NULL ){ fprintf(stderr, "ERROR cannot bind\n"); exit(1); } BIO_get_ssl(bio, &ssl); SSL_set_mode( ssl, SSL_MODE_AUTO_RETRY ); abio = BIO_new_accept("localhost:15001"); BIO_set_accept_bios(abio, bio); BIO_do_accept(abio); fprintf(stdout, "DEBUG: waiting for connection\n"); BIO_do_accept(abio); out = BIO_pop(abio); fprintf(stdout, "DEBUG: doing handshake\n"); BIO_do_handshake(out); if(BIO_write(out, "Hello", 5) <= 0){ if(! BIO_should_retry(bio)) { fprintf(stderr, "ERROR connection is already closed. (write)\n"); exit(1); } else { //retry routine } } bzero(buf, len); if( BIO_read(out, buf, len) <= 0 ){ if( !(BIO_should_retry(bio)) ){ fprintf(stderr, "ERROR connection is already closed (read)\n"); exit(0); } else { //retry routine } } fprintf(stdout, "Hello%s\n", buf); //close connection BIO_free_all(abio); BIO_free_all(out); BIO_free_all(bio); SSL_CTX_free(ctx); return 0; }
/* * 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); }
int main(int argc, char **argv) { char buf[BUFFER_SIZE]; SSL_CTX *ctx; const SSL_METHOD *method; BIO *abio, *cbio; if (argc < 2) { fprintf(stderr, "Usage: %s [port]\n", argv[0]); exit(EXIT_FAILURE); } // init openssl lib. SSL_library_init(); // call OpenSSL_add_ssl_algorithms(); ERR_load_BIO_strings(); SSL_load_error_strings(); // setup tls context. method = TLSv1_2_server_method(); // SSLv23_server_method(); ctx = SSL_CTX_new(method); if (!ctx) { perror("Unable to create SSL context"); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } /* Set the key and cert */ if (SSL_CTX_use_certificate_file(ctx, CERT_FILE_PATH, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } if (SSL_CTX_use_PrivateKey_file(ctx, KEY_FILE_PATH, SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384"); SSL_CTX_set_ecdh_auto(ctx, 1); // create BIO(high level API); for accept abio = BIO_new_accept(argv[1]); if(BIO_do_accept(abio) <= 0) { // first BIO_do_accept() is as to init BIO. fprintf(stderr, "Error setting up accept\n"); ERR_print_errors_fp(stderr); exit(0); } // configuration for I/O operation over ssl/tls. BIO_set_accept_bios(abio, BIO_new_ssl(ctx, 0)); // listen loop printf("Server is listening on %d\n", atoi(argv[1])); while (1) { if(BIO_do_accept(abio) <= 0) { fprintf(stderr, "Error accepting connection\n"); ERR_print_errors_fp(stderr); exit(0); } fprintf(stderr, "Connection 1 established\n"); /* Retrieve BIO for connection */ cbio = BIO_pop(abio); while (1) { int len, err; len = BIO_read(cbio, buf, BUFFER_SIZE); if (!len) break; if (len < 0) { fprintf(stderr, "error SSL_read"); break; } err = BIO_write(cbio, buf, len); if (err < 0) { fprintf(stderr, "error SSL_write"); break; } } BIO_free(cbio); } }
bool TLS_SOCKET_CLASS::accept(BASE_SOCKET_CLASS** acceptedSocket_ptr_ptr) // DESCRIPTION : Accept connection from listen socket. // PRECONDITIONS : // POSTCONDITIONS : // EXCEPTIONS : // NOTES : The returned socket was new'ed so it must be deleted by the caller //<<=========================================================================== { *acceptedSocket_ptr_ptr = NULL; BIO* acceptedBio_ptr; SSL* acceptedSsl_ptr; long error; int fileDesc; struct fd_set fds; struct timeval tv = {1, 0}; // always timeout in 1 second int sel; if (terminatingM) { if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - In process of terminating. Cannot accept."); } // return - in process of termintating return false; } // make sure we are listening to the port if (!listeningM) { if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Socket is not listening to port %d. Cannot accept a connection.", localListenPortM); } return false; } if (acceptBioM_ptr == NULL) { if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Socket is listening to port %d, but not bound.", localListenPortM); } listeningM = false; return false; } if (loggerM_ptr) { loggerM_ptr->text(LOG_DEBUG, 1, "Secure Socket - tls::accept()"); } // get the file descriptor and set up the file descriptor set for select() fileDesc = BIO_get_fd(acceptBioM_ptr, NULL); if (fileDesc == -1) { openSslError("getting listen socket file descriptor"); return false; } // wait for a connection do { FD_ZERO(&fds); FD_SET(fileDesc, &fds); sel = select(fileDesc + 1, &fds, NULL, NULL, &tv); if (sel == 0) { // no data at the end of the timeout - check for terminating if (terminatingM) { return false; } } else if (sel == SOCKET_ERROR) { // socket error if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Error waiting to accept connection (error code %d)", WSAGetLastError()); } return false; } else if (sel != 1) { // unknown error if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Unknown error while waiting to accept connection (select returned %d)", sel); } return false; } } while (sel != 1); // accept a connection if (BIO_do_accept(acceptBioM_ptr) <= 0) { openSslError(LOG_DEBUG, "accepting connection on port %d", localListenPortM); close(); return false; } // get the new connection acceptedBio_ptr = BIO_pop(acceptBioM_ptr); // setup the socket structure acceptedSsl_ptr = SSL_new(ctxM_ptr); if (acceptedSsl_ptr == NULL) { openSslError("creating accepted secure socket object"); BIO_free(acceptedBio_ptr); return false; } // set the 'this' pointer for the callbacks openSslMsgCallback and openSslVerifyCallback SSL_set_msg_callback_arg(acceptedSsl_ptr, static_cast<void*>(this)); SSL_set_accept_state(acceptedSsl_ptr); SSL_set_bio(acceptedSsl_ptr, acceptedBio_ptr, acceptedBio_ptr); // the ssl takes over the BIO memory if (SSL_accept(acceptedSsl_ptr) <= 0) { openSslError("accepting secure connection to port %d", localListenPortM); SSL_free(acceptedSsl_ptr); return false; } // make sure everything is OK error = postConnectionCheck(acceptedSsl_ptr); if (error != X509_V_OK) { openSslError("checking connection parameters after accepting from port %d", localListenPortM); SSL_free(acceptedSsl_ptr); return false; } // create a socket for the new connection *acceptedSocket_ptr_ptr = new TLS_SOCKET_CLASS(*this, acceptedSsl_ptr); if (loggerM_ptr && (loggerM_ptr->getLogMask() & LOG_DEBUG)) { char buffer[128]; SSL_CIPHER_description(SSL_get_current_cipher(acceptedSsl_ptr), buffer, 128); loggerM_ptr->text(LOG_DEBUG, 1, "Secure Socket - %s connection opened using cipher %s", SSL_get_version(acceptedSsl_ptr), buffer); } return true; }
int main(int argc, char *argv[]) { char *port = "*:4433"; BIO *in = NULL; BIO *ssl_bio, *tmp; SSL_CTX *ctx; SSL_CONF_CTX *cctx = NULL; CONF *conf = NULL; STACK_OF(CONF_VALUE) *sect = NULL; CONF_VALUE *cnf; long errline = -1; char buf[512]; int ret = EXIT_FAILURE, i; ctx = SSL_CTX_new(TLS_server_method()); conf = NCONF_new(NULL); if (NCONF_load(conf, "accept.cnf", &errline) <= 0) { if (errline <= 0) fprintf(stderr, "Error processing config file\n"); else fprintf(stderr, "Error on line %ld\n", errline); goto err; } sect = NCONF_get_section(conf, "default"); if (sect == NULL) { fprintf(stderr, "Error retrieving default section\n"); goto err; } cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { int rv; cnf = sk_CONF_VALUE_value(sect, i); rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); if (rv > 0) continue; if (rv != -2) { fprintf(stderr, "Error processing %s = %s\n", cnf->name, cnf->value); ERR_print_errors_fp(stderr); goto err; } if (strcmp(cnf->name, "Port") == 0) { port = cnf->value; } else { fprintf(stderr, "Unknown configuration option %s\n", cnf->name); goto err; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } /* Setup server side SSL bio */ ssl_bio = BIO_new_ssl(ctx, 0); if ((in = BIO_new_accept(port)) == NULL) goto err; /* * This means that when a new connection is accepted on 'in', The ssl_bio * will be 'duplicated' and have the new socket BIO push into it. * Basically it means the SSL BIO will be automatically setup */ BIO_set_accept_bios(in, ssl_bio); again: /* * The first call will setup the accept socket, and the second will get a * socket. In this loop, the first actual accept will occur in the * BIO_read() function. */ if (BIO_do_accept(in) <= 0) goto err; for (;;) { i = BIO_read(in, buf, 512); if (i == 0) { /* * If we have finished, remove the underlying BIO stack so the * next time we call any function for this BIO, it will attempt * to do an accept */ printf("Done\n"); tmp = BIO_pop(in); BIO_free_all(tmp); goto again; } if (i < 0) { if (BIO_should_retry(in)) continue; goto err; } fwrite(buf, 1, i, stdout); fflush(stdout); } ret = EXIT_SUCCESS; err: if (ret != EXIT_SUCCESS) ERR_print_errors_fp(stderr); BIO_free(in); return ret; }
netsnmp_transport * netsnmp_tlstcp_open(netsnmp_transport *t) { _netsnmpTLSBaseData *tlsdata; BIO *bio; SSL_CTX *ctx; SSL *ssl; int rc = 0; _netsnmp_verify_info *verify_info; netsnmp_assert_or_return(t != NULL, NULL); netsnmp_assert_or_return(t->data != NULL, NULL); netsnmp_assert_or_return(sizeof(_netsnmpTLSBaseData) == t->data_length, NULL); tlsdata = t->data; if (tlsdata->flags & NETSNMP_TLSBASE_IS_CLIENT) { /* Is the client */ /* RFC5953 Section 5.3.1: Establishing a Session as a Client * 1) The snmpTlstmSessionOpens counter is incremented. */ snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENS); /* RFC5953 Section 5.3.1: Establishing a Session as a Client 2) The client selects the appropriate certificate and cipher_suites for the key agreement based on the tmSecurityName and the tmRequestedSecurityLevel for the session. For sessions being established as a result of a SNMP-TARGET-MIB based operation, the certificate will potentially have been identified via the snmpTlstmParamsTable mapping and the cipher_suites will have to be taken from system-wide or implementation-specific configuration. If no row in the snmpTlstmParamsTable exists then implementations MAY choose to establish the connection using a default client certificate available to the application. Otherwise, the certificate and appropriate cipher_suites will need to be passed to the openSession() ASI as supplemental information or configured through an implementation-dependent mechanism. It is also implementation-dependent and possibly policy-dependent how tmRequestedSecurityLevel will be used to influence the security capabilities provided by the (D)TLS connection. However this is done, the security capabilities provided by (D)TLS MUST be at least as high as the level of security indicated by the tmRequestedSecurityLevel parameter. The actual security level of the session is reported in the tmStateReference cache as tmSecurityLevel. For (D)TLS to provide strong authentication, each principal acting as a command generator SHOULD have its own certificate. */ /* Implementation notes: we do most of this in the sslctx_client_setup The transport should have been f_config()ed with the proper fingerprints to use (which is stored in tlsdata), or we'll use the default identity fingerprint if that can be found. */ /* XXX: check securityLevel and ensure no NULL fingerprints are used */ /* set up the needed SSL context */ tlsdata->ssl_context = ctx = sslctx_client_setup(TLSv1_method(), tlsdata); if (!ctx) { snmp_log(LOG_ERR, "failed to create TLS context\n"); return NULL; } /* RFC5953 Section 5.3.1: Establishing a Session as a Client 3) Using the destTransportDomain and destTransportAddress values, the client will initiate the (D)TLS handshake protocol to establish session keys for message integrity and encryption. */ /* Implementation note: The transport domain and address are pre-processed by this point */ /* Create a BIO connection for it */ DEBUGMSGTL(("tlstcp", "connecting to tlstcp %s\n", tlsdata->addr_string)); t->remote = (void *) strdup(tlsdata->addr_string); t->remote_length = strlen(tlsdata->addr_string) + 1; bio = BIO_new_connect(tlsdata->addr_string); /* RFC5953 Section 5.3.1: Establishing a Session as a Client 3) continued: If the attempt to establish a session is unsuccessful, then snmpTlstmSessionOpenErrors is incremented, an error indication is returned, and processing stops. */ if (NULL == bio) { snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS); snmp_log(LOG_ERR, "tlstcp: failed to create bio\n"); _openssl_log_error(rc, NULL, "BIO creation"); return NULL; } /* Tell the BIO to actually do the connection */ if ((rc = BIO_do_connect(bio)) <= 0) { snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS); snmp_log(LOG_ERR, "tlstcp: failed to connect to %s\n", tlsdata->addr_string); _openssl_log_error(rc, NULL, "BIO_do_connect"); BIO_free(bio); return NULL; } /* Create the SSL layer on top of the socket bio */ ssl = tlsdata->ssl = SSL_new(ctx); if (NULL == ssl) { snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS); snmp_log(LOG_ERR, "tlstcp: failed to create a SSL connection\n"); BIO_free(bio); return NULL; } /* Bind the SSL layer to the BIO */ SSL_set_bio(ssl, bio, bio); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); verify_info = SNMP_MALLOC_TYPEDEF(_netsnmp_verify_info); if (NULL == verify_info) { snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS); snmp_log(LOG_ERR, "tlstcp: failed to create a SSL connection\n"); SSL_shutdown(ssl); BIO_free(bio); return NULL; } SSL_set_ex_data(ssl, tls_get_verify_info_index(), verify_info); /* Then have SSL do it's connection over the BIO */ if ((rc = SSL_connect(ssl)) <= 0) { snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS); snmp_log(LOG_ERR, "tlstcp: failed to ssl_connect\n"); BIO_free(bio); return NULL; } /* RFC5953 Section 5.3.1: Establishing a Session as a Client 3) continued: If the session failed to open because the presented server certificate was unknown or invalid then the snmpTlstmSessionUnknownServerCertificate or snmpTlstmSessionInvalidServerCertificates MUST be incremented and a snmpTlstmServerCertificateUnknown or snmpTlstmServerInvalidCertificate notification SHOULD be sent as appropriate. Reasons for server certificate invalidation includes, but is not limited to, cryptographic validation failures and an unexpected presented certificate identity. */ /* RFC5953 Section 5.3.1: Establishing a Session as a Client 4) The (D)TLS client MUST then verify that the (D)TLS server's presented certificate is the expected certificate. The (D)TLS client MUST NOT transmit SNMP messages until the server certificate has been authenticated, the client certificate has been transmitted and the TLS connection has been fully established. If the connection is being established from configuration based on SNMP-TARGET-MIB configuration, then the snmpTlstmAddrTable DESCRIPTION clause describes how the verification is done (using either a certificate fingerprint, or an identity authenticated via certification path validation). If the connection is being established for reasons other than configuration found in the SNMP-TARGET-MIB then configuration and procedures outside the scope of this document should be followed. Configuration mechanisms SHOULD be similar in nature to those defined in the snmpTlstmAddrTable to ensure consistency across management configuration systems. For example, a command-line tool for generating SNMP GETs might support specifying either the server's certificate fingerprint or the expected host name as a command line argument. */ /* Implementation notes: - All remote certificate fingerprints are expected to be stored in the transport's config information. This is true both for CLI clients and TARGET-MIB sessions. - netsnmp_tlsbase_verify_server_cert implements these checks */ if (netsnmp_tlsbase_verify_server_cert(ssl, tlsdata) != SNMPERR_SUCCESS) { /* XXX: unknown vs invalid; two counters */ snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONUNKNOWNSERVERCERTIFICATE); snmp_log(LOG_ERR, "tlstcp: failed to verify ssl certificate\n"); SSL_shutdown(ssl); BIO_free(bio); return NULL; } /* RFC5953 Section 5.3.1: Establishing a Session as a Client 5) (D)TLS provides assurance that the authenticated identity has been signed by a trusted configured certification authority. If verification of the server's certificate fails in any way (for example because of failures in cryptographic verification or the presented identity did not match the expected named entity) then the session establishment MUST fail, the snmpTlstmSessionInvalidServerCertificates object is incremented. If the session can not be opened for any reason at all, including cryptographic verification failures, then the snmpTlstmSessionOpenErrors counter is incremented and processing stops. */ /* XXX: add snmpTlstmSessionInvalidServerCertificates on crypto failure */ /* RFC5953 Section 5.3.1: Establishing a Session as a Client 6) The TLSTM-specific session identifier (tlstmSessionID) is set in the tmSessionID of the tmStateReference passed to the TLS Transport Model to indicate that the session has been established successfully and to point to a specific (D)TLS connection for future use. The tlstmSessionID is also stored in the LCD for later lookup during processing of incoming messages (Section 5.1.2). */ /* Implementation notes: - the tlsdata pointer is used as our session identifier, as noted in the netsnmp_tlstcp_recv() function comments. */ t->sock = BIO_get_fd(bio, NULL); } else { #ifndef NETSNMP_NO_LISTEN_SUPPORT /* Is the server */ /* Create the socket bio */ DEBUGMSGTL(("tlstcp", "listening on tlstcp port %s\n", tlsdata->addr_string)); tlsdata->accept_bio = BIO_new_accept(tlsdata->addr_string); t->local = (void *) strdup(tlsdata->addr_string); t->local_length = strlen(tlsdata->addr_string)+1; if (NULL == tlsdata->accept_bio) { snmp_log(LOG_ERR, "TLSTCP: Falied to create a accept BIO\n"); return NULL; } /* openssl requires an initial accept to bind() the socket */ if (BIO_do_accept(tlsdata->accept_bio) <= 0) { _openssl_log_error(rc, tlsdata->ssl, "BIO_do__accept"); snmp_log(LOG_ERR, "TLSTCP: Falied to do first accept on the TLS accept BIO\n"); return NULL; } /* create the OpenSSL TLS context */ tlsdata->ssl_context = sslctx_server_setup(TLSv1_method()); t->sock = BIO_get_fd(tlsdata->accept_bio, NULL); t->flags |= NETSNMP_TRANSPORT_FLAG_LISTEN; #else /* NETSNMP_NO_LISTEN_SUPPORT */ return NULL; #endif /* NETSNMP_NO_LISTEN_SUPPORT */ } return t; }
int main(int argc, char *argv[]) { SSL *ssl; SSL_CTX *ctx; BIO *bio, *abio, *cbio; pthread_t t; X509 *peer; int (*callback)(char *, int, int, void *) = &password_callback; SSL_library_init(); SSL_load_error_strings(); ERR_load_BIO_strings(); ERR_load_SSL_strings(); printf("Attempting to create SSL context...\n"); ctx = SSL_CTX_new(SSLv3_server_method()); if(ctx == NULL) { printf("Failed. Aborting.\n"); ERR_print_errors_fp(stdout); return 0; } printf("Loading certificates...\n"); SSL_CTX_set_default_passwd_cb(ctx, callback); //if (SSL_CTX_use_certificate_file(ctx, "./CA/server_cert.pem", SSL_FILETYPE_PEM) != 1) { if (SSL_CTX_use_certificate_chain_file(ctx, "./CAtest/server_cert.pem") != 1) { /* Handle failed load here */ ERR_print_errors_fp(stdout); exit(1); } if (SSL_CTX_use_PrivateKey_file(ctx, "./CAtest/private/server_key.pem", SSL_FILETYPE_PEM) != 1) { /* Handle failed load here */ ERR_print_errors_fp(stdout); exit(1); } if (!SSL_CTX_load_verify_locations(ctx, "./CAtest/cacert.pem", "./CA/")) { /* Handle failed load here */ ERR_print_errors_fp(stdout); exit(1); } SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, verify_callback); SSL_CTX_set_verify_depth(ctx, 5); printf("Attempting to create BIO object...\n"); bio = BIO_new_ssl(ctx, 0); if(bio == NULL) { printf("Failed. Aborting.\n"); ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return 0; } printf("Attempting to set up BIO for SSL...\n"); BIO_get_ssl(bio, &ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); abio = BIO_new_accept("4422"); BIO_set_accept_bios(abio, bio); /* First call to BIO_accept() sets up accept BIO */ if (BIO_do_accept(abio) <= 0) { fprintf(stderr, "Error setting up accept\n"); ERR_print_errors_fp(stderr); exit(0); } do { /* Wait for incoming connection */ if (BIO_do_accept(abio) <= 0) { fprintf(stderr, "Error accepting connection\n"); ERR_print_errors_fp(stderr); exit(0); } fprintf(stderr, "Connection 1 established\n"); /* Retrieve BIO for connection */ cbio = BIO_pop(abio); pthread_create(&t, NULL, handle_connection, cbio); } while (1); SSL_shutdown(ssl); BIO_free_all(bio); BIO_free_all(abio); SSL_CTX_free(ctx); SSL_free(ssl); return 0; }
void *phr_authority_list_loading_main(void *arg) { BIO *bio_acc = NULL; BIO *bio_client = NULL; SSL *ssl_client = NULL; SSL_CTX *ctx = NULL; int err; char *hosts[2]; ctx = setup_server_ctx(ESA_CERTFILE_PATH, ESA_CERTFILE_PASSWD, EMU_ROOT_CA_ONLY_CERT_CERTFILE_PATH); bio_acc = BIO_new_accept(ESA_PHR_AUTHORITY_LIST_LOADING_PORT); if(!bio_acc) int_error("Creating server socket failed"); if(BIO_do_accept(bio_acc) <= 0) int_error("Binding server socket failed"); for(;;) { if(BIO_do_accept(bio_acc) <= 0) int_error("Accepting connection failed"); bio_client = BIO_pop(bio_acc); if(!(ssl_client = SSL_new(ctx))) int_error("Creating SSL context failed"); SSL_set_bio(ssl_client, bio_client, bio_client); if(SSL_accept(ssl_client) <= 0) { fprintf(stderr, "Accepting SSL connection failed\n"); goto ERROR_AT_SSL_LAYER; } hosts[0] = ADMIN_CN; hosts[1] = USER_CN; if((err = post_connection_check(ssl_client, hosts, 2, true, GLOBAL_authority_name)) != X509_V_OK) { fprintf(stderr, "Checking peer certificate failed\n\"%s\"\n", X509_verify_cert_error_string(err)); goto ERROR_AT_SSL_LAYER; } // Serve the PHR authority list if(!load_phr_authority_list(ssl_client)) goto ERROR_AT_SSL_LAYER; ERROR_AT_SSL_LAYER: SSL_cleanup(ssl_client); ssl_client = NULL; ERR_remove_state(0); } SSL_CTX_free(ctx); ctx = NULL; BIO_free(bio_acc); bio_acc = NULL; pthread_exit(NULL); return NULL; }
int main(int argc, char *argv[]) { SSL_library_init(); SSL_load_error_strings(); SSL * new_ssl; SSL_CTX * new_ctx; new_ctx = dh_setup_ctx(); BIO * acc, * client; char port[sizeof(argv[1])] = ""; int check = 0; long port_num; parse_port(argc,argv,port); acc = BIO_new_accept("1300"); port_num = BIO_set_accept_port(acc,port); if ( !acc ) { printf("%s \n", "Error in new bio accept"); return -1; } if ( BIO_do_accept(acc) <= 0) { printf("%s \n", "Error in do accept" ); return -1; } int get = 0; while ( 1 ) { if( BIO_do_accept(acc) <= 0 ) { printf("%s \n", "Error in accepting connections"); return -1; } client = BIO_pop(acc); if ( !(new_ssl = SSL_new(new_ctx))) { printf("%s \n", "Error in creating new SSL"); return -1; } SSL_set_bio(new_ssl,client,client); if( SSL_accept(new_ssl) <= 0 ) { get = SSL_get_error(new_ssl,get); printf("%s \n", "Error in accepting SSL connection"); printf("%d \n", get); printf("%s \n",ERR_error_string(get,NULL)); return -1; } int buf[256] = { 0 }; int count = 0; if ( SSL_read(new_ssl,buf,sizeof(buf)) > 0) { /*get = SSL_get_error(new_ssl,get); printf("%d \n", get); printf("%s \n",ERR_error_string(get,NULL)); */ while( (char)buf[count] != EOF ) { printf("%c" , (char)buf[count]); count++; } } SSL_shutdown(new_ssl); SSL_free(new_ssl); } SSL_CTX_free(new_ctx); BIO_free(acc); return 0; }
void *emergency_delegation_list_loading_main(void *arg) { BIO *bio_acc = NULL; BIO *bio_client = NULL; SSL *ssl_client = NULL; SSL_CTX *ctx = NULL; int err; char *host[1]; ctx = setup_server_ctx(EMS_CERTFILE_PATH, EMS_CERTFILE_PASSWD, PHR_ROOT_CA_ONLY_CERT_CERTFILE_PATH); bio_acc = BIO_new_accept(EMS_EMERGENCY_DELEGATION_LIST_LOADING_PORT); if(!bio_acc) int_error("Creating server socket failed"); if(BIO_do_accept(bio_acc) <= 0) int_error("Binding server socket failed"); for(;;) { if(BIO_do_accept(bio_acc) <= 0) int_error("Accepting connection failed"); bio_client = BIO_pop(bio_acc); if(!(ssl_client = SSL_new(ctx))) int_error("Creating SSL context failed"); SSL_set_bio(ssl_client, bio_client, bio_client); if(SSL_accept(ssl_client) <= 0) { fprintf(stderr, "Accepting SSL connection failed\n"); goto ERROR_AT_SSL_LAYER; } host[0] = USER_CN; if((err = post_connection_check(ssl_client, host, 1, true, GLOBAL_authority_name)) != X509_V_OK) { fprintf(stderr, "Checking peer certificate failed\n\"%s\"\n", X509_verify_cert_error_string(err)); goto ERROR_AT_SSL_LAYER; } // Process types of request if(!process_request(ssl_client)) goto ERROR_AT_SSL_LAYER; ERROR_AT_SSL_LAYER: SSL_cleanup(ssl_client); ssl_client = NULL; ERR_remove_state(0); } SSL_CTX_free(ctx); ctx = NULL; BIO_free(bio_acc); bio_acc = NULL; pthread_exit(NULL); return NULL; }
int main(int argc, char *argv[]) { char *port = NULL; BIO *ssl_bio, *tmp; SSL_CTX *ctx; char buf[512]; int ret = 1, i; if (argc <= 1) port = "*:4433"; else port = argv[1]; signal(SIGINT, close_up); SSL_load_error_strings(); /* Add ciphers and message digests */ OpenSSL_add_ssl_algorithms(); ctx = SSL_CTX_new(TLS_server_method()); if (!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) goto err; if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) goto err; if (!SSL_CTX_check_private_key(ctx)) goto err; /* Setup server side SSL bio */ ssl_bio = BIO_new_ssl(ctx, 0); if ((in = BIO_new_accept(port)) == NULL) goto err; /* * This means that when a new connection is accepted on 'in', The ssl_bio * will be 'duplicated' and have the new socket BIO push into it. * Basically it means the SSL BIO will be automatically setup */ BIO_set_accept_bios(in, ssl_bio); again: /* * The first call will setup the accept socket, and the second will get a * socket. In this loop, the first actual accept will occur in the * BIO_read() function. */ if (BIO_do_accept(in) <= 0) goto err; for (;;) { i = BIO_read(in, buf, 512); if (i == 0) { /* * If we have finished, remove the underlying BIO stack so the * next time we call any function for this BIO, it will attempt * to do an accept */ printf("Done\n"); tmp = BIO_pop(in); BIO_free_all(tmp); goto again; } if (i < 0) goto err; fwrite(buf, 1, i, stdout); fflush(stdout); } ret = 0; err: if (ret) { ERR_print_errors_fp(stderr); } BIO_free(in); exit(ret); return (!ret); }
/****** * 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; }
bool TLS_SOCKET_CLASS::listen() // DESCRIPTION : Setup the listen port. // PRECONDITIONS : // POSTCONDITIONS : // EXCEPTIONS : // NOTES : //<<=========================================================================== { ostringstream listenPort; // make sure the socket is not already in use if (terminatingM) { if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - In process of terminating. Cannot listen."); } // return - in process of termintating return false; } if (connectedM) { if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Already connected to \"%s\". Cannot listen to port %d.", remoteHostnameM.c_str(), localListenPortM); } // return - already connected return false; } else if (listeningM) { if (loggerM_ptr) { loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Socket is already listening to port %d. Cannot listen again.", localListenPortM); } // return - socket is already being used to listen return false; } listeningM = false; if (loggerM_ptr) { loggerM_ptr->text(LOG_DEBUG, 1, "Secure Socket - tls::listen(%d)", localListenPortM); } if (acceptBioM_ptr != NULL) { BIO_free(acceptBioM_ptr); acceptBioM_ptr = NULL; } // create the socket listenPort << localListenPortM; acceptBioM_ptr = BIO_new_accept(const_cast<char *>(listenPort.str().c_str())); if (acceptBioM_ptr == NULL) { openSslError("creating server socket to port %d", localListenPortM); return false; } // bind to the port if (BIO_do_accept(acceptBioM_ptr) <= 0) { openSslError("binding server socket to port %d", localListenPortM); BIO_free(acceptBioM_ptr); acceptBioM_ptr = NULL; return false; } // listen socket set up listeningM = true; // return whether listening or not return listeningM; }