Esempio n. 1
0
static int
ssl_check_error(SSL *ssl, int ret)
{
	int error;

	error = SSL_get_error(ssl, ret);

	switch (error) {
	case SSL_ERROR_NONE:
		return (0);
	case SSL_ERROR_WANT_READ:
		pjdlog_debug(2, "SSL_ERROR_WANT_READ");
		return (-1);
	case SSL_ERROR_WANT_WRITE:
		pjdlog_debug(2, "SSL_ERROR_WANT_WRITE");
		return (-1);
	case SSL_ERROR_ZERO_RETURN:
		pjdlog_exitx(EX_OK, "Connection closed.");
	case SSL_ERROR_SYSCALL:
		ssl_log_errors();
		pjdlog_exitx(EX_TEMPFAIL, "SSL I/O error.");
	case SSL_ERROR_SSL:
		ssl_log_errors();
		pjdlog_exitx(EX_TEMPFAIL, "SSL protocol error.");
	default:
		ssl_log_errors();
		pjdlog_exitx(EX_TEMPFAIL, "Unknown SSL error (%d).", error);
	}
}
Esempio n. 2
0
static void
tls_exec_server(const char *user, int startfd, const char *privkey,
    const char *cert, int debuglevel)
{
	SSL_CTX *sslctx;
	SSL *ssl;
	int sockfd, tcpfd, ret;

	pjdlog_debug_set(debuglevel);
	pjdlog_prefix_set("[TLS sandbox] (server) ");
#ifdef HAVE_SETPROCTITLE
	setproctitle("[TLS sandbox] (server) ");
#endif

	sockfd = startfd;
	tcpfd = startfd + 1;

	SSL_load_error_strings();
	SSL_library_init();

	sslctx = SSL_CTX_new(TLSv1_server_method());
	if (sslctx == NULL)
		pjdlog_exitx(EX_TEMPFAIL, "SSL_CTX_new() failed.");

	SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

	ssl = SSL_new(sslctx);
	if (ssl == NULL)
		pjdlog_exitx(EX_TEMPFAIL, "SSL_new() failed.");

	if (SSL_use_RSAPrivateKey_file(ssl, privkey, SSL_FILETYPE_PEM) != 1) {
		ssl_log_errors();
		pjdlog_exitx(EX_CONFIG,
		    "SSL_use_RSAPrivateKey_file(%s) failed.", privkey);
	}

	if (SSL_use_certificate_file(ssl, cert, SSL_FILETYPE_PEM) != 1) {
		ssl_log_errors();
		pjdlog_exitx(EX_CONFIG, "SSL_use_certificate_file(%s) failed.",
		    cert);
	}

	if (sandbox(user, true, "proto_tls server") != 0)
		pjdlog_exitx(EX_CONFIG, "Unable to sandbox TLS server.");
	pjdlog_debug(1, "Privileges successfully dropped.");

	nonblock(sockfd);
	nonblock(tcpfd);

	if (SSL_set_fd(ssl, tcpfd) != 1)
		pjdlog_exitx(EX_TEMPFAIL, "SSL_set_fd() failed.");

	ret = SSL_accept(ssl);
	ssl_check_error(ssl, ret);

	tls_loop(sockfd, ssl);
}
Esempio n. 3
0
static X509* load_cert(const char* cert, size_t cert_size) {
  BIO* bio = BIO_new_mem_buf(const_cast<char*>(cert), cert_size);
  if (bio == NULL) {
    return NULL;
  }

  X509* x509 = PEM_read_bio_X509(bio, NULL, pem_password_callback, NULL);
  if (x509 == NULL) {
    ssl_log_errors("Unable to load certificate");
  }

  BIO_free_all(bio);

  return x509;
}
Esempio n. 4
0
static EVP_PKEY* load_key(const char* key,
                          size_t key_size,
                          const char* password) {
  BIO* bio = BIO_new_mem_buf(const_cast<char*>(key), key_size);
  if (bio == NULL) {
    return NULL;
  }

  EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bio,
                                           NULL,
                                           pem_password_callback,
                                           const_cast<char*>(password));
  if (pkey == NULL) {
    ssl_log_errors("Unable to load private key");
  }

  BIO_free_all(bio);

  return pkey;
}
Esempio n. 5
0
// This starts a new TCP/TLS connection to notblocked
// It is called both when a new local proxy connection is accepted
// and when we need to re-open an existing telex transport (state->local is reused)
void make_new_telex_conn(struct telex_state *state)
{
    struct telex_conf *conf = state->conf;

    HexDump(LOG_TRACE, state->name, "Opening telex id:", state->remote_conn_id, sizeof(state->remote_conn_id));

	state->remotetcp = bufferevent_socket_new(state->base, -1,
		BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
	if (!state->remotetcp) {
		LogError(state->name, "Could not create remote bufferevent socket");
		StateCleanup(&state);
		return;
	}
	_inc(BEV);

    // TODO: make nonblocking lookup?
    bufferevent_socket_connect_hostname(state->remotetcp, NULL, AF_INET, conf->notblocked_host, conf->notblocked_port);

    // After resolution...
    /*
    struct sockaddr_in sin;
    if (getpeername(bufferevent_getfd(state->remotetcp), (struct sockaddr *)&sin, (socklen_t*)sizeof(sin)) < 0) {
        perror("getpeername");
        LogError("proxy", "getpeername failed");
        StateCleanup(&state);
        return;
    }
    char ip_p[INET_ADDRSTRLEN];
    LogTrace(state->name, "Connecting to %s:%d",
             evutil_inet_ntop(AF_INET, server_ip, ip_p, sizeof(ip_p)), state->conf->notblocked_port);
    //bufferevent_socket_connect(state->remotetcp, ai->ai_addr, (int)ai->ai_addrlen);
    */

	if (ssl_new_telex(state) < 0) {
		ssl_log_errors(LOG_ERROR, state->name);
		LogError(state->name, "Could not create new telex SSL connection object");
		StateCleanup(&state);
		return;
	}
	_inc(SSL);

	state->remote = bufferevent_openssl_filter_new(state->base, state->remotetcp,
		state->ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS);
		// Not BEV_OPT_CLOSE_ON_FREE!
	if (!state->remote) {
		LogError(state->name, "Could not create remote SSL bufferevent filter");
		StateCleanup(&state);
		return;
	}
	_inc(BEV);

    // First, set our read_cb to something that receives the SPTelex init message
	bufferevent_setcb(state->remote, (bufferevent_data_cb)first_read_cb, NULL,
		(bufferevent_event_cb)event_cb, state);

    // Disable until SPTelex init msg
    bufferevent_disable(state->local, EV_READ|EV_WRITE);
	bufferevent_setcb(state->local, (bufferevent_data_cb)read_cb, NULL,
		(bufferevent_event_cb)event_cb, state);

    // Hmm...we should make a second one of these
    state->in_local = 0;
}