Exemple #1
0
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server)
{
	GIOSSLChannel *chan;
	GIOChannel *gchan;
	int fd;
	SSL *ssl;
	SSL_CTX *ctx = NULL;

	const char *mycert = server->connrec->tls_cert;
	const char *mypkey = server->connrec->tls_pkey;
	const char *mypass = server->connrec->tls_pass;
	const char *cafile = server->connrec->tls_cafile;
	const char *capath = server->connrec->tls_capath;
	const char *ciphers = server->connrec->tls_ciphers;
	gboolean verify = server->connrec->tls_verify;

	g_return_val_if_fail(handle != NULL, NULL);

	if(!ssl_inited && !irssi_ssl_init())
		return NULL;

	if(!(fd = g_io_channel_unix_get_fd(handle)))
		return NULL;

	ERR_clear_error();
	ctx = SSL_CTX_new(SSLv23_client_method());
	if (ctx == NULL) {
		g_error("Could not allocate memory for SSL context");
		return NULL;
	}
	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
	SSL_CTX_set_default_passwd_cb(ctx, get_pem_password_callback);
	SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)mypass);

	if (ciphers != NULL && ciphers[0] != '\0') {
		if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1)
			g_warning("No valid SSL cipher suite could be selected");
	}

	if (mycert && *mycert) {
		char *scert = NULL, *spkey = NULL;
		FILE *fp;
		scert = convert_home(mycert);
		if (mypkey && *mypkey)
			spkey = convert_home(mypkey);

		if ((fp = fopen(scert, "r"))) {
			X509 *cert;
			/* Let's parse the certificate by hand instead of using
			 * SSL_CTX_use_certificate_file so that we can validate
			 * some parts of it. */
			cert = PEM_read_X509(fp, NULL, get_pem_password_callback, (void *)mypass);
			if (cert != NULL) {
				/* Only the expiration date is checked right now */
				if (X509_cmp_current_time(X509_get_notAfter(cert))  <= 0 ||
				    X509_cmp_current_time(X509_get_notBefore(cert)) >= 0)
					g_warning("The client certificate is expired");

				ERR_clear_error();
				if (! SSL_CTX_use_certificate(ctx, cert))
					g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error()));
				else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM))
					g_warning("Loading of private key '%s' failed: %s", mypkey ? mypkey : mycert, ERR_reason_error_string(ERR_get_error()));
				else if (! SSL_CTX_check_private_key(ctx))
					g_warning("Private key does not match the certificate");

				X509_free(cert);
			} else
				g_warning("Loading of client certificate '%s' failed: %s", mycert, ERR_reason_error_string(ERR_get_error()));

			fclose(fp);
		} else
			g_warning("Could not find client certificate '%s'", scert);
		g_free(scert);
		g_free(spkey);
	}

	if ((cafile && *cafile) || (capath && *capath)) {
		char *scafile = NULL;
		char *scapath = NULL;
		if (cafile && *cafile)
			scafile = convert_home(cafile);
		if (capath && *capath)
			scapath = convert_home(capath);
		if (! SSL_CTX_load_verify_locations(ctx, scafile, scapath)) {
			g_warning("Could not load CA list for verifying TLS server certificate");
			g_free(scafile);
			g_free(scapath);
			SSL_CTX_free(ctx);
			return NULL;
		}
		g_free(scafile);
		g_free(scapath);
		verify = TRUE;
	} else if (store != NULL) {
		/* Make sure to increment the refcount every time the store is
		 * used, that's essential not to get it free'd by OpenSSL when
		 * the SSL_CTX is destroyed. */
		X509_STORE_up_ref(store);
		SSL_CTX_set_cert_store(ctx, store);
	}

	if(!(ssl = SSL_new(ctx)))
	{
		g_warning("Failed to allocate SSL structure");
		SSL_CTX_free(ctx);
		return NULL;
	}

	if(!SSL_set_fd(ssl, fd))
	{
		g_warning("Failed to associate socket to SSL stream");
		SSL_free(ssl);
		SSL_CTX_free(ctx);
		return NULL;
	}

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	SSL_set_tlsext_host_name(ssl, server->connrec->address);
#endif

	SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
			SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

	chan = g_new0(GIOSSLChannel, 1);
	chan->fd = fd;
	chan->giochan = handle;
	chan->ssl = ssl;
	chan->ctx = ctx;
	chan->server = server;
	chan->port = port;
	chan->verify = verify;

	gchan = (GIOChannel *)chan;
	gchan->funcs = &irssi_ssl_channel_funcs;
	g_io_channel_init(gchan);
	gchan->is_readable = gchan->is_writeable = TRUE;
	gchan->use_buffer = FALSE;

	return gchan;
}
Exemple #2
0
/*
 * Fetches the resource denoted by |uri|.
 */
static void fetch_uri(const struct URI *uri)
{
  nghttp2_session_callbacks callbacks;
  int fd;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  struct Request req;
  struct Connection connection;
  int rv;
  nfds_t npollfds = 1;
  struct pollfd pollfds[1];

  request_init(&req, uri);

  setup_nghttp2_callbacks(&callbacks);

  /* Establish connection and setup SSL */
  fd = connect_to(req.host, req.port);
  if(fd == -1) {
    die("Could not open file descriptor");
  }
  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  if(ssl_ctx == NULL) {
    dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
  }
  init_ssl_ctx(ssl_ctx);
  ssl = SSL_new(ssl_ctx);
  if(ssl == NULL) {
    dief("SSL_new", ERR_error_string(ERR_get_error(), NULL));
  }
  /* To simplify the program, we perform SSL/TLS handshake in blocking
     I/O. */
  ssl_handshake(ssl, fd);

  connection.ssl = ssl;
  connection.want_io = IO_NONE;

  /* Send connection header in blocking I/O mode */
  SSL_write(ssl, NGHTTP2_CLIENT_CONNECTION_PREFACE,
            NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);

  /* Here make file descriptor non-block */
  make_non_block(fd);
  set_tcp_nodelay(fd);

  printf("[INFO] SSL/TLS handshake completed\n");
  rv = nghttp2_session_client_new(&connection.session, &callbacks,
                                  &connection);
  if(rv != 0) {
    diec("nghttp2_session_client_new", rv);
  }

  /* Submit the HTTP request to the outbound queue. */
  submit_request(&connection, &req);

  pollfds[0].fd = fd;
  ctl_poll(pollfds, &connection);

  /* Event loop */
  while(nghttp2_session_want_read(connection.session) ||
        nghttp2_session_want_write(connection.session)) {
    int nfds = poll(pollfds, npollfds, -1);
    if(nfds == -1) {
      dief("poll", strerror(errno));
    }
    if(pollfds[0].revents & (POLLIN | POLLOUT)) {
      exec_io(&connection);
    }
    if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
      die("Connection error");
    }
    ctl_poll(pollfds, &connection);
  }

  /* Resource cleanup */
  nghttp2_session_del(connection.session);
  SSL_shutdown(ssl);
  SSL_free(ssl);
  SSL_CTX_free(ssl_ctx);
  shutdown(fd, SHUT_WR);
  close(fd);
  request_free(&req);
}
Exemple #3
0
void child_cycle(int channel)
{
    int message = 0;
    int result = 0;
    int local_socket = 0;
    int remote_socket = 0;
    struct sockaddr_in my_addr, peer_addr;
    socklen_t peer_addr_size = 0;

    memset(&my_addr, 0, sizeof(struct sockaddr_in));
    memset(&peer_addr, 0, sizeof(struct sockaddr_in));
    /*
     * Do the TLS initialization dance.
     */
    result = ssl_server_init();
    if (result < 0)
    {
        message = -1;
        result = write(channel, &message, sizeof(int));
        exit(0);
    }
    /*
     * Create a unix socket
     */
    local_socket = socket(AF_INET, SOCK_STREAM, 0);
    my_addr.sin_family = AF_INET;
    my_addr.sin_addr.s_addr = INADDR_ANY;
    my_addr.sin_port = htons(8035);
    /* Avoid spurious failures when rerunning the test due to socket not yet
     * being released. */
    int opt = 1;
    setsockopt(local_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    /*
     * Bind it
     */
    result = bind(local_socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in));
    if (result < 0)
    {
        message = -1;
        result = write(channel, &message, sizeof(int));
        exit(0);
    }
    /*
     * Start listening for connections
     */
    result = listen(local_socket, 5);
    if (result < 0)
    {
        message = -1;
        result = write(channel, &message, sizeof(int));
        exit(0);
    }
    /*
     * Signal the parent that we are ok.
     */
    result = write(channel, &message, sizeof(int));
    /*
     * If this did not work, then we abort.
     */
    if (result < 0)
    {
        exit(0);
    }
    /*
     * Send the name of the public key file.
     */
    result = write(channel, server_name_template_public, strlen(server_name_template_public));
    if (result < 0)
    {
        exit(0);
    }
    /*
     * Send the name of the certificate file.
     */
    result = write(channel, server_certificate_template_public, strlen(server_certificate_template_public));
    if (result < 0)
    {
        exit(0);
    }
    /*
     * Now wait until somebody calls.
     */
    peer_addr_size = sizeof(struct sockaddr_in);
    while (true)
    {
        remote_socket = accept(local_socket, (struct sockaddr *)&peer_addr, &peer_addr_size);
        if (remote_socket < 0)
        {
            Log (LOG_LEVEL_CRIT, "Could not accept connection");
            continue;
        }
        /*
         * We are not testing the server, we are testing the functions to send and receive data
         * over TLS. We do not need a full fletched server for that, we just need to send and
         * receive data and try the error conditions.
         */
        SSL *ssl = SSL_new(SSLSERVERCONTEXT);
        if (!ssl)
        {
            Log(LOG_LEVEL_CRIT, "Could not create SSL structure on the server side");
            SSL_free(ssl);
            close (remote_socket);
            remote_socket = -1;
            continue;
        }
        SSL_set_fd(ssl, remote_socket);
        result = SSL_accept(ssl);
        if (result < 0)
        {
            Log(LOG_LEVEL_CRIT, "Could not accept a TLS connection");
            close (remote_socket);
            remote_socket = -1;
            continue;
        }
        /*
         * Our mission is pretty simple, receive data and send it back.
         */
        int received = 0;
        int sent = 0;
        char buffer[4096];
        do {
            received = SSL_read(ssl, buffer, 4096);
            if (received < 0)
            {
                Log(LOG_LEVEL_CRIT, "Failure while receiving data over TLS");
                break;
            }
            sent = SSL_write(ssl, buffer, received);
            if (sent < 0)
            {
                Log(LOG_LEVEL_CRIT, "Failure while sending data over TLS");
                break;
            }
        } while (received > 0);
        /*
         * Mission completed, start again.
         */
        SSL_shutdown(ssl);
        SSL_free(ssl);
        remote_socket = -1;
    }
    exit(0);
}
Exemple #4
0
static void proceed_handshake(h2o_socket_t *sock, const char *err)
{
    h2o_iovec_t first_input = {};
    int ret;

    sock->_cb.write = NULL;

    if (err != NULL) {
        goto Complete;
    }

    if (sock->ssl->handshake.server.async_resumption.state == ASYNC_RESUMPTION_STATE_RECORD) {
        if (sock->ssl->input.encrypted->size <= 1024) {
            /* retain a copy of input if performing async resumption */
            first_input = h2o_iovec_init(alloca(sock->ssl->input.encrypted->size), sock->ssl->input.encrypted->size);
            memcpy(first_input.base, sock->ssl->input.encrypted->bytes, first_input.len);
        } else {
            sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE;
        }
    }

Redo:
    if (sock->ssl->ssl->server) {
        ret = SSL_accept(sock->ssl->ssl);
    } else {
        ret = SSL_connect(sock->ssl->ssl);
    }

    switch (sock->ssl->handshake.server.async_resumption.state) {
    case ASYNC_RESUMPTION_STATE_RECORD:
        /* async resumption has not been triggered; proceed the state to complete */
        sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE;
        break;
    case ASYNC_RESUMPTION_STATE_REQUEST_SENT: {
        /* sent async request, reset the ssl state, and wait for async response */
        assert(ret < 0);
        SSL_CTX *ssl_ctx = SSL_get_SSL_CTX(sock->ssl->ssl);
        SSL_free(sock->ssl->ssl);
        create_ssl(sock, ssl_ctx);
        clear_output_buffer(sock->ssl);
        h2o_buffer_consume(&sock->ssl->input.encrypted, sock->ssl->input.encrypted->size);
        h2o_buffer_reserve(&sock->ssl->input.encrypted, first_input.len);
        memcpy(sock->ssl->input.encrypted->bytes, first_input.base, first_input.len);
        sock->ssl->input.encrypted->size = first_input.len;
        h2o_socket_read_stop(sock);
        return;
    }
    default:
        break;
    }

    if (ret == 0 || (ret < 0 && SSL_get_error(sock->ssl->ssl, ret) != SSL_ERROR_WANT_READ)) {
        /* failed */
        long verify_result = SSL_get_verify_result(sock->ssl->ssl);
        if (verify_result != X509_V_OK) {
            err = X509_verify_cert_error_string(verify_result);
        } else {
            err = "ssl handshake failure";
        }
        goto Complete;
    }

    if (sock->ssl->output.bufs.size != 0) {
        h2o_socket_read_stop(sock);
        flush_pending_ssl(sock, ret == 1 ? on_handshake_complete : proceed_handshake);
    } else {
        if (ret == 1) {
            if (!sock->ssl->ssl->server) {
                X509 *cert = SSL_get_peer_certificate(sock->ssl->ssl);
                if (cert != NULL) {
                    switch (validate_hostname(sock->ssl->handshake.client.server_name, cert)) {
                    case MatchFound:
                        /* ok */
                        break;
                    case MatchNotFound:
                        err = h2o_socket_error_ssl_cert_name_mismatch;
                        break;
                    default:
                        err = h2o_socket_error_ssl_cert_invalid;
                        break;
                    }
                    X509_free(cert);
                } else {
                    err = h2o_socket_error_ssl_no_cert;
                }
            }
            goto Complete;
        }
        if (sock->ssl->input.encrypted->size != 0)
            goto Redo;
        h2o_socket_read_start(sock, proceed_handshake);
    }
    return;

Complete:
    h2o_socket_read_stop(sock);
    on_handshake_complete(sock, err);
}
Exemple #5
0
LWS_VISIBLE int
lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
{
	struct lws_context *context = wsi->context;
	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
	int n, m;
#if !defined(USE_WOLFSSL) && !defined(LWS_USE_POLARSSL) && !defined(LWS_USE_MBEDTLS)
	BIO *bio;
#endif

	if (!LWS_SSL_ENABLED(wsi->vhost))
		return 0;

	switch (wsi->mode) {
	case LWSCM_SSL_INIT:

		if (wsi->ssl)
			lwsl_err("%s: leaking ssl\n", __func__);
		if (accept_fd == LWS_SOCK_INVALID)
			assert(0);

#if defined(LWS_USE_POLARSSL)
	{
		ssl_session *ssn;
		int rc;

		wsi->ssl = lws_zalloc(sizeof(ssl_context));
		ssn = lws_zalloc(sizeof(ssl_session));

		rc = ssl_init(wsi->ssl);
		if (rc) {
			lwsl_err("ssl_init failed\n");
			goto fail;
		}

		ssl_set_endpoint(wsi->ssl, SSL_IS_SERVER);
		ssl_set_authmode(wsi->ssl, SSL_VERIFY_OPTIONAL);
		ssl_set_rng(wsi->ssl, urandom_bytes, NULL);
		ssl_set_dbg(wsi->ssl, pssl_debug, NULL);
		ssl_set_bio(wsi->ssl, net_recv, &wsi->sock, net_send, &wsi->sock);

		ssl_set_ciphersuites(wsi->ssl, ciphers);

		ssl_set_session(wsi->ssl, ssn);

		ssl_set_ca_chain(wsi->ssl, &wsi->vhost->ssl_ctx->ca,
				 NULL, NULL);

		ssl_set_own_cert_rsa(wsi->ssl,
				&wsi->vhost->ssl_ctx->certificate,
				&wsi->vhost->ssl_ctx->key);

//		ssl_set_dh_param(wsi->ssl, my_dhm_P, my_dhm_G);

		lwsl_err("%s: polarssl init done\n", __func__);
	}
#else
#if defined(LWS_USE_MBEDTLS)
#else
		wsi->ssl = SSL_new(wsi->vhost->ssl_ctx);
		if (wsi->ssl == NULL) {
			lwsl_err("SSL_new failed: %s\n",
				 ERR_error_string(lws_ssl_get_error(wsi, 0), NULL));
			lws_decode_ssl_error();
			if (accept_fd != LWS_SOCK_INVALID)
				compatible_close(accept_fd);
			goto fail;
		}

		SSL_set_ex_data(wsi->ssl,
			openssl_websocket_private_data_index, wsi->vhost);

		SSL_set_fd(wsi->ssl, accept_fd);
#endif
#endif

#ifdef USE_WOLFSSL
#ifdef USE_OLD_CYASSL
		CyaSSL_set_using_nonblock(wsi->ssl, 1);
#else
		wolfSSL_set_using_nonblock(wsi->ssl, 1);
#endif
#else
#if defined(LWS_USE_POLARSSL)

#else
#if defined(LWS_USE_MBEDTLS)
#else
		SSL_set_mode(wsi->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
		bio = SSL_get_rbio(wsi->ssl);
		if (bio)
			BIO_set_nbio(bio, 1); /* nonblocking */
		else
			lwsl_notice("NULL rbio\n");
		bio = SSL_get_wbio(wsi->ssl);
		if (bio)
			BIO_set_nbio(bio, 1); /* nonblocking */
		else
			lwsl_notice("NULL rbio\n");
#endif
#endif
#endif

		/*
		 * we are not accepted yet, but we need to enter ourselves
		 * as a live connection.  That way we can retry when more
		 * pieces come if we're not sorted yet
		 */

		wsi->mode = LWSCM_SSL_ACK_PENDING;
		if (insert_wsi_socket_into_fds(context, wsi)) {
			lwsl_err("%s: failed to insert into fds\n", __func__);
			goto fail;
		}

		lws_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT,
				context->timeout_secs);

		lwsl_info("inserted SSL accept into fds, trying SSL_accept\n");

		/* fallthru */

	case LWSCM_SSL_ACK_PENDING:

		if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
			lwsl_err("%s: lws_change_pollfd failed\n", __func__);
			goto fail;
		}

		lws_latency_pre(context, wsi);

		n = recv(wsi->sock, (char *)pt->serv_buf, context->pt_serv_buf_size,
			 MSG_PEEK);

		/*
		 * optionally allow non-SSL connect on SSL listening socket
		 * This is disabled by default, if enabled it goes around any
		 * SSL-level access control (eg, client-side certs) so leave
		 * it disabled unless you know it's not a problem for you
		 */

		if (wsi->vhost->allow_non_ssl_on_ssl_port) {
			if (n >= 1 && pt->serv_buf[0] >= ' ') {
				/*
				* TLS content-type for Handshake is 0x16, and
				* for ChangeCipherSpec Record, it's 0x14
				*
				* A non-ssl session will start with the HTTP
				* method in ASCII.  If we see it's not a legit
				* SSL handshake kill the SSL for this
				* connection and try to handle as a HTTP
				* connection upgrade directly.
				*/
				wsi->use_ssl = 0;
#if defined(LWS_USE_POLARSSL)
				ssl_close_notify(wsi->ssl);
				ssl_free(wsi->ssl);
#else
#if defined(LWS_USE_MBEDTLS)
#else
				SSL_shutdown(wsi->ssl);
				SSL_free(wsi->ssl);
#endif
#endif
				wsi->ssl = NULL;
				if (lws_check_opt(context->options,
				    LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS))
					wsi->redirect_to_https = 1;
				goto accepted;
			}
			if (!n) /*
				 * connection is gone, or nothing to read
				 * if it's gone, we will timeout on
				 * PENDING_TIMEOUT_SSL_ACCEPT
				 */
				break;
			if (n < 0 && (LWS_ERRNO == LWS_EAGAIN ||
				      LWS_ERRNO == LWS_EWOULDBLOCK)) {
				/*
				 * well, we get no way to know ssl or not
				 * so go around again waiting for something
				 * to come and give us a hint, or timeout the
				 * connection.
				 */
				m = SSL_ERROR_WANT_READ;
				goto go_again;
			}
		}

		/* normal SSL connection processing path */
#if defined(LWS_USE_POLARSSL)
		n = ssl_handshake(wsi->ssl);
#else
#if defined(LWS_USE_MBEDTLS)
#else
		n = SSL_accept(wsi->ssl);
#endif
#endif
		lws_latency(context, wsi,
			"SSL_accept LWSCM_SSL_ACK_PENDING\n", n, n == 1);

		if (n == 1)
			goto accepted;

		m = lws_ssl_get_error(wsi, n);
		lwsl_debug("SSL_accept failed %d / %s\n",
			   m, ERR_error_string(m, NULL));
go_again:
		if (m == SSL_ERROR_WANT_READ) {
			if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
				lwsl_err("%s: WANT_READ change_pollfd failed\n", __func__);
				goto fail;
			}

			lwsl_info("SSL_ERROR_WANT_READ\n");
			break;
		}
		if (m == SSL_ERROR_WANT_WRITE) {
			if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) {
				lwsl_err("%s: WANT_WRITE change_pollfd failed\n", __func__);
				goto fail;
			}

			break;
		}
		lwsl_err("SSL_accept failed skt %u: %s\n",
			   wsi->sock, ERR_error_string(m, NULL));

		lws_ssl_elaborate_error();
		goto fail;

accepted:
		/* OK, we are accepted... give him some time to negotiate */
		lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
				context->timeout_secs);

		wsi->mode = LWSCM_HTTP_SERVING;

		lws_http2_configure_if_upgraded(wsi);

		lwsl_debug("accepted new SSL conn\n");
		break;
	}

	return 0;

fail:
	return 1;
}
Exemple #6
0
int
main(int argc, char *argv[])
{
	
	int client_sock = -1;
	int client_name_len = sizeof (client_name);
	int request=0;
	
	struct nunetwork_headerstruct *header_buf;
	header_buf = (struct nunetwork_headerstruct*)malloc( sizeof(*header_buf) );
	/********************
         * Don't forget to make pointer to variable cast (*pointer)
         * When using sizeof(). Otherwise it may cost you a week of
	 * debug time.
         *******************/
	

	if (geteuid()) {
		printf("Netustad must be run as root.\n");
		exit(1);
	}
	
	conffile	= (char *)strdup(default_conf_file);
	
	
	/*setlocale (LC_ALL, "");*/
	bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
	textdomain ( PACKAGE );
	

	/*******************/
	/* Check Arguments */
	/*******************/
	if (argc==2) {	
			
			if (strcmp(argv[1], "-h") == 0 ||
				strcmp(argv[1], "--help") == 0) {
				printf( gettext("\nnetUstad: Network Ustadi (Network Master)\n"));
				printf( gettext("Copyright (C) 2004   by Ozkan KIRIK\n"));
				printf( gettext("Usage: netustad [options]\n"));
				printf( gettext("\n"));
				printf( "%s:\n", gettext("Options"));
				printf( gettext("\t-h\tShow this help screen\n"));
				printf( gettext("\t-v\tShow version\n"));
				printf
					(gettext("\t-c\tUse following parameter as configuration file"));
				printf("\n");
				exit(0);
			} else if (strcmp(argv[1], "-v") == 0 ||
				   strcmp(argv[1], "--version") == 0) {
				printf(gettext("\nnetUstad: Network Ustadi (Network Master)\n"));
				printf(gettext("Copyright (C) 2004  by Ozkan KIRIK\n\n"));
				printf(gettext("Version: %s\n\n"), NUVERSION);
				exit(0);
			}
				
	} else if (argc == 3 && strcmp(argv[1], "-c") == 0) {
			conffile = strdup(argv[2]);

	}  else if (argc!=1) {
			if (strcmp(argv[1], "-c") == 0) {
				printf (gettext("\nnetUstad: Invalid Number Of Arguments\n\n"));
			} else {
				printf(gettext("\nnetUstad: Invalid Argument\n\n"));
			}
			exit(1);

	}


	/**********************/
	/* Start Main Program */
	/**********************/

	readconfig(conffile);
	if (setlocale (LC_ALL, (const char*) lc_all) == NULL) {
		log_msg(mainlogfile, gettext("setlocale failed\n"), 1);
		printf(gettext("setlocale failed\n"));
	}
	bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
	textdomain ( PACKAGE );
	nameoftty = ttyname(0);
	daemonize();

	#ifndef WITHOUT_SSL
        	ssl = nunetwork_init_ssl( nunetwork_init_ctx( cert_file, key_file) );
	#endif

	server_sock = startup(&port);	/* Open Socket & Listen */

	log_msg(mainlogfile, "<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n", 0);
	snprintf(log_msg_text, sizeof(log_msg_text)-1, "netUstad-%s\n", NUVERSION);
        log_msg(mainlogfile, log_msg_text, 0);
	snprintf(log_msg_text, sizeof (log_msg_text)-1, "%s",
		 gettext("netUstad is started\n"));
	log_msg(mainlogfile, log_msg_text, 1);
	snprintf(log_msg_text, sizeof (log_msg_text)-1, gettext("\nListening port %d\n"), port);
	log_msg(mainlogfile, log_msg_text, 0);
	log_msg(mainlogfile, gettext("Ready for requests...\n\n"), 0);
	snprintf(log_msg_text, sizeof(log_msg_text)-1, "netUstad-%s\n", NUVERSION);
	log_msg(nameoftty, log_msg_text, 0);
	snprintf(log_msg_text, sizeof (log_msg_text)-1,
		 gettext("\nnetUstad is started\nListening port %d\n"), port);
	log_msg(nameoftty, log_msg_text, 0);

	while (1) {
		client_sock = accept(server_sock,
				     (struct sockaddr *) &client_name,
				     (socklen_t *)&client_name_len);

		if (client_sock == -1)
			continue;
	
		 #ifndef WITHOUT_SSL
		        SSL_set_fd(ssl, client_sock);
		        sslerror = SSL_accept(ssl);
		
		        if ( sslerror <= 0 ) {
		                sslerror= SSL_get_error(ssl, sslerror);
		                ERR_error_string(sslerror, log_msg_text);
		
		                log_msg(mainlogfile, log_msg_text, 1);
				log_msg(mainlogfile, "\n",0);
				SSL_shutdown(ssl);
				SSL_free(ssl);
				close(client_sock);
				ssl = nunetwork_init_ssl(ctx);
				continue;
		        }
			
			request =  nunetwork_getheaders(ssl, header_buf, nu_acceptedheaders); 
			if (request > 0) 
				accept_request(ssl, header_buf);
			else if (request==-2 || request==0)
				bad_request(ssl);
			nunetwork_close(ssl);
		 #else
			request = nunetwork_getheaders(client_sock, header_buf, nu_acceptedheaders);
		        if (request > 0)
				accept_request(client_sock, header_buf);
			else if (request==-2 || request==0 )
				bad_request(ssl);
		 	nunetwork_close(client_sock);
		 #endif
		
	
	
	}
	#ifndef WITHOUT_SSL
		SSL_shutdown(ssl);
		SSL_free(ssl);
		SSL_CTX_free(ctx);
	#else
		close(server_sock);
	#endif


	return (0);
}
void DataPlaneServer::readyRead(int) {
    memset(&client_addr, 0, sizeof(struct sockaddr_storage));

    /* Create BIO */
    bio = BIO_new_dgram(fd, BIO_NOCLOSE);

    /* Set and activate timeouts */
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);

    ssl = SSL_new(ctx);

    SSL_set_bio(ssl, bio, bio);
    SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);

    int dtlsRet;
    errno = 0;
    while ((dtlsRet = DTLSv1_listen(ssl, &client_addr)) <= 0) {
        if (errno != EAGAIN) {
            qWarning() << "DTLSv1_listen error";
            qWarning() << SSL_get_error(ssl, dtlsRet);
            qWarning() << "Errno is" << errno;
            if (errno == EINVAL) {
                qWarning() << "!!!!!!!!!!! Your openssl library does not support DTLSv1_listen !!!!!!!!!!!";
                qWarning() << "Cannot accept new connection";
                SSL_shutdown(ssl);
                close(fd);
                SSL_free(ssl);
                ERR_remove_state(0);
                return;
            }
        }
    }

    QThread* workerThread = new QThread();
    threads.append(workerThread);

    addrUnion infServer_addr;
    addrUnion infClient_addr;
    memcpy(&infServer_addr, &server_addr, sizeof(struct sockaddr_storage));
    memcpy(&infClient_addr, &client_addr, sizeof(struct sockaddr_storage));

    // get UID from friend using his IP to create worker thread
    // if IP is not in DB we close the connection
    char friendIp[INET6_ADDRSTRLEN];
    inet_ntop(AF_INET6, &infClient_addr.s6.sin6_addr, friendIp, INET6_ADDRSTRLEN);

    ConnectionInitiator* init = ConnectionInitiator::getInstance();

    QString friendUid = qSql->getUidFromIP(QHostAddress(QString(friendIp)));
    ControlPlaneConnection* cp = init->getConnection(friendUid);
    if (friendUid.isEmpty() || cp->getMode() == Closed) {
        qDebug() << "friendUId NOT in DB or no control plane connection!";
        SSL_shutdown(ssl);

        close(fd);
        //free(info);
        SSL_free(ssl);
        ERR_remove_state(0);
        qDebug("done, connection closed.");
        fflush(stdout);
        return;
    }
    // associate with dataplaneconnection
    DataPlaneConnection* dpc = init->getDpConnection(friendUid);

    ServerWorker* worker = new ServerWorker(infServer_addr, infClient_addr, ssl, dpc);
    worker->moveToThread(workerThread);
    connect(workerThread, SIGNAL(started()), worker, SLOT(connection_handle()));
    connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
    //connect(worker, SIGNAL(bufferReady(const char*, int)), dpc, SLOT(readBuffer(const char*, int)));
    UnixSignalHandler* u = UnixSignalHandler::getInstance();
    connect(u, SIGNAL(exiting()), workerThread, SLOT(quit()));
    workerThread->start();
}
Exemple #8
0
/* The program expects at most four arguments: host in IP format, port
 * number to connect to, proxy in IP format and proxy port number.
 * If last two are specified, host can be in any format proxy will
 * understand (since this is an example for SSL programming, host name
 * resolving code is left out).
 *
 * Default values are "127.0.0.1", 443. If any proxy parameter is
 * omitted, the program will connect directly to the host.
 */
int main(int argc, char *argv[])
{
	char buffer[4096]; /* This should be dynamically allocated */
	const char *request = "GET / HTTP/1.0\r\n\r\n";
	BOOL is_ok = FALSE;
	X509 *server_cert;
	SSL_CTX *ctx;
	BIO *bio_err;
	SSL *ssl;

	if (Init())
	{
		/* Basic intialization. Next few steps (up to SSL_new()) need
		 * to be done only once per AmiSSL opener.
		 */
		SSLeay_add_ssl_algorithms();
		SSL_load_error_strings();

		/* Note: BIO writing routines are prepared for NULL BIO handle */
		if((bio_err = BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp_amiga(bio_err, GetStdErr(), BIO_NOCLOSE | BIO_FP_TEXT);

		/* Get a new SSL context */
		if((ctx = SSL_CTX_new(SSLv23_client_method())) != NULL)
		{
			/* Basic certificate handling. OpenSSL documentation has more
			 * information on this.
			 */
			SSL_CTX_set_default_verify_paths(ctx);
			SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
			                   NULL);

			/* The following needs to be done once per socket */
			if((ssl = SSL_new(ctx)) != NULL)
			{
				int sock;

				/* Connect to the HTTPS server, directly or through a proxy */
				if (argc > 4)
					sock = ConnectToServer(argv[1], atol(argv[2]), argv[3],
					                       atol(argv[4]));
				else
					sock = ConnectToServer(argv[1] ? argv[1] : (char *)"127.0.0.1",
					                       argc > 2 ? atol(argv[2]) : 443,
					                       NULL, 0);

				/* Check if connection was established */
				if (sock >= 0)
				{
					int ssl_err = 0;

					/* Associate the socket with the ssl structure */
					SSL_set_fd(ssl, sock);

					/* Perform SSL handshake */
					if((ssl_err = SSL_connect(ssl)) >= 0)
					{
						Printf("SSL connection using %s\n", SSL_get_cipher(ssl));

						/* Certificate checking. This example is *very* basic */
						if((server_cert = SSL_get_peer_certificate(ssl)))
						{
							char *str;

							Printf("Server certificate:\n");

							if((str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0)))
							{
								Printf("\tSubject: %s\n", str);
								OPENSSL_free(str);
							}
							else
								FPrintf(GetStdErr(), "Warning: couldn't read subject name in certificate!\n");

							if((str = X509_NAME_oneline(X509_get_issuer_name(server_cert),
							                            0, 0)) != NULL)
							{
								Printf("\tIssuer: %s\n", str);
								OPENSSL_free(str);
							}
							else
								FPrintf(GetStdErr(), "Warning: couldn't read issuer name in certificate!\n");

							X509_free(server_cert);

							/* Send a HTTP request. Again, this is just
							 * a very basic example.
							 */
							if ((ssl_err = SSL_write(ssl, request, strlen(request)))
							    > 0)
							{
								/* Dump everything to output */
								while ((ssl_err = SSL_read(ssl, buffer,
								                           sizeof(buffer) - 1))
								       > 0)
									FWrite(Output(), buffer, ssl_err, 1);

								FFlush(Output());

								/* This is not entirely true, check
								 * the SSL_read documentation
								 */
								is_ok = ssl_err == 0;
							}
							else
								FPrintf(GetStdErr(), "Couldn't write request!\n");
						}
						else
							FPrintf(GetStdErr(), "Couldn't get server certificate!\n");
					}
					else
						FPrintf(GetStdErr(), "Couldn't establish SSL connection!\n");

					/* If there were errors, print them */
					if (ssl_err < 0)
						ERR_print_errors(bio_err);

					/* Send SSL close notification and close the socket */
					SSL_shutdown(ssl);
					CloseSocket(sock);
				}
				else
					FPrintf(GetStdErr(), "Couldn't connect to host!\n");

        
			  FPrintf(GetStdErr(), "before SSL_free()\n");
				SSL_free(ssl);
			}
			else
				FPrintf(GetStdErr(), "Couldn't create new SSL handle!\n");

			FPrintf(GetStdErr(), "before SSL_CTX_free()\n");
			SSL_CTX_free(ctx);
		}
		else
			FPrintf(GetStdErr(), "Couldn't create new context!\n");

	  FPrintf(GetStdErr(), "before Cleanup()\n");
		Cleanup();
	}

	FPrintf(GetStdErr(), "before end of main()\n");
	return(is_ok ? RETURN_OK : RETURN_ERROR);
}
Exemple #9
0
LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection)
{
	if (!connection || connection->ssl_data)
		return IDEVICE_E_INVALID_ARG;

	idevice_error_t ret = IDEVICE_E_SSL_ERROR;
	uint32_t return_me = 0;
	plist_t pair_record = NULL;

	userpref_read_pair_record(connection->udid, &pair_record);
	if (!pair_record) {
		debug_info("ERROR: Failed enabling SSL. Unable to read pair record for udid %s.", connection->udid);
		return ret;
	}

#ifdef HAVE_OPENSSL
	key_data_t root_cert = { NULL, 0 };
	key_data_t root_privkey = { NULL, 0 };

	pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert);
	pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_privkey);

	if (pair_record)
		plist_free(pair_record);

	BIO *ssl_bio = BIO_new(BIO_s_socket());
	if (!ssl_bio) {
		debug_info("ERROR: Could not create SSL bio.");
		return ret;
	}
	BIO_set_fd(ssl_bio, (int)(long)connection->data, BIO_NOCLOSE);

	SSL_CTX *ssl_ctx = SSL_CTX_new(TLSv1_method());
	if (ssl_ctx == NULL) {
		debug_info("ERROR: Could not create SSL context.");
		BIO_free(ssl_bio);
		return ret;
	}

	BIO* membp;
	X509* rootCert = NULL;
	membp = BIO_new_mem_buf(root_cert.data, root_cert.size);
	PEM_read_bio_X509(membp, &rootCert, NULL, NULL);
	BIO_free(membp);
	if (SSL_CTX_use_certificate(ssl_ctx, rootCert) != 1) {
		debug_info("WARNING: Could not load RootCertificate");
	}
	X509_free(rootCert);
	free(root_cert.data);

	RSA* rootPrivKey = NULL;
	membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size);
	PEM_read_bio_RSAPrivateKey(membp, &rootPrivKey, NULL, NULL);
	BIO_free(membp);
	if (SSL_CTX_use_RSAPrivateKey(ssl_ctx, rootPrivKey) != 1) {
		debug_info("WARNING: Could not load RootPrivateKey");
	}
	RSA_free(rootPrivKey);
	free(root_privkey.data);

	SSL *ssl = SSL_new(ssl_ctx);
	if (!ssl) {
		debug_info("ERROR: Could not create SSL object");
		BIO_free(ssl_bio);
		SSL_CTX_free(ssl_ctx);
		return ret;
	}
	SSL_set_connect_state(ssl);
	SSL_set_verify(ssl, 0, ssl_verify_callback);
	SSL_set_bio(ssl, ssl_bio, ssl_bio);

	return_me = SSL_do_handshake(ssl);
	if (return_me != 1) {
		debug_info("ERROR in SSL_do_handshake: %s", ssl_error_to_string(SSL_get_error(ssl, return_me)));
		SSL_free(ssl);
		SSL_CTX_free(ssl_ctx);
	} else {
		ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private));
		ssl_data_loc->session = ssl;
		ssl_data_loc->ctx = ssl_ctx;
		connection->ssl_data = ssl_data_loc;
		ret = IDEVICE_E_SUCCESS;
		debug_info("SSL mode enabled, cipher: %s", SSL_get_cipher(ssl));
	}
	/* required for proper multi-thread clean up to prevent leaks */
#ifdef HAVE_ERR_REMOVE_THREAD_STATE
	ERR_remove_thread_state(NULL);
#else
	ERR_remove_state(0);
#endif
#else
	ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private));

	/* Set up GnuTLS... */
	debug_info("enabling SSL mode");
	errno = 0;
	gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate);
#if GNUTLS_VERSION_NUMBER >= 0x020b07
	gnutls_certificate_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback);
#else
	gnutls_certificate_client_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback);
#endif
	gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT);
	gnutls_priority_set_direct(ssl_data_loc->session, "NONE:+VERS-TLS1.0:+ANON-DH:+RSA:+AES-128-CBC:+AES-256-CBC:+SHA1:+MD5:+COMP-NULL", NULL);
	gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate);
	gnutls_session_set_ptr(ssl_data_loc->session, ssl_data_loc);

	gnutls_x509_crt_init(&ssl_data_loc->root_cert);
	gnutls_x509_crt_init(&ssl_data_loc->host_cert);
	gnutls_x509_privkey_init(&ssl_data_loc->root_privkey);
	gnutls_x509_privkey_init(&ssl_data_loc->host_privkey);

	pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, ssl_data_loc->root_cert);
	pair_record_import_crt_with_name(pair_record, USERPREF_HOST_CERTIFICATE_KEY, ssl_data_loc->host_cert);
	pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, ssl_data_loc->root_privkey);
	pair_record_import_key_with_name(pair_record, USERPREF_HOST_PRIVATE_KEY_KEY, ssl_data_loc->host_privkey);

	if (pair_record)
		plist_free(pair_record);

	debug_info("GnuTLS step 1...");
	gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection);
	debug_info("GnuTLS step 2...");
	gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write);
	debug_info("GnuTLS step 3...");
	gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read);
	debug_info("GnuTLS step 4 -- now handshaking...");
	if (errno) {
		debug_info("WARNING: errno says %s before handshake!", strerror(errno));
	}
	return_me = gnutls_handshake(ssl_data_loc->session);
	debug_info("GnuTLS handshake done...");

	if (return_me != GNUTLS_E_SUCCESS) {
		internal_ssl_cleanup(ssl_data_loc);
		free(ssl_data_loc);
		debug_info("GnuTLS reported something wrong.");
		gnutls_perror(return_me);
		debug_info("oh.. errno says %s", strerror(errno));
	} else {
		connection->ssl_data = ssl_data_loc;
		ret = IDEVICE_E_SUCCESS;
		debug_info("SSL mode enabled");
	}
#endif
	return ret;
}
Exemple #10
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = WOLFSSL_SOCKET_INVALID;
    SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;

    wolfSSL_method_func method = NULL;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

#ifndef WOLFSSL_ALT_TEST_STRINGS
    const char msg[] = "I hear you fa shizzle!";
#else
    const char msg[] = "I hear you fa shizzle!\n";
#endif
    char   input[80];
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    word16 port = wolfSSLPort;
    int    usePsk = 0;
    int    usePskPlus = 0;
    int    useAnon = 0;
    int    doDTLS = 0;
    int    needDH = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    int    pkCallbacks  = 0;
    int    wc_shutdown     = 0;
    int    resume = 0;
    int    resumeCount = 0;
    int    loopIndefinitely = 0;
    int    echoData = 0;
    int    throughput = 0;
    int    minDhKeyBits  = DEFAULT_MIN_DHKEY_BITS;
    short  minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS;
    short  minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS;
    int    doListen = 1;
    int    crlFlags = 0;
    int    ret;
    int    err = 0;
    char*  serverReadyFile = NULL;
    char*  alpnList = NULL;
    unsigned char alpn_opt = 0;
    char*  cipherList = NULL;
    const char* verifyCert = cliCert;
    const char* ourCert    = svrCert;
    const char* ourKey     = svrKey;
    const char* ourDhParam = dhParam;
    tcp_ready*  readySignal = NULL;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef WOLFSSL_TRUST_PEER_CERT
    const char* trustCert  = NULL;
#endif

#ifndef NO_PSK
    int sendPskIdentityHint = 1;
#endif

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

#ifdef HAVE_WNR
    const char* wnrConfigFile = wnrConfig;
#endif

#ifdef WOLFSSL_STATIC_MEMORY
    #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \
        || defined(SESSION_CERTS)
        /* big enough to handle most cases including session certs */
        byte memory[204000];
    #else
        byte memory[80000];
    #endif
    byte memoryIO[34500]; /* max of 17k for IO buffer (TLS packet can be 16k) */
    WOLFSSL_MEM_CONN_STATS ssl_stats;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)pkCallbacks;
    (void)needDH;
    (void)ourKey;
    (void)ourCert;
    (void)ourDhParam;
    (void)verifyCert;
    (void)useNtruKey;
    (void)doCliCertCheck;
    (void)minDhKeyBits;
    (void)minRsaKeyBits;
    (void)minEccKeyBits;
    (void)alpnList;
    (void)alpn_opt;
    (void)crlFlags;
    (void)readySignal;

#ifdef CYASSL_TIRTOS
    fdOpenSession(Task_self());
#endif

#ifdef WOLFSSL_VXWORKS
    useAnyAddr = 1;
#else
    while ((ch = mygetopt(argc, argv,
                  "?jdbstnNufrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 'j' :
                usePskPlus = 1;
                break;

            case 't' :
            #ifdef USE_WOLFSSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'R' :
                serverReadyFile = myoptarg;
                break;

            case 'r' :
                #ifndef NO_SESSION_CACHE
                    resume = 1;
                #endif
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS
                pkCallbacks = 1;
            #endif
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                break;

            case 'w' :
                wc_shutdown = 1;
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'D' :
                #ifndef NO_DH
                    ourDhParam = myoptarg;
                #endif
                break;

            case 'Z' :
                #ifndef NO_DH
                    minDhKeyBits = atoi(myoptarg);
                    if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;
            case 'I':
                #ifndef NO_PSK
                    sendPskIdentityHint = 0;
                #endif
                break;

            case 'L' :
                #ifdef HAVE_ALPN
                    alpnList = myoptarg;

                    if (alpnList[0] == 'C' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
                    else if (alpnList[0] == 'F' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
                    else {
                        Usage();
                        exit(MY_EX_USAGE);
                    }

                    alpnList += 2;

                #endif
                break;

            case 'i' :
                loopIndefinitely = 1;
                break;

            case 'e' :
                echoData = 1;
                break;

            case 'B':
                throughput = atoi(myoptarg);
                if (throughput <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            #ifdef WOLFSSL_TRUST_PEER_CERT
            case 'E' :
                 trustCert = myoptarg;
                break;
            #endif

            case 'q' :
                #ifdef HAVE_WNR
                    wnrConfigFile = myoptarg;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */
#endif /* !WOLFSSL_VXWORKS */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#if defined(USE_CYASSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
    if (trackMemory)
        InitMemoryTracker();
#endif

#ifdef HAVE_WNR
    if (wc_InitNetRandom(wnrConfigFile, NULL, 5000) != 0)
        err_sys("can't load whitewood net random config file");
#endif

    switch (version) {
#ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_SSLV3
        case 0:
            method = wolfSSLv3_server_method_ex;
            break;
    #endif

    #ifndef NO_TLS
        case 1:
            method = wolfTLSv1_server_method_ex;
            break;


        case 2:
            method = wolfTLSv1_1_server_method_ex;
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = wolfTLSv1_2_server_method_ex;
            break;
#endif

#ifdef CYASSL_DTLS
    #ifndef NO_OLD_TLS
        case -1:
            method = wolfDTLSv1_server_method_ex;
            break;
    #endif

        case -2:
            method = wolfDTLSv1_2_server_method_ex;
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

#ifdef WOLFSSL_STATIC_MEMORY
    #ifdef DEBUG_WOLFSSL
    /* print off helper buffer sizes for use with static memory
     * printing to stderr incase of debug mode turned on */
    fprintf(stderr, "static memory management size = %d\n",
            wolfSSL_MemoryPaddingSz());
    fprintf(stderr, "calculated optimum general buffer size = %d\n",
            wolfSSL_StaticBufferSz(memory, sizeof(memory), 0));
    fprintf(stderr, "calculated optimum IO buffer size      = %d\n",
            wolfSSL_StaticBufferSz(memoryIO, sizeof(memoryIO),
                                                  WOLFMEM_IO_POOL_FIXED));
    #endif /* DEBUG_WOLFSSL */

    if (wolfSSL_CTX_load_static_memory(&ctx, method, memory, sizeof(memory),0,1)
            != SSL_SUCCESS)
        err_sys("unable to load static memory and create ctx");

    /* load in a buffer for IO */
    if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO, sizeof(memoryIO),
                                 WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1)
            != SSL_SUCCESS)
        err_sys("unable to load static memory and create ctx");
#else
    ctx = SSL_CTX_new(method(NULL));
#endif
    if (ctx == NULL)
        err_sys("unable to get ctx");

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    if (TicketInit() != 0)
        err_sys("unable to setup Session Ticket Key context");
    wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
#endif

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    if (!usePsk) {
        usePsk = 1;
    }
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    if (!usePsk) {
        usePsk = 1;
    }
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if ((!usePsk || usePskPlus) && !useAnon) {
        if (SSL_CTX_use_certificate_chain_file(ctx, ourCert)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " wolfSSL home dir");
    }
#endif

#ifndef NO_DH
    if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits) != SSL_SUCCESS) {
        err_sys("Error setting minimum DH key size");
    }
#endif
#ifndef NO_RSA
    if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != SSL_SUCCESS){
        err_sys("Error setting minimum RSA key size");
    }
#endif
#ifdef HAVE_ECC
    if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != SSL_SUCCESS){
        err_sys("Error setting minimum ECC key size");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from wolfSSL home dir");
    }
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server private key file, check file and run "
                "from wolfSSL home dir");
    }
#endif

    if (usePsk || usePskPlus) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);

        if (sendPskIdentityHint == 1)
            SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");

        if (cipherList == NULL && !usePskPlus) {
            const char *defaultCipherList;
            #if defined(HAVE_AESGCM) && !defined(NO_DH)
                defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
                needDH = 1;
            #elif defined(HAVE_NULL_CIPHER)
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

    if (useAnon) {
#ifdef HAVE_ANON
        CyaSSL_CTX_allow_anon_cipher(ctx);
        if (cipherList == NULL) {
            if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("server can't set cipher list 4");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs
       if using PSK Plus then verify peer certs except PSK suites */
    if (doCliCertCheck && (usePsk == 0 || usePskPlus) && useAnon == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                ((usePskPlus)? SSL_VERIFY_FAIL_EXCEPT_PSK :
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT),0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        #ifdef WOLFSSL_TRUST_PEER_CERT
        if (trustCert) {
            if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert,
                                            SSL_FILETYPE_PEM)) != SSL_SUCCESS) {
                err_sys("can't load trusted peer cert file");
            }
        }
        #endif /* WOLFSSL_TRUST_PEER_CERT */
   }
#endif

#if defined(CYASSL_SNIFFER)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES128-SHA") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif

#ifdef USE_WINDOWS_API
    if (port == 0) {
        /* Generate random port for testing */
        port = GetRandomPort();
    }
#endif /* USE_WINDOWS_API */

    while (1) {
        /* allow resume option */
        if(resumeCount > 1) {
            if (doDTLS == 0) {
                SOCKADDR_IN_T client;
                socklen_t client_len = sizeof(client);
                clientfd = accept(sockfd, (struct sockaddr*)&client,
                                 (ACCEPT_THIRD_T)&client_len);
            } else {
                tcp_listen(&sockfd, &port, useAnyAddr, doDTLS);
                clientfd = sockfd;
            }
            if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) {
                err_sys("tcp accept failed");
            }
        }
#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
    {
        WOLFSSL_MEM_STATS mem_stats;
        fprintf(stderr, "Before creating SSL\n");
        if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1)
            err_sys("ctx not using static memory");
        if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */
            err_sys("error printing out memory stats");
    }
#endif

        ssl = SSL_new(ctx);
        if (ssl == NULL)
            err_sys("unable to get SSL");

#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
    {
        WOLFSSL_MEM_STATS mem_stats;
        fprintf(stderr, "After creating SSL\n");
        if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1)
            err_sys("ctx not using static memory");
        if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */
            err_sys("error printing out memory stats");
    }
#endif

#ifndef NO_HANDSHAKE_DONE_CB
        wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL);
#endif
#ifdef HAVE_CRL
#ifdef HAVE_CRL_MONITOR
        crlFlags = CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON;
#endif
        if (CyaSSL_EnableCRL(ssl, 0) != SSL_SUCCESS)
            err_sys("unable to enable CRL");
        if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, crlFlags)
                                                                 != SSL_SUCCESS)
            err_sys("unable to load CRL");
        if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
            err_sys("unable to set CRL callback url");
#endif
#ifdef HAVE_OCSP
        if (useOcsp) {
            if (ocspUrl != NULL) {
                CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                        | CYASSL_OCSP_URL_OVERRIDE);
            }
            else
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
        }
#endif
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
        if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS)
            err_sys("can't enable OCSP Stapling Certificate Manager");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate1-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate2-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate3-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
#endif
#ifdef HAVE_PK_CALLBACKS
        if (pkCallbacks)
            SetupPkCallbacks(ctx, ssl);
#endif

        /* do accept */
        readySignal = ((func_args*)args)->signal;
        if (readySignal) {
            readySignal->srfName = serverReadyFile;
        }
        tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr,
                       doDTLS, serverReadyFile ? 1 : 0, doListen);
        doListen = 0; /* Don't listen next time */

        if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) {
            err_sys("error in setting fd");
        }

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            printf("ALPN accepted protocols list : %s\n", alpnList);
            wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
        }
#endif

#ifdef WOLFSSL_DTLS
        if (doDTLS) {
            SOCKADDR_IN_T cliaddr;
            byte          b[1500];
            int           n;
            socklen_t     len = sizeof(cliaddr);

            /* For DTLS, peek at the next datagram so we can get the client's
             * address and set it into the ssl object later to generate the
             * cookie. */
            n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
                              (struct sockaddr*)&cliaddr, &len);
            if (n <= 0)
                err_sys("recvfrom failed");

            wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
        }
#endif
        if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
                                                               || needDH == 1) {
            #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN)
                CyaSSL_SetTmpDH_file(ssl, ourDhParam, SSL_FILETYPE_PEM);
            #elif !defined(NO_DH)
                SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
            #endif
        }

#ifndef CYASSL_CALLBACKS
        if (nonBlocking) {
            CyaSSL_set_using_nonblock(ssl, 1);
            tcp_set_nonblocking(&clientfd);
        }
#endif

        do {
#ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_PENDING_E) {
                ret = AsyncCryptPoll(ssl);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
#endif

            err = 0; /* Reset error */
#ifndef CYASSL_CALLBACKS
            if (nonBlocking) {
                ret = NonBlockingSSL_Accept(ssl);
            }
            else {
                ret = SSL_accept(ssl);
            }
#else
            ret = NonBlockingSSL_Accept(ssl);
#endif
            if (ret != SSL_SUCCESS) {
                err = SSL_get_error(ssl, 0);
            }
        } while (ret != SSL_SUCCESS && err == WC_PENDING_E);

        if (ret != SSL_SUCCESS) {
            char buffer[CYASSL_MAX_ERROR_SZ];
            err = SSL_get_error(ssl, 0);
            printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
            err_sys("SSL_accept failed");
        }

        showPeer(ssl);

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            char *protocol_name = NULL, *list = NULL;
            word16 protocol_nameSz = 0, listSz = 0;

            err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
            if (err == SSL_SUCCESS)
                printf("Sent ALPN protocol : %s (%d)\n",
                       protocol_name, protocol_nameSz);
            else if (err == SSL_ALPN_NOT_FOUND)
                printf("No ALPN response sent (no match)\n");
            else
                printf("Getting ALPN protocol name failed\n");

            err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz);
            if (err == SSL_SUCCESS)
                printf("List of protocol names sent by Client: %s (%d)\n",
                       list, listSz);
            else
                printf("Get list of client's protocol name failed\n");

            free(list);
        }
#endif
        if(echoData == 0 && throughput == 0) {
            ret = SSL_read(ssl, input, sizeof(input)-1);
            if (ret > 0) {
                input[ret] = 0;
                printf("Client message: %s\n", input);

            }
            else if (ret < 0) {
                int readErr = SSL_get_error(ssl, 0);
                if (readErr != SSL_ERROR_WANT_READ)
                    err_sys("SSL_read failed");
            }

            if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
                err_sys("SSL_write failed");
        }
        else {
            ServerEchoData(ssl, clientfd, echoData, throughput);
        }

#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
        os_dly_wait(500) ;
#elif defined (CYASSL_TIRTOS)
        Task_yield();
#endif

        if (doDTLS == 0) {
            ret = SSL_shutdown(ssl);
            if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
                SSL_shutdown(ssl);    /* bidirectional shutdown */
        }
        /* display collected statistics */
#ifdef WOLFSSL_STATIC_MEMORY
        if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1)
            err_sys("static memory was not used with ssl");

        fprintf(stderr, "\nprint off SSL memory stats\n");
        fprintf(stderr, "*** This is memory state before wolfSSL_free is called\n");
        fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem);
        fprintf(stderr, "current memory in use  = %d\n", ssl_stats.curMem);
        fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc);
        fprintf(stderr, "current connection allocs = %d\n",ssl_stats.curAlloc);
        fprintf(stderr, "total connection allocs   = %d\n",ssl_stats.totalAlloc);
        fprintf(stderr, "total connection frees    = %d\n\n", ssl_stats.totalFr);

#endif
        SSL_free(ssl);

        CloseSocket(clientfd);

        if (resume == 1 && resumeCount == 0) {
            resumeCount++;           /* only do one resume for testing */
            continue;
        }
        resumeCount = 0;

        if(!loopIndefinitely) {
            break;  /* out of while loop, done with normal and resume option */
        }
    } /* while(1) */


    CloseSocket(sockfd);
    SSL_CTX_free(ctx);

    ((func_args*)args)->return_code = 0;


#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    ecc_fp_free();  /* free per thread cache */
#endif

#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
    if (trackMemory)
        ShowMemoryTracker();
#endif

#ifdef CYASSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    TicketCleanup();
#endif

    /* There are use cases  when these assignments are not read. To avoid
     * potential confusion those warnings have been handled here.
     */
    (void) ourKey;
    (void) verifyCert;
    (void) doCliCertCheck;
    (void) useNtruKey;
    (void) ourDhParam;
    (void) ourCert;
    (void) trackMemory;
#ifndef CYASSL_TIRTOS
    return 0;
#endif
}
Exemple #11
0
PEGASUS_NAMESPACE_BEGIN

//
// Basic SSL socket
//

SSLSocket::SSLSocket(
    SocketHandle socket,
    SSLContext * sslcontext,
    ReadWriteSem * sslContextObjectLock,
    const String& ipAddress)
   :
   _SSLConnection(0),
   _socket(socket),
   _SSLContext(sslcontext),
   _sslContextObjectLock(sslContextObjectLock),
   _ipAddress(ipAddress),
   _certificateVerified(false)
{
    PEG_METHOD_ENTER(TRC_SSL, "SSLSocket::SSLSocket()");

    SSL* sslConnection;
    SharedPtr<X509_STORE, FreeX509STOREPtr> tmpCrlStore;

    _sslReadErrno = 0;

    //
    // create the SSLConnection area
    //
    if (!(sslConnection = SSL_new(_SSLContext->_rep->getContext())))
    {
        PEG_METHOD_EXIT();
        MessageLoaderParms parms(
            "Common.TLS.COULD_NOT_GET_SSL_CONNECTION_AREA",
            "Could not get SSL Connection Area.");
        throw SSLException(parms);
    }

    // This try/catch block is necessary so that we can free the SSL Connection
    // Area if any exceptions are thrown.
    try
    {
        //
        // set the verification callback data
        //

        // we are only storing one set of data, so we can just use index 0,
        // this is defined in SSLContext.h
        //int index = SSL_get_ex_new_index(
        //    0, (void*)"pegasus", NULL, NULL, NULL);

        //
        // Create a new callback info for each new connection
        //
#ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
        tmpCrlStore = _SSLContext->_rep->getCRLStore();
#endif
        _SSLCallbackInfo.reset(new SSLCallbackInfo(
            _SSLContext->getSSLCertificateVerifyFunction(),
            tmpCrlStore.get(),
            _ipAddress ));

        if (SSL_set_ex_data(
                sslConnection,
                SSLCallbackInfo::SSL_CALLBACK_INDEX,
                _SSLCallbackInfo.get()))
        {
            PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
                "--->SSL: Set callback info");
        }
        else
        {
            PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
                "--->SSL: Error setting callback info");
        }

        //
        // and connect the active socket with the ssl operation
        //
        if (!(SSL_set_fd(sslConnection, _socket) ))
        {
            PEG_METHOD_EXIT();
            MessageLoaderParms parms(
                "Common.TLS.COULD_NOT_LINK_SOCKET",
                "Could not link socket to SSL Connection.");
            throw SSLException(parms);
        }
    }
    catch (...)
    {
        SSL_free(sslConnection);
        throw;
    }

    _SSLConnection = sslConnection;
    _crlStore = new SharedPtr<X509_STORE, FreeX509STOREPtr>(tmpCrlStore);

    PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: Created SSL socket");

    PEG_METHOD_EXIT();
}
Exemple #12
0
int MAIN(int argc, char **argv)
{
    int ret = 1, i;
    int verbose = 0, Verbose = 0;
    const char **pp;
    const char *p;
    int badops = 0;
    SSL_CTX *ctx = NULL;
    SSL *ssl = NULL;
    char *ciphers = NULL;
    const SSL_METHOD *meth = NULL;
    STACK_OF(SSL_CIPHER) *sk;
    char buf[512];
    BIO *STDout = NULL;

    meth = SSLv23_server_method();

    apps_startup();

    if (bio_err == NULL)
        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
    STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
    {
        BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        STDout = BIO_push(tmpbio, STDout);
    }
#endif
    if (!load_config(bio_err, NULL))
        goto end;

    argc--;
    argv++;
    while (argc >= 1) {
        if (strcmp(*argv, "-v") == 0)
            verbose = 1;
        else if (strcmp(*argv, "-V") == 0)
            verbose = Verbose = 1;
#ifndef OPENSSL_NO_SSL2
        else if (strcmp(*argv, "-ssl2") == 0)
            meth = SSLv2_client_method();
#endif
#ifndef OPENSSL_NO_SSL3
        else if (strcmp(*argv, "-ssl3") == 0)
            meth = SSLv3_client_method();
#endif
#ifndef OPENSSL_NO_TLS1
        else if (strcmp(*argv, "-tls1") == 0)
            meth = TLSv1_client_method();
#endif
        else if ((strncmp(*argv, "-h", 2) == 0) || (strcmp(*argv, "-?") == 0)) {
            badops = 1;
            break;
        } else {
            ciphers = *argv;
        }
        argc--;
        argv++;
    }

    if (badops) {
        for (pp = ciphers_usage; (*pp != NULL); pp++)
            BIO_printf(bio_err, "%s", *pp);
        goto end;
    }

    OpenSSL_add_ssl_algorithms();

    ctx = SSL_CTX_new(meth);
    if (ctx == NULL)
        goto err;
    if (ciphers != NULL) {
        if (!SSL_CTX_set_cipher_list(ctx, ciphers)) {
            BIO_printf(bio_err, "Error in cipher list\n");
            goto err;
        }
    }
    ssl = SSL_new(ctx);
    if (ssl == NULL)
        goto err;

    if (!verbose) {
        for (i = 0;; i++) {
            p = SSL_get_cipher_list(ssl, i);
            if (p == NULL)
                break;
            if (i != 0)
                BIO_printf(STDout, ":");
            BIO_printf(STDout, "%s", p);
        }
        BIO_printf(STDout, "\n");
    } else {                    /* verbose */

        sk = SSL_get_ciphers(ssl);

        for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
            SSL_CIPHER *c;

            c = sk_SSL_CIPHER_value(sk, i);

            if (Verbose) {
                unsigned long id = SSL_CIPHER_get_id(c);
                int id0 = (int)(id >> 24);
                int id1 = (int)((id >> 16) & 0xffL);
                int id2 = (int)((id >> 8) & 0xffL);
                int id3 = (int)(id & 0xffL);

                if ((id & 0xff000000L) == 0x02000000L) {
                    /* SSL2 cipher */
                    BIO_printf(STDout, "     0x%02X,0x%02X,0x%02X - ", id1,
                               id2, id3);
                } else if ((id & 0xff000000L) == 0x03000000L) {
                    /* SSL3 cipher */
                    BIO_printf(STDout, "          0x%02X,0x%02X - ", id2,
                               id3);
                } else {
                    /* whatever */
                    BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0,
                               id1, id2, id3);
                }
            }

            BIO_puts(STDout, SSL_CIPHER_description(c, buf, sizeof buf));
        }
    }

    ret = 0;
    if (0) {
 err:
        SSL_load_error_strings();
        ERR_print_errors(bio_err);
    }
 end:
    if (ctx != NULL)
        SSL_CTX_free(ctx);
    if (ssl != NULL)
        SSL_free(ssl);
    if (STDout != NULL)
        BIO_free_all(STDout);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Exemple #13
0
/* {{{ ftp_login
 */
int
ftp_login(ftpbuf_t *ftp, const char *user, const char *pass)
{
#ifdef HAVE_FTP_SSL
	SSL_CTX	*ctx = NULL;
	long ssl_ctx_options = SSL_OP_ALL;
	int err, res;
	zend_bool retry;
#endif
	if (ftp == NULL) {
		return 0;
	}

#ifdef HAVE_FTP_SSL
	if (ftp->use_ssl && !ftp->ssl_active) {
		if (!ftp_putcmd(ftp, "AUTH", "TLS")) {
			return 0;
		}
		if (!ftp_getresp(ftp)) {
			return 0;
		}

		if (ftp->resp != 234) {
			if (!ftp_putcmd(ftp, "AUTH", "SSL")) {
				return 0;
			}
			if (!ftp_getresp(ftp)) {
				return 0;
			}

			if (ftp->resp != 334) {
				return 0;
			} else {
				ftp->old_ssl = 1;
				ftp->use_ssl_for_data = 1;
			}
		}

		ctx = SSL_CTX_new(SSLv23_client_method());
		if (ctx == NULL) {
			php_error_docref(NULL, E_WARNING, "failed to create the SSL context");
			return 0;
		}

#if OPENSSL_VERSION_NUMBER >= 0x0090605fL
		ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
		SSL_CTX_set_options(ctx, ssl_ctx_options);

		ftp->ssl_handle = SSL_new(ctx);
		if (ftp->ssl_handle == NULL) {
			php_error_docref(NULL, E_WARNING, "failed to create the SSL handle");
			SSL_CTX_free(ctx);
			return 0;
		}

		SSL_set_fd(ftp->ssl_handle, ftp->fd);

		do {
			res = SSL_connect(ftp->ssl_handle);
			err = SSL_get_error(ftp->ssl_handle, res);

			/* TODO check if handling other error codes would make sense */
			switch (err) {
				case SSL_ERROR_NONE:
					retry = 0;
					break;

				case SSL_ERROR_ZERO_RETURN:
					retry = 0;
					SSL_shutdown(ftp->ssl_handle);
					break;

				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_WRITE: {
						php_pollfd p;
						int i;

						p.fd = ftp->fd;
						p.events = (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : POLLOUT;
						p.revents = 0;

						i = php_poll2(&p, 1, 300);

						retry = i > 0;
					}
					break;

				default:
					php_error_docref(NULL, E_WARNING, "SSL/TLS handshake failed");
					SSL_shutdown(ftp->ssl_handle);
					SSL_free(ftp->ssl_handle);
					return 0;
			}
		} while (retry);

		ftp->ssl_active = 1;

		if (!ftp->old_ssl) {

			/* set protection buffersize to zero */
			if (!ftp_putcmd(ftp, "PBSZ", "0")) {
				return 0;
			}
			if (!ftp_getresp(ftp)) {
				return 0;
			}

			/* enable data conn encryption */
			if (!ftp_putcmd(ftp, "PROT", "P")) {
				return 0;
			}
			if (!ftp_getresp(ftp)) {
				return 0;
			}

			ftp->use_ssl_for_data = (ftp->resp >= 200 && ftp->resp <=299);
		}
	}
#endif

	if (!ftp_putcmd(ftp, "USER", user)) {
		return 0;
	}
	if (!ftp_getresp(ftp)) {
		return 0;
	}
	if (ftp->resp == 230) {
		return 1;
	}
	if (ftp->resp != 331) {
		return 0;
	}
	if (!ftp_putcmd(ftp, "PASS", pass)) {
		return 0;
	}
	if (!ftp_getresp(ftp)) {
		return 0;
	}
	return (ftp->resp == 230);
}
Exemple #14
0
/* {{{ data_accept
 */
databuf_t*
data_accept(databuf_t *data, ftpbuf_t *ftp)
{
	php_sockaddr_storage addr;
	socklen_t			size;

#ifdef HAVE_FTP_SSL
	SSL_CTX		*ctx;
	zend_long ssl_ctx_options = SSL_OP_ALL;
	int err, res;
	zend_bool retry;
#endif

	if (data->fd != -1) {
		goto data_accepted;
	}
	size = sizeof(addr);
	data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size);
	closesocket(data->listener);
	data->listener = -1;

	if (data->fd == -1) {
		efree(data);
		return NULL;
	}

data_accepted:
#ifdef HAVE_FTP_SSL

	/* now enable ssl if we need to */
	if (ftp->use_ssl && ftp->use_ssl_for_data) {
		ctx = SSL_CTX_new(SSLv23_client_method());
		if (ctx == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL context");
			return 0;
		}

#if OPENSSL_VERSION_NUMBER >= 0x0090605fL
		ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
		SSL_CTX_set_options(ctx, ssl_ctx_options);

		data->ssl_handle = SSL_new(ctx);
		if (data->ssl_handle == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL handle");
			SSL_CTX_free(ctx);
			return 0;
		}


		SSL_set_fd(data->ssl_handle, data->fd);

		if (ftp->old_ssl) {
			SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle);
		}

		do {
			res = SSL_connect(data->ssl_handle);
			err = SSL_get_error(data->ssl_handle, res);

			switch (err) {
				case SSL_ERROR_NONE:
					retry = 0;
					break;

				case SSL_ERROR_ZERO_RETURN:
					retry = 0;
					SSL_shutdown(data->ssl_handle);
					break;

				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_WRITE: {
						php_pollfd p;
						int i;

						p.fd = ftp->fd;
						p.events = (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : POLLOUT;
						p.revents = 0;

						i = php_poll2(&p, 1, 300);

						retry = i > 0;
					}
					break;

				default:
					php_error_docref(NULL, E_WARNING, "data_accept: SSL/TLS handshake failed");
					SSL_shutdown(data->ssl_handle);
					SSL_free(data->ssl_handle);
					return 0;
			}
		} while (retry);

		data->ssl_active = 1;
	}

#endif

	return data;
}
Exemple #15
0
int main(int argc, char *argv[])
{
    /* deletes existeng ecents */
    remove("ecents.txt");
    SSL_CTX *ctx;
    int type, server, localport, proxyport, bankport;
    int i = 0;
    SSL *ssl;
    char buf[1024];
	char buf2[33000];
    int bytes;
    char *proxyhost;
    char *bankhost;
    
    if ( argc <6 )
    {
        printf("usage: type localport proxyhost proxyport bankhost bankport \n");
        exit(0);
    }
    /* initialises SSL library and copies line arguments */
    SSL_library_init();
    type = atoi(argv[1]);
    localport=atoi(argv[2]);
    proxyhost=argv[3];
    proxyport = atoi(argv[4]);
    bankhost = argv[5];
    bankport = atoi(argv[6]);
    registrationrequest(type, localport, proxyhost, proxyport);
    int requestedecents = 1000;
    
    
    while(1){
        char msg[1024];
        bzero(msg,1024);
        ctx = InitCTX();
        if(i == 0){
            printf("\nrequested number of eCents: \n");
	    wait(3);
	    printf("\t%i\n", requestedecents);
	    wait(3);
            sprintf(msg,"%c%i",'0',requestedecents);
	        server = OpenConnection(bankhost, localport, bankport);
        }
        else{
            printf("\ninput:\n");
            strcpy(msg, geteCent());
            if(strlen(msg) != 32){
                printf("no eCents\n");
            }
            else {
                strcat(msg, getData());
                server = OpenConnection(proxyhost, localport, proxyport);
            }
        }
	/* creates ssl context and sets socket to it*/
        ssl = SSL_new(ctx);      
        SSL_set_fd(ssl, server);   
        if ( SSL_connect(ssl) == -1 ){  
            ERR_print_errors_fp(stderr);
	    printf("connection error\n");
	}
        else
        {
            printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
            printf("sending: %s\n", msg);
            ShowCerts(ssl);  
		/* Write to Bank to verify ecent */  
            SSL_write(ssl, msg, sizeof(msg));  
            
            if(i == 0){
		bzero(buf2, 33000);
		/* Read from Bank, confirm verification*/
		bytes = SSL_read(ssl, buf2, sizeof(buf2)); 
		if(bytes < 1) 
		{
			printf("Exit read error from Bank\n");
			exit(1);
		}
            	buf2[bytes] = '\0';
                printf("eCents received: %s\n", buf2);
                puteCents(buf2);
            }
            else{
		/* Reads from Collector*/
		bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
            	buf[bytes] = '\0';
		if(bytes < 1) 
		{
			printf("Exit: read error from Analyst\n");
			exit(1);
		}
                if(strcmp(buf, "invalid eCent") == 0)
                    printf("\n%s\n", buf);
                else
                    printf("\naverage: %s\n", buf);
            }
            SSL_free(ssl);        
        }
        sleep(1);
        close(server);         
        SSL_CTX_free(ctx);       
        i++;
    }
    return 0;
}
Exemple #16
0
static void sl_destroy_ssl (SLtype type, VOID_STAR f){
  SLssl_Type *ssl;
  ssl=(SLssl_Type *)f;
  SSL_free((SSL *)(ssl->ssl));
}
Exemple #17
0
Result<SslFd> SslFd::init(SocketFd fd, CSlice host, CSlice cert_file, VerifyPeer verify_peer) {
#if TD_WINDOWS
  return Status::Error("TODO");
#else
  static bool init_openssl = [] {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
    return OPENSSL_init_ssl(0, nullptr) != 0;
#else
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    return OpenSSL_add_ssl_algorithms() != 0;
#endif
  }();
  CHECK(init_openssl);

  openssl_clear_errors("Before SslFd::init");
  CHECK(!fd.empty());

  auto ssl_method =
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
      TLS_client_method();
#else
      SSLv23_client_method();
#endif
  if (ssl_method == nullptr) {
    return create_openssl_error(-6, "Failed to create an SSL client method");
  }

  auto ssl_ctx = SSL_CTX_new(ssl_method);
  if (ssl_ctx == nullptr) {
    return create_openssl_error(-7, "Failed to create an SSL context");
  }
  auto ssl_ctx_guard = ScopeExit() + [&]() { SSL_CTX_free(ssl_ctx); };
  long options = 0;
#ifdef SSL_OP_NO_SSLv2
  options |= SSL_OP_NO_SSLv2;
#endif
#ifdef SSL_OP_NO_SSLv3
  options |= SSL_OP_NO_SSLv3;
#endif
  SSL_CTX_set_options(ssl_ctx, options);
  SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE);

  if (cert_file.empty()) {
    SSL_CTX_set_default_verify_paths(ssl_ctx);
  } else {
    if (SSL_CTX_load_verify_locations(ssl_ctx, cert_file.c_str(), nullptr) == 0) {
      return create_openssl_error(-8, "Failed to set custom cert file");
    }
  }
  if (VERIFY_PEER && verify_peer == VerifyPeer::On) {
    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, verify_callback);

    if (VERIFY_DEPTH != -1) {
      SSL_CTX_set_verify_depth(ssl_ctx, VERIFY_DEPTH);
    }
  } else {
    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, nullptr);
  }

  // TODO(now): cipher list
  string cipher_list;
  if (SSL_CTX_set_cipher_list(ssl_ctx, cipher_list.empty() ? "DEFAULT" : cipher_list.c_str()) == 0) {
    return create_openssl_error(-9, PSLICE("Failed to set cipher list \"%s\"", cipher_list.c_str()));
  }

  auto ssl_handle = SSL_new(ssl_ctx);
  if (ssl_handle == nullptr) {
    return create_openssl_error(-13, "Failed to create an SSL handle");
  }
  auto ssl_handle_guard = ScopeExit() + [&]() {
    do_ssl_shutdown(ssl_handle);
    SSL_free(ssl_handle);
  };

#if OPENSSL_VERSION_NUMBER >= 0x10002000L
  X509_VERIFY_PARAM *param = SSL_get0_param(ssl_handle);
  /* Enable automatic hostname checks */
  // TODO: X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
  X509_VERIFY_PARAM_set_hostflags(param, 0);
  X509_VERIFY_PARAM_set1_host(param, host.c_str(), 0);
#else
#warning DANGEROUS! HTTPS HOST WILL NOT BE CHECKED. INSTALL OPENSSL >= 1.0.2 OR IMPLEMENT HTTPS HOST CHECK MANUALLY
#endif

  if (!SSL_set_fd(ssl_handle, fd.get_fd().get_native_fd())) {
    return create_openssl_error(-14, "Failed to set fd");
  }

#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
  auto host_str = host.str();
  SSL_set_tlsext_host_name(ssl_handle, MutableCSlice(host_str).begin());
#endif
  SSL_set_connect_state(ssl_handle);

  ssl_ctx_guard.dismiss();
  ssl_handle_guard.dismiss();
  return SslFd(std::move(fd), ssl_handle, ssl_ctx);
#endif
}
Exemple #18
0
/*@C
     PetscHTTPSRequest - Send a request to an HTTPS server

   Input Parameters:
+   type - either "POST" or "GET"
.   url -  URL of request host/path
.   header - additional header information, may be NULL
.   ctype - data type of body, for example application/json
.   body - data to send to server
.   ssl - obtained with PetscHTTPSConnect()
-   buffsize - size of buffer

   Output Parameter:
.   buff - everything returned from server

    Level: advanced

.seealso: PetscHTTPRequest(), PetscHTTPSConnect(), PetscSSLInitializeContext(), PetscSSLDestroyContext(), PetscPullJSONValue()

@*/
PetscErrorCode PetscHTTPSRequest(const char type[],const char url[],const char header[],const char ctype[],const char body[],SSL *ssl,char buff[],size_t buffsize)
{
  char           *request;
  int            r;
  size_t         request_len,len;
  PetscErrorCode ierr;
  PetscBool      foundbody = PETSC_FALSE;

  PetscFunctionBegin;
  ierr = PetscHTTPBuildRequest(type,url,header,ctype,body,&request);CHKERRQ(ierr);
  ierr = PetscStrlen(request,&request_len);CHKERRQ(ierr);

  r = SSL_write(ssl,request,(int)request_len);
  switch (SSL_get_error(ssl,r)){
    case SSL_ERROR_NONE:
      if (request_len != (size_t)r) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Incomplete write to SSL socket");
      break;
    default:
      SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL socket write problem");
  }

  /* Now read the server's response, globus sends it in two chunks hence must read a second time if needed */
  ierr      = PetscMemzero(buff,buffsize);CHKERRQ(ierr);
  len       = 0;
  foundbody = PETSC_FALSE;
  do {
    char   *clen;
    int    cl;
    size_t nlen;

    r = SSL_read(ssl,buff+len,(int)buffsize);
    len += r;
    switch (SSL_get_error(ssl,r)){
    case SSL_ERROR_NONE:
      break;
    case SSL_ERROR_ZERO_RETURN:
      foundbody = PETSC_TRUE;
      SSL_shutdown(ssl);
      break;
    case SSL_ERROR_SYSCALL:
      foundbody = PETSC_TRUE;
      break;
    default:
      SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL read problem");
    }

    ierr = PetscStrstr(buff,"Content-Length: ",&clen);CHKERRQ(ierr);
    if (clen) {
      clen += 15;
      sscanf(clen,"%d",&cl);
      if (!cl) foundbody = PETSC_TRUE;
      else {
        ierr = PetscStrstr(buff,"\r\n\r\n",&clen);CHKERRQ(ierr);
        if (clen) {
          ierr = PetscStrlen(clen,&nlen);CHKERRQ(ierr);
          if (nlen-4 == (size_t) cl) foundbody = PETSC_TRUE;
        }
      }
    } else {
      /* if no content length than must leave because you don't know if you can read again */
      foundbody = PETSC_TRUE;
    }
  } while (!foundbody);
  ierr = PetscInfo1(NULL,"HTTPS result follows: \n%s\n",buff);CHKERRQ(ierr);

  SSL_free(ssl);
  ierr = PetscFree(request);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #19
0
void
signal_handler(int sig)
{
	switch (sig) {
	case SIGXFSZ:
		log_msg(mainlogfile, gettext("File size limit exceeded"), 1);
		log_msg(mainlogfile, gettext("\nProgram Terminated.\n"), 1);
		log_msg(mainlogfile,
			"<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n\n", 0);
		if (client_sock != -1)
				close(client_sock);

		#ifndef WITHOUT_SSL
		        SSL_shutdown(ssl);
    			SSL_free(ssl);
    			SSL_CTX_free(ctx);
		#else
        		close(server_sock);
		#endif

		exit(1);

		break;
	case SIGPIPE:
		
		#ifndef WITHOUT_SSL		
			nunetwork_close(ssl);
		#else
			nunetwork_close(client_sock);
		#endif
		
		break;
	case SIGHUP:
		log_msg(mainlogfile, gettext("Hangup signal catched"), 1);
		log_msg(mainlogfile, gettext("\nReloading configuration...\n\n"), 1);
		readconfig(conffile);
		setlocale (LC_ALL, (const char*)lc_all);
		bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
		textdomain ( PACKAGE );
		log_msg(mainlogfile,
			gettext("Configuration reloaded successfully.\n\n"), 1);

		break;
	case SIGTERM:
		log_msg(mainlogfile, gettext("Terminate signal catched"), 1);
		log_msg(mainlogfile, gettext("\nClosing active sessions...\n"), 1);
		if (client_sock != -1)
			close(client_sock);
		
		#ifndef WITHOUT_SSL
        		SSL_shutdown(ssl);
    			SSL_free(ssl);
    			SSL_CTX_free(ctx);
		#else
        		close(server_sock);
		#endif
		

		log_msg(mainlogfile, gettext("Bye bye\n"), 1);
		log_msg(mainlogfile,
			"<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n\n", 0);
		log_msg(logfile,
			"<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>\n\n", 0);
		exit(0);
		break;
	}
}
void main()
{
    int     err;
        int     verify_client = OFF; /* To verify a client certificate, set ON */
 
      int     listen_sock;
        int     sock;
       struct sockaddr_in sa_serv;
         struct sockaddr_in sa_cli;
          size_t client_len;
          char    *str;
       char     buf[4096];
 
    SSL_CTX         *ctx;
        SSL            *ssl;
       SSL_METHOD      *meth;

        X509            *client_cert = NULL;
 
   short int       s_port = 5555;
/*----------------------------------------------------------------*/
      /* Load encryption & hashing algorithms for the SSL program */
  SSL_library_init();
 
    /* Load the error strings for SSL & CRYPTO APIs */
      SSL_load_error_strings();
 
      /* Create a SSL_METHOD structure (choose a SSL/TLS protocol version) */
     meth = SSLv3_method();
 
 /* Create a SSL_CTX structure */
    ctx = SSL_CTX_new(meth);
 
       if (!ctx) {
 
            ERR_print_errors_fp(stderr);
 
           exit(1);
 
       }
 
      /* Load the server certificate into the SSL_CTX structure */
        if (SSL_CTX_use_certificate_file(ctx, RSA_SERVER_CERT, SSL_FILETYPE_PEM) <= 0) {
 
                    ERR_print_errors_fp(stderr);
 
                   exit(1);
 
       }
 
      /* Load the private-key corresponding to the server certificate */
          if (SSL_CTX_use_PrivateKey_file(ctx, RSA_SERVER_KEY, SSL_FILETYPE_PEM) <= 0) {
 
              ERR_print_errors_fp(stderr);
                exit(1);
    }
 
      /* Check if the server certificate and private-key matches */
       if (!SSL_CTX_check_private_key(ctx)) {
 
                 fprintf(stderr,"Private key does not match the certificate public key\n");
                  exit(1);
    }
 
      if(verify_client == ON)
 
        {
 
              /* Load the RSA CA certificate into the SSL_CTX structure */
                if (!SSL_CTX_load_verify_locations(ctx, RSA_SERVER_CA_CERT, NULL)) {
 
                   ERR_print_errors_fp(stderr);
                        exit(1);
            }
 
              /* Set to require peer (client) certificate verification */
         SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
 
          /* Set the verification depth to 1 */
               SSL_CTX_set_verify_depth(ctx,1);
 
       }
   /* ----------------------------------------------- */
       /* Set up a TCP socket */
 
      listen_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);   
 
    RETURN_ERR(listen_sock, "socket");
          memset (&sa_serv, '\0', sizeof(sa_serv));
       sa_serv.sin_family      = AF_INET;
          sa_serv.sin_addr.s_addr = INADDR_ANY;
       sa_serv.sin_port        = htons (s_port);          /* Server Port number */
         err = bind(listen_sock, (struct sockaddr*)&sa_serv,sizeof(sa_serv));
 
       RETURN_ERR(err, "bind");
     
   /* Wait for an incoming TCP connection. */
          err = listen(listen_sock, 5);                    
 
      RETURN_ERR(err, "listen");
          client_len = sizeof(sa_cli);
 
   /* Socket for a TCP/IP connection is created */
     sock = accept(listen_sock, (struct sockaddr*)&sa_cli, &client_len);
 
    RETURN_ERR(sock, "accept");
         close (listen_sock);
 
   printf ("Connection from %lx, port %x\n", sa_cli.sin_addr.s_addr, 
   sa_cli.sin_port);
 
     /* ----------------------------------------------- */
       /* TCP connection is ready. */
      /* A SSL structure is created */
    ssl = SSL_new(ctx);
 
    RETURN_NULL(ssl);
 
      /* Assign the socket into the SSL structure (SSL and socket without BIO) */
 SSL_set_fd(ssl, sock);
 
 /* Perform SSL Handshake on the SSL server */
       err = SSL_accept(ssl);
 
 RETURN_SSL(err);
 
       /* Informational output (optional) */
       printf("SSL connection using %s\n", SSL_get_cipher (ssl));
 
     if (verify_client == ON)
    {
 
          /* Get the client's certificate (optional) */
       client_cert = SSL_get_peer_certificate(ssl);
        if (client_cert != NULL) 
           {
 
              printf ("Client certificate:\n");     
              str = X509_NAME_oneline(X509_get_subject_name(client_cert), 0, 0);
                  RETURN_NULL(str);
                   printf ("\t subject: %s\n", str);
                   free (str);
                 str = X509_NAME_oneline(X509_get_issuer_name(client_cert), 0, 0);
                   RETURN_NULL(str);
                   printf ("\t issuer: %s\n", str);
                    free (str);
                 X509_free(client_cert);
     } 
 
     else
 
                   printf("The SSL client does not have certificate.\n");
  }
 
      /*------- DATA EXCHANGE - Receive message and send reply. -------*/
 /* Receive data from the SSL client */
      err = SSL_read(ssl, buf, sizeof(buf) - 1);
 
     RETURN_SSL(err);
 
       buf[err] = '\0';
 
       printf ("Received %d chars:'%s'\n", err, buf);
 
 /* Send data to the SSL client */
   err = SSL_write(ssl, "This message is from the SSL server", 
 
   strlen("This message is from the SSL server"));
 
        RETURN_SSL(err);
 
       /*--------------- SSL closure ---------------*/
     /* Shutdown this side (server) of the connection. */
 
   err = SSL_shutdown(ssl);
 
       RETURN_SSL(err);
 
       /* Terminate communication on a socket */
   err = close(sock);
 
     RETURN_ERR(err, "close");
 
      /* Free the SSL structure */
        SSL_free(ssl);
 
 /* Free the SSL_CTX structure */
    SSL_CTX_free(ctx);
 
}
Exemple #21
0
int main_tls_client() {
  SSL_CTX *ctx;
  SSL *ssl;
  int server = 0;
  int ret;

  if ( (ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
    printf("Unable to create a new SSL context structure.\n");

  SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
  // Force gcm(aes) mode
  SSL_CTX_set_cipher_list(ctx, "ECDH-ECDSA-AES128-GCM-SHA256");

  ssl = SSL_new(ctx);

  server = create_socket();

  SSL_set_fd(ssl, server);

  if ( SSL_connect(ssl) != 1 ) {
    printf("Error: Could not build a SSL session\n");
    exit(-1);
  }

// Start tests

  clock_t start, end;
  double cpu_time_used;

  int filefd;
  int bytes;
  int totalbytes = 0;
  bytes_recv = 0;
  char buf[16384];

  int res = 0;
  int total_recv = 0;

  start = clock();

  filefd = open(test_data, O_RDONLY);
  totalbytes = 0;

  do {
    bytes = read(filefd, buf, sizeof(buf));
    totalbytes += bytes;
    if (bytes > 0)
      SSL_write(ssl, buf, bytes);
  } while(bytes > 0);

  close(filefd);


    end = clock();
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

    printf("OpenSSL receive time: %.02f\n", cpu_time_used);

  res = 0;
  total_recv = 0;

  res = SSL_read(ssl, buf, 1);

  total_recv += res;
  if (res < 0) {
    printf("SSL Read error: %i\n", res);
  }
  printf("Received openssl test data: %i %i\n", res, total_recv);

/* Kernel TLS tests */
  int tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
  if (tfmfd == -1) {
    perror("socket error:");
    exit(-1);
  }

  struct sockaddr_alg sa = {
    .salg_family = AF_ALG,
    .salg_type = "tls", /* this selects the hash logic in the kernel */
    .salg_name = "rfc5288(gcm(aes))" /* this is the cipher name */
  };

  if (bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
    perror("AF_ALG: bind failed");
    close(tfmfd);
    exit(-1);
  }

  int opfd = accept(tfmfd, NULL, 0);
  if (opfd == -1) {
    perror("accept:");
    close(tfmfd);
    exit(-1);
  }

  if (setsockopt(tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 16)) {
    perror("AF_ALG: set authsize failed\n");
    exit(-1);
  }

  EVP_CIPHER_CTX * writeCtx = ssl->enc_write_ctx;
  EVP_CIPHER_CTX * readCtx = ssl->enc_read_ctx;

  EVP_AES_GCM_CTX* gcmWrite = (EVP_AES_GCM_CTX*)(writeCtx->cipher_data);
  EVP_AES_GCM_CTX* gcmRead = (EVP_AES_GCM_CTX*)(readCtx->cipher_data);

  unsigned char* writeKey = (unsigned char*)(gcmWrite->gcm.key);
  unsigned char* readKey = (unsigned char*)(gcmRead->gcm.key);

  unsigned char* writeIV = gcmWrite->iv;
  unsigned char* readIV = gcmRead->iv;

  char keyiv[20];
  memcpy(keyiv, writeKey, 16);
  memcpy(keyiv + 16, writeIV, 4);

  if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, keyiv, 20)) {
    perror("AF_ALG: set write key failed\n");
    exit(-1);
  }

  memcpy(keyiv, readKey, 16);
  memcpy(keyiv + 16, readIV, 4);

  if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, keyiv, 20)) {
    perror("AF_ALG: set read key failed\n");
    exit(-1);
  }

  // Load up the cmsg data
  struct cmsghdr *header = NULL;
  uint32_t *type = NULL;
  struct msghdr msg;

  /* IV data */
  struct af_alg_iv *alg_iv = NULL;
  int ivsize = 12;
  uint32_t iv_msg_size = CMSG_SPACE(sizeof(*alg_iv) + ivsize);

  /* AEAD data */
  uint32_t *assoclen = NULL;
  uint32_t assoc_msg_size = CMSG_SPACE(sizeof(*assoclen));

  uint32_t bufferlen =
    CMSG_SPACE(sizeof(*type)) + /* Encryption / Decryption */
    iv_msg_size +/* IV */
    assoc_msg_size;/* AEAD associated data size */

  memset(&msg, 0, sizeof(msg));

  char* buffer = calloc(1, bufferlen);
  if (!buffer)
    return -ENOMEM;

  msg.msg_control = buffer;
  msg.msg_controllen = bufferlen;
  msg.msg_iov = NULL;
  msg.msg_iovlen = 0;

  /* encrypt/decrypt operation */
  header = CMSG_FIRSTHDR(&msg);
  header->cmsg_level = SOL_ALG;
  header->cmsg_type = ALG_SET_OP;
  header->cmsg_len = CMSG_LEN(sizeof(*type));
  type = (void*)CMSG_DATA(header);
  *type = server;


  /* set IV */
  header = CMSG_NXTHDR(&msg, header);
  header->cmsg_level = SOL_ALG;
  header->cmsg_type = ALG_SET_IV;
  header->cmsg_len = iv_msg_size;
  alg_iv = (void*)CMSG_DATA(header);
  alg_iv->ivlen = 8;
  uint64_t writeSeq;
  unsigned char* writeSeqNum = ssl->s3->write_sequence;
  memcpy(&writeSeq, writeSeqNum, sizeof(writeSeq));

  memcpy(alg_iv->iv, &writeSeq, 8);


  /* set AEAD information */
  /* Set associated data length */
  header = CMSG_NXTHDR(&msg, header);
  header->cmsg_level = SOL_ALG;
  header->cmsg_type = ALG_SET_AEAD_ASSOCLEN;
  header->cmsg_len = CMSG_LEN(sizeof(*assoclen));
  assoclen = (void*)CMSG_DATA(header);
  *assoclen = 13 + 8;

  ret = sendmsg(opfd, &msg, MSG_MORE);
  if (ret < 0) {
    perror("sendmsg");
    exit(-1);
  }

  header = CMSG_FIRSTHDR(&msg);
  header = CMSG_NXTHDR(&msg, header);
  alg_iv = (void*)CMSG_DATA(header);
  uint64_t readSeq;
  unsigned char* readSeqNum = ssl->s3->read_sequence;
  memcpy(&readSeq, readSeqNum, sizeof(readSeq));
  memcpy(alg_iv->iv, &readSeq, 8);

  ret = sendmsg(opfd, &msg, MSG_MORE);
  if (ret < 0) {
    perror("sendmsg recv");
    exit(-1);
  }

  // Try some simple writes

  send(opfd, buf, 10, 0);
  send(opfd, buf, 100, 0);
  send(opfd, buf, 16000, 0);
  printf("Successful send\n");

  res = 0;
  total_recv = 0;

  res = recv(opfd, &buf, 1, 0);

  total_recv += res;
  if (res < 0) {
    printf("Ktls recv error: %i\n", res);
  }
  printf("Recvd ktls test data: %i %i\n", res, total_recv);

  start = clock();
  off_t offset = 0;


  filefd = open(test_data, O_RDONLY);

  res = sendfile(opfd, filefd, &offset, totalbytes);

  close(filefd);

  end = clock();
  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

  printf("ktls receive time: %.02f\n", cpu_time_used);

  SSL_free(ssl);
  close(server);
  SSL_CTX_free(ctx);
  return(0);
}

int OpenListener(int port)
{   int sd;
  struct sockaddr_in6 addr;

  sd = socket(PF_INET6, SOCK_STREAM, 0);
  bzero(&addr, sizeof(addr));
  addr.sin6_family = AF_INET6;
  addr.sin6_port = htons(port);
  memcpy(addr.sin6_addr.s6_addr, &in6addr_any, sizeof(in6addr_any));

  if ( bind(sd, (const struct sockaddr*)&addr, sizeof(addr)) != 0 )
    {
      perror("can't bind port");
      abort();
    }
  if ( listen(sd, 10) != 0 )
    {
      perror("Can't configure listening port");
      abort();
    }
  return sd;
}
int MAIN(int argc, char **argv)
{
    int off=0;
    SSL *con=NULL,*con2=NULL;
    X509_STORE *store = NULL;
    int s,k,width,state=0;
    char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
    int cbuf_len,cbuf_off;
    int sbuf_len,sbuf_off;
    fd_set readfds,writefds;
    short port=PORT;
    int full_log=1;
    char *host=SSL_HOST_NAME;
    char *cert_file=NULL,*key_file=NULL;
    int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
    char *passarg = NULL, *pass = NULL;
    X509 *cert = NULL;
    EVP_PKEY *key = NULL;
    char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
    int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
    int crlf=0;
    int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
    SSL_CTX *ctx=NULL;
    int ret=1,in_init=1,i,nbio_test=0;
    int starttls_proto = 0;
    int prexit = 0, vflags = 0;
    SSL_METHOD *meth=NULL;
#ifdef sock_type
#undef sock_type
#endif
    int sock_type=SOCK_STREAM;
    BIO *sbio;
    char *inrand=NULL;
#ifndef OPENSSL_NO_ENGINE
    char *engine_id=NULL;
    ENGINE *e=NULL;
#endif
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
    struct timeval tv;
#endif

    struct sockaddr peer;
    int peerlen = sizeof(peer);
    int enable_timeouts = 0 ;
    long mtu = 0;

#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
    meth=SSLv23_client_method();
#elif !defined(OPENSSL_NO_SSL3)
    meth=SSLv3_client_method();
#elif !defined(OPENSSL_NO_SSL2)
    meth=SSLv2_client_method();
#endif

    apps_startup();
    c_Pause=0;
    c_quiet=0;
    c_ign_eof=0;
    c_debug=0;
    c_msg=0;
    c_showcerts=0;

    if (bio_err == NULL)
        bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

    if (!load_config(bio_err, NULL))
        goto end;

    if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
            ((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
            ((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
    {
        BIO_printf(bio_err,"out of memory\n");
        goto end;
    }

    verify_depth=0;
    verify_error=X509_V_OK;
#ifdef FIONBIO
    c_nbio=0;
#endif

    argc--;
    argv++;
    while (argc >= 1)
    {
        if	(strcmp(*argv,"-host") == 0)
        {
            if (--argc < 1) goto bad;
            host= *(++argv);
        }
        else if	(strcmp(*argv,"-port") == 0)
        {
            if (--argc < 1) goto bad;
            port=atoi(*(++argv));
            if (port == 0) goto bad;
        }
        else if (strcmp(*argv,"-connect") == 0)
        {
            if (--argc < 1) goto bad;
            if (!extract_host_port(*(++argv),&host,NULL,&port))
                goto bad;
        }
        else if	(strcmp(*argv,"-verify") == 0)
        {
            verify=SSL_VERIFY_PEER;
            if (--argc < 1) goto bad;
            verify_depth=atoi(*(++argv));
            BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
        }
        else if	(strcmp(*argv,"-cert") == 0)
        {
            if (--argc < 1) goto bad;
            cert_file= *(++argv);
        }
        else if	(strcmp(*argv,"-certform") == 0)
        {
            if (--argc < 1) goto bad;
            cert_format = str2fmt(*(++argv));
        }
        else if	(strcmp(*argv,"-crl_check") == 0)
            vflags |= X509_V_FLAG_CRL_CHECK;
        else if	(strcmp(*argv,"-crl_check_all") == 0)
            vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
        else if	(strcmp(*argv,"-prexit") == 0)
            prexit=1;
        else if	(strcmp(*argv,"-crlf") == 0)
            crlf=1;
        else if	(strcmp(*argv,"-quiet") == 0)
        {
            c_quiet=1;
            c_ign_eof=1;
        }
        else if	(strcmp(*argv,"-ign_eof") == 0)
            c_ign_eof=1;
        else if	(strcmp(*argv,"-pause") == 0)
            c_Pause=1;
        else if	(strcmp(*argv,"-debug") == 0)
            c_debug=1;
#ifdef WATT32
        else if (strcmp(*argv,"-wdebug") == 0)
            dbug_init();
#endif
        else if	(strcmp(*argv,"-msg") == 0)
            c_msg=1;
        else if	(strcmp(*argv,"-showcerts") == 0)
            c_showcerts=1;
        else if	(strcmp(*argv,"-nbio_test") == 0)
            nbio_test=1;
        else if	(strcmp(*argv,"-state") == 0)
            state=1;
#ifndef OPENSSL_NO_SSL2
        else if	(strcmp(*argv,"-ssl2") == 0)
            meth=SSLv2_client_method();
#endif
#ifndef OPENSSL_NO_SSL3
        else if	(strcmp(*argv,"-ssl3") == 0)
            meth=SSLv3_client_method();
#endif
#ifndef OPENSSL_NO_TLS1
        else if	(strcmp(*argv,"-tls1") == 0)
            meth=TLSv1_client_method();
#endif
#ifndef OPENSSL_NO_DTLS1
        else if	(strcmp(*argv,"-dtls1") == 0)
        {
            meth=DTLSv1_client_method();
            sock_type=SOCK_DGRAM;
        }
        else if (strcmp(*argv,"-timeout") == 0)
            enable_timeouts=1;
        else if (strcmp(*argv,"-mtu") == 0)
        {
            if (--argc < 1) goto bad;
            mtu = atol(*(++argv));
        }
#endif
        else if (strcmp(*argv,"-bugs") == 0)
            bugs=1;
        else if	(strcmp(*argv,"-keyform") == 0)
        {
            if (--argc < 1) goto bad;
            key_format = str2fmt(*(++argv));
        }
        else if	(strcmp(*argv,"-pass") == 0)
        {
            if (--argc < 1) goto bad;
            passarg = *(++argv);
        }
        else if	(strcmp(*argv,"-key") == 0)
        {
            if (--argc < 1) goto bad;
            key_file= *(++argv);
        }
        else if	(strcmp(*argv,"-reconnect") == 0)
        {
            reconnect=5;
        }
        else if	(strcmp(*argv,"-CApath") == 0)
        {
            if (--argc < 1) goto bad;
            CApath= *(++argv);
        }
        else if	(strcmp(*argv,"-CAfile") == 0)
        {
            if (--argc < 1) goto bad;
            CAfile= *(++argv);
        }
        else if (strcmp(*argv,"-no_tls1") == 0)
            off|=SSL_OP_NO_TLSv1;
        else if (strcmp(*argv,"-no_ssl3") == 0)
            off|=SSL_OP_NO_SSLv3;
        else if (strcmp(*argv,"-no_ssl2") == 0)
            off|=SSL_OP_NO_SSLv2;
        else if (strcmp(*argv,"-serverpref") == 0)
            off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
        else if	(strcmp(*argv,"-cipher") == 0)
        {
            if (--argc < 1) goto bad;
            cipher= *(++argv);
        }
#ifdef FIONBIO
        else if (strcmp(*argv,"-nbio") == 0)
        {
            c_nbio=1;
        }
#endif
        else if	(strcmp(*argv,"-starttls") == 0)
        {
            if (--argc < 1) goto bad;
            ++argv;
            if (strcmp(*argv,"smtp") == 0)
                starttls_proto = 1;
            else if (strcmp(*argv,"pop3") == 0)
                starttls_proto = 2;
            else
                goto bad;
        }
#ifndef OPENSSL_NO_ENGINE
        else if	(strcmp(*argv,"-engine") == 0)
        {
            if (--argc < 1) goto bad;
            engine_id = *(++argv);
        }
#endif
        else if (strcmp(*argv,"-rand") == 0)
        {
            if (--argc < 1) goto bad;
            inrand= *(++argv);
        }
        else
        {
            BIO_printf(bio_err,"unknown option %s\n",*argv);
            badop=1;
            break;
        }
        argc--;
        argv++;
    }
    if (badop)
    {
bad:
        sc_usage();
        goto end;
    }

    OpenSSL_add_ssl_algorithms();
    SSL_load_error_strings();

#ifndef OPENSSL_NO_ENGINE
    e = setup_engine(bio_err, engine_id, 1);
#endif
    if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
    {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }

    if (key_file == NULL)
        key_file = cert_file;


    if (key_file)

    {

        key = load_key(bio_err, key_file, key_format, 0, pass, e,
                       "client certificate private key file");
        if (!key)
        {
            ERR_print_errors(bio_err);
            goto end;
        }

    }

    if (cert_file)

    {
        cert = load_cert(bio_err,cert_file,cert_format,
                         NULL, e, "client certificate file");

        if (!cert)
        {
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
            && !RAND_status())
    {
        BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
    }
    if (inrand != NULL)
        BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
                   app_RAND_load_files(inrand));

    if (bio_c_out == NULL)
    {
        if (c_quiet && !c_debug && !c_msg)
        {
            bio_c_out=BIO_new(BIO_s_null());
        }
        else
        {
            if (bio_c_out == NULL)
                bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
        }
    }

    ctx=SSL_CTX_new(meth);
    if (ctx == NULL)
    {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (bugs)
        SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
    else
        SSL_CTX_set_options(ctx,off);
    /* DTLS: partial reads end up discarding unread UDP bytes :-(
     * Setting read ahead solves this problem.
     */
    if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);

    if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
    if (cipher != NULL)
        if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
            BIO_printf(bio_err,"error setting cipher list\n");
            ERR_print_errors(bio_err);
            goto end;
        }
#if 0
        else
            SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
#endif

    SSL_CTX_set_verify(ctx,verify,verify_callback);
    if (!set_cert_key_stuff(ctx,cert,key))
        goto end;

    if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
            (!SSL_CTX_set_default_verify_paths(ctx)))
    {
        /* BIO_printf(bio_err,"error setting default verify locations\n"); */
        ERR_print_errors(bio_err);
        /* goto end; */
    }

    store = SSL_CTX_get_cert_store(ctx);
    X509_STORE_set_flags(store, vflags);

    con=SSL_new(ctx);
#ifndef OPENSSL_NO_KRB5
    if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)
    {
        kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
    }
#endif	/* OPENSSL_NO_KRB5  */
    /*	SSL_set_cipher_list(con,"RC4-MD5"); */

re_start:

    if (init_client(&s,host,port,sock_type) == 0)
    {
        BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
        SHUTDOWN(s);
        goto end;
    }
    BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);

#ifdef FIONBIO
    if (c_nbio)
    {
        unsigned long l=1;
        BIO_printf(bio_c_out,"turning on non blocking io\n");
        if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
        {
            ERR_print_errors(bio_err);
            goto end;
        }
    }
#endif
    if (c_Pause & 0x01) con->debug=1;

    if ( SSL_version(con) == DTLS1_VERSION)
    {
        struct timeval timeout;

        sbio=BIO_new_dgram(s,BIO_NOCLOSE);
        if (getsockname(s, &peer, (void *)&peerlen) < 0)
        {
            BIO_printf(bio_err, "getsockname:errno=%d\n",
                       get_last_socket_error());
            SHUTDOWN(s);
            goto end;
        }

        BIO_ctrl_set_connected(sbio, 1, &peer);

        if ( enable_timeouts)
        {
            timeout.tv_sec = 0;
            timeout.tv_usec = DGRAM_RCV_TIMEOUT;
            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);

            timeout.tv_sec = 0;
            timeout.tv_usec = DGRAM_SND_TIMEOUT;
            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
        }

        if ( mtu > 0)
        {
            SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
            SSL_set_mtu(con, mtu);
        }
        else
            /* want to do MTU discovery */
            BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
    }
    else
        sbio=BIO_new_socket(s,BIO_NOCLOSE);



    if (nbio_test)
    {
        BIO *test;

        test=BIO_new(BIO_f_nbio_test());
        sbio=BIO_push(test,sbio);
    }

    if (c_debug)
    {
        con->debug=1;
        BIO_set_callback(sbio,bio_dump_callback);
        BIO_set_callback_arg(sbio,bio_c_out);
    }
    if (c_msg)
    {
        SSL_set_msg_callback(con, msg_cb);
        SSL_set_msg_callback_arg(con, bio_c_out);
    }

    SSL_set_bio(con,sbio,sbio);
    SSL_set_connect_state(con);

    /* ok, lets connect */
    width=SSL_get_fd(con)+1;

    read_tty=1;
    write_tty=0;
    tty_on=0;
    read_ssl=1;
    write_ssl=1;

    cbuf_len=0;
    cbuf_off=0;
    sbuf_len=0;
    sbuf_off=0;

    /* This is an ugly hack that does a lot of assumptions */
    if (starttls_proto == 1)
    {
        BIO_read(sbio,mbuf,BUFSIZZ);
        BIO_printf(sbio,"STARTTLS\r\n");
        BIO_read(sbio,sbuf,BUFSIZZ);
    }
    if (starttls_proto == 2)
    {
        BIO_read(sbio,mbuf,BUFSIZZ);
        BIO_printf(sbio,"STLS\r\n");
        BIO_read(sbio,sbuf,BUFSIZZ);
    }

    for (;;)
    {
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);

        if (SSL_in_init(con) && !SSL_total_renegotiations(con))
        {
            in_init=1;
            tty_on=0;
        }
        else
        {
            tty_on=1;
            if (in_init)
            {
                in_init=0;
                print_stuff(bio_c_out,con,full_log);
                if (full_log > 0) full_log--;

                if (starttls_proto)
                {
                    BIO_printf(bio_err,"%s",mbuf);
                    /* We don't need to know any more */
                    starttls_proto = 0;
                }

                if (reconnect)
                {
                    reconnect--;
                    BIO_printf(bio_c_out,"drop connection and then reconnect\n");
                    SSL_shutdown(con);
                    SSL_set_connect_state(con);
                    SHUTDOWN(SSL_get_fd(con));
                    goto re_start;
                }
            }
        }

        ssl_pending = read_ssl && SSL_pending(con);

        if (!ssl_pending)
        {
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
            if (tty_on)
            {
                if (read_tty)  FD_SET(fileno(stdin),&readfds);
                if (write_tty) FD_SET(fileno(stdout),&writefds);
            }
            if (read_ssl)
                FD_SET(SSL_get_fd(con),&readfds);
            if (write_ssl)
                FD_SET(SSL_get_fd(con),&writefds);
#else
            if(!tty_on || !write_tty) {
                if (read_ssl)
                    FD_SET(SSL_get_fd(con),&readfds);
                if (write_ssl)
                    FD_SET(SSL_get_fd(con),&writefds);
            }
#endif
            /*			printf("mode tty(%d %d%d) ssl(%d%d)\n",
            				tty_on,read_tty,write_tty,read_ssl,write_ssl);*/

            /* Note: under VMS with SOCKETSHR the second parameter
             * is currently of type (int *) whereas under other
             * systems it is (void *) if you don't have a cast it
             * will choke the compiler: if you do have a cast then
             * you can either go for (int *) or (void *).
             */
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
            /* Under Windows/DOS we make the assumption that we can
            * always write to the tty: therefore if we need to
            		 * write to the tty we just fall through. Otherwise
            		 * we timeout the select every second and see if there
            		 * are any keypresses. Note: this is a hack, in a proper
            		 * Windows application we wouldn't do this.
            		 */
            i=0;
            if(!write_tty) {
                if(read_tty) {
                    tv.tv_sec = 1;
                    tv.tv_usec = 0;
                    i=select(width,(void *)&readfds,(void *)&writefds,
                             NULL,&tv);
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
                    if(!i && (!_kbhit() || !read_tty) ) continue;
#else
                    if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
#endif
                } else 	i=select(width,(void *)&readfds,(void *)&writefds,
                                     NULL,NULL);
            }
#elif defined(OPENSSL_SYS_NETWARE)
            if(!write_tty) {
                if(read_tty) {
                    tv.tv_sec = 1;
                    tv.tv_usec = 0;
                    i=select(width,(void *)&readfds,(void *)&writefds,
                             NULL,&tv);
                } else 	i=select(width,(void *)&readfds,(void *)&writefds,
                                     NULL,NULL);
            }
#else
            i=select(width,(void *)&readfds,(void *)&writefds,
                     NULL,NULL);
#endif
            if ( i < 0)
            {
                BIO_printf(bio_err,"bad select %d\n",
                           get_last_socket_error());
                goto shut;
                /* goto end; */
            }
        }

        if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
        {
            k=SSL_write(con,&(cbuf[cbuf_off]),
                        (unsigned int)cbuf_len);
            switch (SSL_get_error(con,k))
            {
            case SSL_ERROR_NONE:
                cbuf_off+=k;
                cbuf_len-=k;
                if (k <= 0) goto end;
                /* we have done a  write(con,NULL,0); */
                if (cbuf_len <= 0)
                {
                    read_tty=1;
                    write_ssl=0;
                }
                else /* if (cbuf_len > 0) */
                {
                    read_tty=0;
                    write_ssl=1;
                }
                break;
            case SSL_ERROR_WANT_WRITE:
                BIO_printf(bio_c_out,"write W BLOCK\n");
                write_ssl=1;
                read_tty=0;
                break;
            case SSL_ERROR_WANT_READ:
                BIO_printf(bio_c_out,"write R BLOCK\n");
                write_tty=0;
                read_ssl=1;
                write_ssl=0;
                break;
            case SSL_ERROR_WANT_X509_LOOKUP:
                BIO_printf(bio_c_out,"write X BLOCK\n");
                break;
            case SSL_ERROR_ZERO_RETURN:
                if (cbuf_len != 0)
                {
                    BIO_printf(bio_c_out,"shutdown\n");
                    goto shut;
                }
                else
                {
                    read_tty=1;
                    write_ssl=0;
                    break;
                }

            case SSL_ERROR_SYSCALL:
                if ((k != 0) || (cbuf_len != 0))
                {
                    BIO_printf(bio_err,"write:errno=%d\n",
                               get_last_socket_error());
                    goto shut;
                }
                else
                {
                    read_tty=1;
                    write_ssl=0;
                }
                break;
            case SSL_ERROR_SSL:
                ERR_print_errors(bio_err);
                goto shut;
            }
        }
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
        /* Assume Windows/DOS can always write */
        else if (!ssl_pending && write_tty)
#else
        else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
#endif
        {
#ifdef CHARSET_EBCDIC
            ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
#endif
            i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);

            if (i <= 0)
            {
                BIO_printf(bio_c_out,"DONE\n");
                goto shut;
                /* goto end; */
            }

            sbuf_len-=i;;
            sbuf_off+=i;
            if (sbuf_len <= 0)
            {
                read_ssl=1;
                write_tty=0;
            }
        }
        else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
        {
#ifdef RENEG
        { static int iiii; if (++iiii == 52) {
                    SSL_renegotiate(con);
                    iiii=0;
                }
            }
#endif
#if 1
            k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
#else
            /* Demo for pending and peek :-) */
            k=SSL_read(con,sbuf,16);
            {   char zbuf[10240];
                printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
            }
#endif

            switch (SSL_get_error(con,k))
            {
            case SSL_ERROR_NONE:
                if (k <= 0)
                    goto end;
                sbuf_off=0;
                sbuf_len=k;

                read_ssl=0;
                write_tty=1;
                break;
            case SSL_ERROR_WANT_WRITE:
                BIO_printf(bio_c_out,"read W BLOCK\n");
                write_ssl=1;
                read_tty=0;
                break;
            case SSL_ERROR_WANT_READ:
                BIO_printf(bio_c_out,"read R BLOCK\n");
                write_tty=0;
                read_ssl=1;
                if ((read_tty == 0) && (write_ssl == 0))
                    write_ssl=1;
                break;
            case SSL_ERROR_WANT_X509_LOOKUP:
                BIO_printf(bio_c_out,"read X BLOCK\n");
                break;
            case SSL_ERROR_SYSCALL:
                BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
                goto shut;
            case SSL_ERROR_ZERO_RETURN:
                BIO_printf(bio_c_out,"closed\n");
                goto shut;
            case SSL_ERROR_SSL:
                ERR_print_errors(bio_err);
                goto shut;
                /* break; */
            }
        }

#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
        else if (_kbhit())
#else
        else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
#endif
#elif defined (OPENSSL_SYS_NETWARE)
        else if (_kbhit())
#else
        else if (FD_ISSET(fileno(stdin),&readfds))
#endif
        {
            if (crlf)
            {
                int j, lf_num;

                i=read(fileno(stdin),cbuf,BUFSIZZ/2);
                lf_num = 0;
                /* both loops are skipped when i <= 0 */
                for (j = 0; j < i; j++)
                    if (cbuf[j] == '\n')
                        lf_num++;
                for (j = i-1; j >= 0; j--)
                {
                    cbuf[j+lf_num] = cbuf[j];
                    if (cbuf[j] == '\n')
                    {
                        lf_num--;
                        i++;
                        cbuf[j+lf_num] = '\r';
                    }
                }
                assert(lf_num == 0);
            }
            else
                i=read(fileno(stdin),cbuf,BUFSIZZ);

            if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
            {
                BIO_printf(bio_err,"DONE\n");
                goto shut;
            }

            if ((!c_ign_eof) && (cbuf[0] == 'R'))
            {
                BIO_printf(bio_err,"RENEGOTIATING\n");
                SSL_renegotiate(con);
                cbuf_len=0;
            }
            else
            {
                cbuf_len=i;
                cbuf_off=0;
#ifdef CHARSET_EBCDIC
                ebcdic2ascii(cbuf, cbuf, i);
#endif
            }

            write_ssl=1;
            read_tty=0;
        }
    }
shut:
    SSL_shutdown(con);
    SHUTDOWN(SSL_get_fd(con));
    ret=0;
end:
    if(prexit) print_stuff(bio_c_out,con,1);
    if (con != NULL) SSL_free(con);
    if (con2 != NULL) SSL_free(con2);
    if (ctx != NULL) SSL_CTX_free(ctx);
    if (cert)
        X509_free(cert);
    if (key)
        EVP_PKEY_free(key);
    if (pass)
        OPENSSL_free(pass);
    if (cbuf != NULL) {
        OPENSSL_cleanse(cbuf,BUFSIZZ);
        OPENSSL_free(cbuf);
    }
    if (sbuf != NULL) {
        OPENSSL_cleanse(sbuf,BUFSIZZ);
        OPENSSL_free(sbuf);
    }
    if (mbuf != NULL) {
        OPENSSL_cleanse(mbuf,BUFSIZZ);
        OPENSSL_free(mbuf);
    }
    if (bio_c_out != NULL)
    {
        BIO_free(bio_c_out);
        bio_c_out=NULL;
    }
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Exemple #23
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    SOCKET_T clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    int    port = yasslPort;
    int    usePsk = 0;
    int    doDTLS = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    char*  cipherList = NULL;
    char*  verifyCert = (char*)cliCert;
    char*  ourCert    = (char*)svrCert;
    char*  ourKey     = (char*)svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;

    while ((ch = mygetopt(argc, argv, "?dbstnNufp:v:l:A:c:k:S:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_CYASSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'p' :
                port = atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker(); 
#endif

    switch (version) {
#ifndef NO_OLD_TLS
        case 0:
            method = SSLv3_server_method();
            break;

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif
                
#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!usePsk) {
        if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " CyaSSL home dir");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && !usePsk) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");
    }
#endif

    if (usePsk) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #ifdef HAVE_NULL_CIPHER
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }
#endif

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName) {
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                                          XSTRLEN(sniHostName)))
            err_sys("UseSNI failed");
        else
            CyaSSL_CTX_SNI_SetOptions(ctx, CYASSL_SNI_HOST_NAME,
                                                  CYASSL_SNI_ABORT_ON_MISMATCH);
    }
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");
    CyaSSL_set_quiet_shutdown(ssl, 1) ;
#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
        osDelay(5000) ;
    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
    if (usePsk == 0) {
        #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
            CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
        #elif !defined(NO_CERTS)
            SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
        #endif
    }
        osDelay(5000) ;
#ifndef CYASSL_CALLBACKS
    if (nonBlocking) {
        CyaSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&clientfd);
        NonBlockingSSL_Accept(ssl);
    } else if (SSL_accept(ssl) != SSL_SUCCESS) {
        int err = SSL_get_error(ssl, 0);
        char buffer[80];
        printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
        err_sys("SSL_accept failed");
    }
#else
    NonBlockingSSL_Accept(ssl);
#endif
    showPeer(ssl);
        osDelay(5000) ;
    idx = SSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);

    }
    else if (idx < 0) {
        int readErr = SSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("SSL_read failed");
    }

    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");
        
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif /* USE_CYASSL_MEMORY */

    return 0;
}
Exemple #24
0
/* sock stream/TCP handler */
void ev_handler(int fd, short ev_flags, void *arg)
{
    int n = 0;
    if(ev_flags & E_READ)
    {
        if(is_use_ssl)
        {
#ifdef USE_SSL
            n = SSL_read(conns[fd].ssl, conns[fd].response, EV_BUF_SIZE - 1);
#else
            n = read(fd, conns[fd].response, EV_BUF_SIZE - 1);
#endif
        }
        else
        {
            n = read(fd, conns[fd].response, EV_BUF_SIZE - 1);
        }
        if(n > 0 )
        {
            SHOW_LOG("Read %d bytes from %d", n, fd);
            conns[fd].response[n] = 0;
            SHOW_LOG("Updating event[%p] on %d ", &conns[fd].event, fd);
            event_add(&conns[fd].event, E_WRITE);	
        }		
        else
        {
            if(n < 0 )
                FATAL_LOG("Reading from %d failed, %s", fd, strerror(errno));
            goto err;
        }
    }
    if(ev_flags & E_WRITE)
    {
        if(is_use_ssl)
        {
#ifdef USE_SSL
            n = SSL_write(conns[fd].ssl, conns[fd].request, strlen(conns[fd].request));
#else
            n = write(fd, conns[fd].request, strlen(conns[fd].request));
#endif
        }
        else
        {
            n = write(fd, conns[fd].request, strlen(conns[fd].request));
        }

        if(n > 0 )
        {
            SHOW_LOG("Wrote %d bytes via %d", n, fd);
        }
        else
        {
            if(n < 0)
                FATAL_LOG("Wrote data via %d failed, %s", fd, strerror(errno));	
            goto err;
        }
        event_del(&conns[fd].event, E_WRITE);
    }
    return ;
err:
    {
        event_destroy(&conns[fd].event);
        shutdown(fd, SHUT_RDWR);
        close(fd);
#ifdef USE_SSL
        if(conns[fd].ssl)
        {
            SSL_shutdown(conns[fd].ssl);
            SSL_free(conns[fd].ssl);
            conns[fd].ssl = NULL;
        }
#endif

        SHOW_LOG("Connection %d closed", fd);
    }
}
Exemple #25
0
void echoclient_test(void* args)
{
    SOCKET_T sockfd = 0;

    FILE* fin   = stdin  ;
    FILE* fout = stdout;

    int inCreated  = 0;
    int outCreated = 0;

    char msg[1024];
    char reply[1024+1];

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    int doDTLS = 0;
    int doPSK = 0;
    int sendSz;
    int argc    = 0;
    char** argv = 0;
    int port = yasslPort;

    ((func_args*)args)->return_code = -1; /* error state */
    
#ifndef CYASSL_MDK_SHELL
    argc = ((func_args*)args)->argc;
    argv = ((func_args*)args)->argv;
#endif

    if (argc >= 2) {
        fin  = fopen(argv[1], "r"); 
        inCreated = 1;
    }
    if (argc >= 3) {
        fout = fopen(argv[2], "w");
        outCreated = 1;
    }

    if (!fin)  err_sys("can't open input file");
    if (!fout) err_sys("can't open output file");

#ifdef CYASSL_DTLS
    doDTLS  = 1;
#endif

#ifdef CYASSL_LEANPSK 
    doPSK = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    doPSK = 1;
#endif

#if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_SHELL)
    port = ((func_args*)args)->signal->port;
#endif

#if defined(CYASSL_DTLS)
    method  = DTLSv1_client_method();
#elif  !defined(NO_TLS)
    method = CyaSSLv23_client_method();
#else
    method = SSLv3_client_method();
#endif
    ctx    = SSL_CTX_new(method);

#ifndef NO_FILESYSTEM
    #ifndef NO_RSA
    if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
        err_sys("can't load ca file, Please run from CyaSSL home dir");
    #endif
    #ifdef HAVE_ECC
        if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    #endif
#elif !defined(NO_CERTS)
    if (!doPSK)
        load_buffer(ctx, caCert, CYASSL_CA);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
#endif
    if (doPSK) {
#ifndef NO_PSK
        const char *defaultCipherList;

        CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
        #ifdef HAVE_NULL_CIPHER
            defaultCipherList = "PSK-NULL-SHA256";
        #else
            defaultCipherList = "PSK-AES128-CBC-SHA256";
        #endif
        if (CyaSSL_CTX_set_cipher_list(ctx,defaultCipherList) !=SSL_SUCCESS)
            err_sys("client can't set cipher list 2");
#endif
    }

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    #if defined(CYASSL_MDK_ARM)
    CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    #endif

    ssl = SSL_new(ctx);
        

    if (doDTLS) {
        SOCKADDR_IN_T addr;
        build_addr(&addr, yasslIP, port, 1);
        CyaSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
        tcp_socket(&sockfd, 1);
    }
    else {
        tcp_connect(&sockfd, yasslIP, port, 0);
    }
        
    SSL_set_fd(ssl, sockfd);
#if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER)
    /* let echoserver bind first, TODO: add Windows signal like pthreads does */
    Sleep(100);
#endif

    if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");

    while (fgets(msg, sizeof(msg), fin) != 0) {
     
        sendSz = (int)strlen(msg);

        if (SSL_write(ssl, msg, sendSz) != sendSz)
            err_sys("SSL_write failed");

        if (strncmp(msg, "quit", 4) == 0) {
            fputs("sending server shutdown command: quit!\n", fout);
            break;
        }

        if (strncmp(msg, "break", 5) == 0) {
            fputs("sending server session close: break!\n", fout);
            break;
        }

        #ifndef CYASSL_MDK_SHELL
        while (sendSz) {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply)-1)) > 0) {
                reply[got] = 0;
                fputs(reply, fout);
                fflush(fout) ;
                sendSz -= got;
            }
            else
                break;
        }
        #else
        {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply)-1)) > 0) {
                reply[got] = 0;
                fputs(reply, fout);
                fflush(fout) ;
                sendSz -= got;
            }
        }
        #endif
    }


#ifdef CYASSL_DTLS
    strncpy(msg, "break", 6);
    sendSz = (int)strlen(msg);
    /* try to tell server done */
    SSL_write(ssl, msg, sendSz);
#else
    SSL_shutdown(ssl);
#endif

    SSL_free(ssl);
    SSL_CTX_free(ctx);

    fflush(fout);
    if (inCreated)  fclose(fin);
    if (outCreated) fclose(fout);

    CloseSocket(sockfd);
    ((func_args*)args)->return_code = 0; 
}
Exemple #26
0
int main(int argc, char **argv)
{
    char *ip = NULL;
    int port = 0;
    int fd = 0;
    struct sockaddr_in sa, lsa;
    socklen_t sa_len, lsa_len = -1;
    int i = 0;
    int conn_num = 0;
    int sock_type = 0;
    int flag = 0;

    if(argc < 5)
    {
        fprintf(stderr, "Usage:%s sock_type(0/TCP|1/UDP) ip port connection_number\n", argv[0]);	
        _exit(-1);
    }	
    ev_sock_type = atoi(argv[1]);
    if(ev_sock_type < 0 || ev_sock_type > ev_sock_count)
    {
        fprintf(stderr, "sock_type must be 0/TCP OR 1/UDP\n");
        _exit(-1);
    }
    sock_type = ev_sock_list[ev_sock_type];
    ip = argv[2];
    port = atoi(argv[3]);
    conn_num = atoi(argv[4]);
    /* Set resource limit */
    setrlimiter("RLIMIT_NOFILE", RLIMIT_NOFILE, CONN_MAX);	
    /* Initialize global vars */
    if((conns = (CONN *)calloc(CONN_MAX, sizeof(CONN))))
    {
        //memset(events, 0, sizeof(EVENT *) * CONN_MAX);
        /* Initialize inet */ 
        memset(&sa, 0, sizeof(struct sockaddr_in));	
        sa.sin_family = AF_INET;
        sa.sin_addr.s_addr = inet_addr(ip);
        sa.sin_port = htons(port);
        sa_len = sizeof(struct sockaddr);
        /* set evbase */
        if((evbase = evbase_init(0)))
        {
            LOGGER_INIT(evbase->logger, "/tmp/ev_client.log");
#ifdef USE_SSL
            SSL_library_init();
            OpenSSL_add_all_algorithms();
            SSL_load_error_strings();
            if((ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
            {
                ERR_print_errors_fp(stdout);
                _exit(-1);
            }
#endif
            //evbase->set_evops(evbase, EOP_POLL);
            while((fd = socket(AF_INET, sock_type, 0)) > 0 && i < conn_num)
            {
                conns[fd].fd = fd;
                /* Connect */
                if(connect(fd, (struct sockaddr *)&sa, sa_len) != 0)
                {
                    FATAL_LOG("Connect to %s:%d failed, %s", ip, port, strerror(errno));
                    break;
                }
                if(is_use_ssl && sock_type == SOCK_STREAM)
                {
#ifdef USE_SSL
                    conns[fd].ssl = SSL_new(ctx);
                    if(conns[fd].ssl == NULL )
                    {
                        FATAL_LOG("new SSL with created CTX failed:%s\n",
                                ERR_reason_error_string(ERR_get_error()));
                        break;
                    }
                    if((ret = SSL_set_fd(conns[fd].ssl, fd)) == 0)
                    {
                        FATAL_LOG("add SSL to tcp socket failed:%s\n",
                                ERR_reason_error_string(ERR_get_error()));
                        break;
                    }
                    /* SSL Connect */
                    if(SSL_connect(conns[fd].ssl) < 0)
                    {
                        FATAL_LOG("SSL connection failed:%s\n",
                                ERR_reason_error_string(ERR_get_error()));
                        break;
                    }
#endif
                }
                /* set FD NON-BLOCK */
                flag = fcntl(fd, F_GETFL, 0);
                flag |= O_NONBLOCK;
                fcntl(fd, F_SETFL, flag);
                    if(sock_type == SOCK_STREAM)
                    {
                        event_set(&conns[fd].event, fd, E_READ|E_WRITE|E_PERSIST, 
                                (void *)&conns[fd].event, &ev_handler);
                    }
                    else
                    {
                        event_set(&conns[fd].event, fd, E_READ|E_WRITE|E_PERSIST, 
                                (void *)&conns[fd].event, &ev_udp_handler);
                    }
                    evbase->add(evbase, &conns[fd].event);
                    sprintf(conns[fd].request, "GET / HTTP/1.0\r\n\r\n");
                lsa_len = sizeof(struct sockaddr);
                memset(&lsa, 0, lsa_len);
                getsockname(fd, (struct sockaddr *)&lsa, &lsa_len);
                SHOW_LOG("%d:Connected to %s:%d via %d port:%d", i, ip, port, fd, ntohs(lsa.sin_port));
                i++;
            }
            while(1)
            {
                evbase->loop(evbase, 0, NULL);
                usleep(1000);
            }
            for(i = 0; i < CONN_MAX; i++)
            {
                    shutdown(conns[i].fd, SHUT_RDWR);
                    close(conns[i].fd);
                    event_destroy(&conns[i].event);
#ifdef USE_SSL
                if(conns[i].ssl)
                {
                    SSL_shutdown(conns[i].ssl);
                    SSL_free(conns[i].ssl); 
                }
#endif
            }
#ifdef USE_SSL
            ERR_free_strings();
            SSL_CTX_free(ctx);
#endif
        }
        free(conns);
    }
    return -1;
}
Exemple #27
0
/*
 * This test checks for the three basic operations:
 * - TLSSend
 * - TLSRecv
 * - TLSRecvLine
 * It is difficult to test each one separatedly, so we test all at once.
 * The test consists on establishing a connection to our child process and then
 * sending and receiving data. We switch between the original functions and the
 * mock functions.
 * We do not test SSL_new, SSL_accept and such because those will be covered by either
 * the client or server tests.
 */
static void test_TLSBasicIO(void)
{
    ASSERT_IF_NOT_INITIALIZED;
    RESET_STATUS;
    SSL *ssl = NULL;
    char output_buffer[] = "this is a buffer";
    int output_buffer_length = strlen(output_buffer);
    char input_buffer[4096];
    int result = 0;

    /*
     * Open a socket and establish a tcp connection.
     */
    struct sockaddr_in server_addr;
    int server = 0;

    memset(&server_addr, 0, sizeof(struct sockaddr_in));
    server = socket(AF_INET, SOCK_STREAM, 0);
    assert_int_not_equal(-1, server);
    server_addr.sin_family = AF_INET;
    /* We should not use inet_addr, but it is easier for this particular case. */
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(8035);

    /*
     * Connect
     */
    result = connect(server, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
    assert_int_not_equal(-1, result);
    /*
     * Create a SSL instance
     */
    ssl = SSL_new(SSLCLIENTCONTEXT);
    assert_true(ssl != NULL);
    SSL_set_fd(ssl, server);
    /*
     * Establish the TLS connection over the socket.
     */
    result = SSL_connect(ssl);
    assert_int_not_equal(-1, result);
    /*
     * Start testing. The first obvious thing to test is to send data.
     */
    result = TLSSend(ssl, output_buffer, output_buffer_length);
    assert_int_equal(result, output_buffer_length);
    /*
     * Good we sent data and the data was sent. Let's check what we get back
     * by using TLSRecv.
     */
    result = TLSRecv(ssl, input_buffer, output_buffer_length);
    assert_int_equal(output_buffer_length, result);

    input_buffer[output_buffer_length] = '\0';
    assert_string_equal(output_buffer, input_buffer);
    /*
     * Brilliant! We transmitted and received data using simple communication.
     * Let's try the line sending.
     */
    char output_line_buffer[] = "hello\ngoodbye\n";
    int output_line_buffer_length = strlen(output_line_buffer);
    char output_just_hello[] = "hello";
    int output_just_hello_length = strlen(output_just_hello);

    result = TLSSend(ssl, output_line_buffer, output_line_buffer_length);
    assert_int_equal(result, output_line_buffer_length);

    result = TLSRecvLine(ssl, input_buffer, output_line_buffer_length);
    /* The reply should be up to the first hello */
    assert_int_equal(result, output_just_hello_length);
    assert_string_equal(input_buffer, output_just_hello);

    /*
     * Basic check
     */
    USE_MOCK(SSL_write);
    USE_MOCK(SSL_read);
    assert_int_equal(0, TLSSend(ssl, output_buffer, 0));
    assert_int_equal(-1, TLSSend(ssl, output_buffer, output_buffer_length));
    assert_int_equal(-1, TLSRecv(ssl, input_buffer, output_buffer_length));
    RESET_STATUS;

    /*
     * Start replacing the functions inside to check that the logic works
     * We start by testing TLSSend, then TLSRead and at last TLSRecvLine.
     */
    USE_MOCK(SSL_write);
    SSL_WRITE_RETURN(0);
    assert_int_equal(0, TLSSend(ssl, output_buffer, output_buffer_length));
    USE_MOCK(SSL_get_shutdown);
    SSL_GET_SHUTDOWN_RETURN(1);
    assert_int_equal(0, TLSSend(ssl, output_buffer, output_buffer_length));
    SSL_WRITE_RETURN(-1);
    assert_int_equal(-1, TLSSend(ssl, output_buffer, output_buffer_length));

    USE_MOCK(SSL_read);
    SSL_READ_RETURN(0);
    SSL_GET_SHUTDOWN_RETURN(0);
    assert_int_equal(0, TLSRecv(ssl, input_buffer, output_buffer_length));
    SSL_GET_SHUTDOWN_RETURN(1);
    assert_int_equal(0, TLSRecv(ssl, input_buffer, output_buffer_length));
    SSL_READ_RETURN(-1);
    assert_int_equal(-1, TLSRecv(ssl, input_buffer, output_buffer_length));

    USE_ORIGINAL(SSL_write);
    SSL_READ_RETURN(0);
    assert_int_equal(-1, TLSRecvLine(ssl, input_buffer, output_buffer_length));
    SSL_READ_RETURN(-1);
    assert_int_equal(-1, TLSRecvLine(ssl, input_buffer, output_buffer_length));
    SSL_READ_RETURN(5);
    assert_int_equal(-1, TLSRecvLine(ssl, input_buffer, 10));
    SSL_READ_USE_BUFFER(output_line_buffer);
    assert_int_equal(5, TLSRecvLine(ssl, input_buffer, output_line_buffer_length));
    assert_string_equal(output_just_hello, input_buffer);

    result = SSL_shutdown(ssl);
    if (ssl)
    {
        SSL_free(ssl);
    }
    RESET_STATUS;
}
Exemple #28
0
//static void fetch_uri(const struct URI *uri)
static void * fetch_uri(void * arg)
{
  spdylay_session_callbacks callbacks;
  int fd;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  struct Request req;
  struct Connection connection;
  int rv;
  nfds_t npollfds = 1;
  struct pollfd pollfds[1];
  uint16_t spdy_proto_version;

  struct URI *uri = (struct URI *)arg;   // typecast void * back to proper type

  request_init(&req, uri);

  setup_spdylay_callbacks(&callbacks);

  /* Establish connection and setup SSL */
  fd = connect_to(req.host, req.port);
  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  if(ssl_ctx == NULL) {
    dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
  }
  init_ssl_ctx(ssl_ctx, &spdy_proto_version);
  ssl = SSL_new(ssl_ctx);
  if(ssl == NULL) {
    dief("SSL_new", ERR_error_string(ERR_get_error(), NULL));
  }
  /* To simplify the program, we perform SSL/TLS handshake in blocking
     I/O. */
  ssl_handshake(ssl, fd);

  connection.ssl = ssl;
  connection.want_io = IO_NONE;

  /* Here make file descriptor non-block */
  make_non_block(fd);
  set_tcp_nodelay(fd);

  printf("[INFO] SPDY protocol version = %d\n", spdy_proto_version);
  rv = spdylay_session_client_new(&connection.session, spdy_proto_version,
                                  &callbacks, &connection);
  if(rv != 0) {
    diec("spdylay_session_client_new", rv);
  }

  /* Submit the HTTP request to the outbound queue. */
  submit_request(&connection, &req);

  pollfds[0].fd = fd;
  ctl_poll(pollfds, &connection);

  /* Event loop */
  while(spdylay_session_want_read(connection.session) ||
        spdylay_session_want_write(connection.session)) {
    int nfds = poll(pollfds, npollfds, -1);
    if(nfds == -1) {
      dief("poll", strerror(errno));
    }
    if(pollfds[0].revents & (POLLIN | POLLOUT)) {
      exec_io(&connection);
    }
    if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
      die("Connection error");
    }
    ctl_poll(pollfds, &connection);
  }

  /* Resource cleanup */
  spdylay_session_del(connection.session);
  SSL_shutdown(ssl);
  SSL_free(ssl);
  SSL_CTX_free(ssl_ctx);
  shutdown(fd, SHUT_WR);
  close(fd);
  request_free(&req);
}
Exemple #29
0
int main(int argc, char *argv[])
{
	if(argc != 2)
	{
		printf("usage : %s <ipaddress>\n", argv[0]);
		return -1;
	}
	strcpy(server_address, argv[1]);
	sleep_us(500000);

	/*
	 * configure the client.
	 */
	if(client_configure(master_port, transmit_port, ssl_certificate, ssl_key) < 0)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "client configured");
		return -1;
	}
	printf("%-60s[\033[;32mOK\033[0m]\n", "client configured");
	sleep_us(500000);

	/* 
	 * initialize the SSL
	 */
	ctx_server = ssl_server_init(ssl_certificate, ssl_key);
	if(ctx_server == NULL)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "SSL server initialize");
		return -1;
	}
	ctx_client = ssl_client_init();
	if(ctx_client == NULL)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "SSL client initialize");
		return -1;
	}
	printf("%-60s[\033[;32mOK\033[0m]\n", "SSL initialize");
	sleep_us(500000);

	/*
	 * connect to the master server.
	 */
	char temp[MAXLINE];
	snprintf(temp, MAXLINE, "connect to master server: %s", argv[1]);
	int masterfd = client_connect(argv[1], master_port);
	if(masterfd == -1)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", temp);
		return -1;
	}
	sockaddr_in clientaddr;
	socklen_t len = sizeof(clientaddr);
	memset(&clientaddr, 0, len);
	getsockname(masterfd, (sockaddr*)&clientaddr, &len);
	inet_ntop(AF_INET, (void *)&clientaddr.sin_addr, ip_address, MAXLINE);

	printf("%-60s[\033[;32mOK\033[0m]\n", temp);
	sleep_us(500000);
	SSL *ssl = ssl_client(ctx_client, masterfd);
	if(ssl == NULL)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "ssl_client\n");
		return -1;
	}

	/*
	 * verify the executable client to judge if it's a fake one.
	 */
	char *ver_buf = file_verify(argv[0]);
	if(ver_buf == NULL)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "verify client");
		return -1;
	}
	int k = SSL_write(ssl, ver_buf, strlen(ver_buf));
	if( k != (int)strlen(ver_buf))
	{
		printf("SSL_write error\n");
		return -1;
	}
	k = SSL_read(ssl, temp, MAXLINE);
	if(k < 0)
	{
		printf("SSL_read error");
		return -1;
	}
	temp[k] = '\0';

	if(strcmp(temp, "verify client unsuccessfully") == 0)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "verify client");
		return -1;
	}
	free(ver_buf);

	sleep_us(500000);
	
	/*
	 * Listen to the transmit port to upload/download files
	 */
	
	snprintf(temp, MAXLINE, "listen to transmit port: %s", transmit_port);
	int listenfd = server_listen(transmit_port);
	if(listenfd == -1)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", temp);
		return -1;
	}
	printf("%-60s[\033[;32mOK\033[0m]\n", temp);
	sleep_us(500000);
	
	/*
	 * create transmit_thread to handle upload/download files request 
	 * from the slave server.
	 */
	
	pthread_t thread;
	int ret = pthread_create(&thread, NULL, transmit_thread, static_cast<void*>(new int(listenfd)));
	if(ret == 0)
	     printf("%-60s[\033[;32mOK\033[0m]\n", "transmit_thread create");
	else
	{
		printf("%-60s[\033[;31FAILED\033[0m]\n", "transmit_thread create");
		return -1;
	}
	
	/*
	 * initialize the download/upload mutex.
	 */
	pthread_mutex_init(&download_mutex, NULL);
	pthread_mutex_init(&upload_mutex, NULL);
	char command_line[MAXLINE];
	snprintf(cmd_line, MAXLINE,"%s:%s> ", argv[1], master_port);
	while(!stop)
	{
		printf(cmd_line);
		fflush(stdin);
		//read the command inputed by the user.
		fgets(command_line, MAXLINE, stdin);
		int len = strlen(command_line);
		if(command_line[len-1] == '\n')
			command_line[len-1] = '\0';
		command_parse(ssl, command_line);
	}
	
	SSL_shutdown(ssl); // send SSL/TLS close_notify */
	close(masterfd);

	SSL_free(ssl);
	SSL_CTX_free(ctx_server);
	SSL_CTX_free(ctx_client);
	return 0;
}
Exemple #30
0
static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
{
	STACK_OF(SSL_CIPHER) *ciphers;
	method_const SSL_METHOD *dtls_method;
	SSL_CIPHER *dtls_cipher;
	SSL *dtls_ssl;
	BIO *dtls_bio;

	if (!vpninfo->dtls_ctx) {
		dtls_method = DTLSv1_client_method();
		vpninfo->dtls_ctx = SSL_CTX_new(dtls_method);
		if (!vpninfo->dtls_ctx) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Initialise DTLSv1 CTX failed\n"));
			openconnect_report_ssl_errors(vpninfo);
			vpninfo->dtls_attempt_period = 0;
			return -EINVAL;
		}

		/* If we don't readahead, then we do short reads and throw
		   away the tail of data packets. */
		SSL_CTX_set_read_ahead(vpninfo->dtls_ctx, 1);

		if (!SSL_CTX_set_cipher_list(vpninfo->dtls_ctx, vpninfo->dtls_cipher)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Set DTLS cipher list failed\n"));
			SSL_CTX_free(vpninfo->dtls_ctx);
			vpninfo->dtls_ctx = NULL;
			vpninfo->dtls_attempt_period = 0;
			return -EINVAL;
		}
	}

	if (!vpninfo->dtls_session) {
		/* We're going to "resume" a session which never existed. Fake it... */
		vpninfo->dtls_session = SSL_SESSION_new();
		if (!vpninfo->dtls_session) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Initialise DTLSv1 session failed\n"));
			vpninfo->dtls_attempt_period = 0;
			return -EINVAL;
		}
		vpninfo->dtls_session->ssl_version = 0x0100; /* DTLS1_BAD_VER */
	}

	/* Do this every time; it may have changed due to a rekey */
	vpninfo->dtls_session->master_key_length = sizeof(vpninfo->dtls_secret);
	memcpy(vpninfo->dtls_session->master_key, vpninfo->dtls_secret,
	       sizeof(vpninfo->dtls_secret));

	vpninfo->dtls_session->session_id_length = sizeof(vpninfo->dtls_session_id);
	memcpy(vpninfo->dtls_session->session_id, vpninfo->dtls_session_id,
	       sizeof(vpninfo->dtls_session_id));

	dtls_ssl = SSL_new(vpninfo->dtls_ctx);
	SSL_set_connect_state(dtls_ssl);

	ciphers = SSL_get_ciphers(dtls_ssl);
	if (sk_SSL_CIPHER_num(ciphers) != 1) {
		vpn_progress(vpninfo, PRG_ERR, _("Not precisely one DTLS cipher\n"));
		SSL_CTX_free(vpninfo->dtls_ctx);
		SSL_free(dtls_ssl);
		SSL_SESSION_free(vpninfo->dtls_session);
		vpninfo->dtls_ctx = NULL;
		vpninfo->dtls_session = NULL;
		vpninfo->dtls_attempt_period = 0;
		return -EINVAL;
	}
	dtls_cipher = sk_SSL_CIPHER_value(ciphers, 0);

	/* Set the appropriate cipher on our session to be resumed */
	vpninfo->dtls_session->cipher = dtls_cipher;
	vpninfo->dtls_session->cipher_id = dtls_cipher->id;

	/* Add the generated session to the SSL */
	if (!SSL_set_session(dtls_ssl, vpninfo->dtls_session)) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("SSL_set_session() failed with old protocol version 0x%x\n"
			       "Are you using a version of OpenSSL older than 0.9.8m?\n"
			       "See http://rt.openssl.org/Ticket/Display.html?id=1751\n"
			       "Use the --no-dtls command line option to avoid this message\n"),
			     vpninfo->dtls_session->ssl_version);
		vpninfo->dtls_attempt_period = 0;
		return -EINVAL;
	}

	dtls_bio = BIO_new_socket(dtls_fd, BIO_NOCLOSE);
	/* Set non-blocking */
	BIO_set_nbio(dtls_bio, 1);
	SSL_set_bio(dtls_ssl, dtls_bio, dtls_bio);

	SSL_set_options(dtls_ssl, SSL_OP_CISCO_ANYCONNECT);

	vpninfo->new_dtls_ssl = dtls_ssl;

	return 0;
}