예제 #1
0
static int do_client(CLI *c) {
    int result;

    if(init_local(c))
        return -1;
    if(!options.option.client && !c->opt->protocol) {
        /* Server mode and no protocol negotiation needed */
        if(init_ssl(c))
            return -1;
        if(init_remote(c))
            return -1;
    } else {
        if(init_remote(c))
            return -1;
        if(negotiate(c)<0) {
            s_log(LOG_ERR, "Protocol negotiations failed");
            return -1;
        }
        if(init_ssl(c))
            return -1;
    }
    result=transfer(c);
    s_log(LOG_NOTICE,
        "Connection %s: %d bytes sent to SSL, %d bytes sent to socket",
         result ? "reset" : "closed", c->ssl_bytes, c->sock_bytes);
    return result;
}
예제 #2
0
파일: client.c 프로젝트: tricky1997/wifisec
static void client_try(CLI * c)
{
	init_local(c);
	if (!c->opt->option.client) {
		init_ssl(c);
		init_remote(c);
	} else {
		init_remote(c);
		init_ssl(c);
	}
	transfer(c);
}
예제 #3
0
파일: client.c 프로젝트: l7s/stunnel
static void do_client(CLI *c) {
    init_local(c);
    if(!c->opt->option.client && !c->opt->protocol) {
        /* server mode and no protocol negotiation needed */
        init_ssl(c);
        init_remote(c);
    } else {
        init_remote(c);
        negotiate(c);
        init_ssl(c);
    }
    transfer(c);
}
예제 #4
0
파일: client.c 프로젝트: nmacs/lm3s-uclinux
static void client_try(CLI *c) {
    init_local(c);
    if(!c->opt->option.client && c->opt->protocol<0) {
        /* server mode and no protocol negotiation needed */
        init_ssl(c);
        init_remote(c);
    } else {
        protocol(c, PROTOCOL_PRE_CONNECT);
        init_remote(c);
        protocol(c, PROTOCOL_PRE_SSL);
        init_ssl(c);
        protocol(c, PROTOCOL_POST_SSL);
    }
    transfer(c);
}
예제 #5
0
apr_status_t
sspdy_create_tls_connection(sspdy_connection_t ** conn,
                            sspdy_config_store_t *config_store,
                            const char *hostname, apr_port_t port,
                            apr_pool_t *pool)
{
    tls_conn_ctx_t *ctx;
    apr_status_t status;

    ctx = apr_pcalloc(pool, sizeof(tls_conn_ctx_t));
    ctx->pool = pool;
    ctx->config_store = config_store;

    STATUSERR(sspdy_connect(&ctx->skt, hostname, port, pool));

    ctx->ssl_ctx = init_ssl(pool, "spdy/3", ctx->skt, hostname);
    STATUSERR(sspdy_create_buf_bucket(&ctx->out_stream, ssl_socket_read,
                                      ssl_socket_write, ctx->ssl_ctx,
                                      pool));

    *conn = apr_palloc(pool, sizeof(sspdy_connection_t));
    (*conn)->type = &sspdy_connection_type_tls;
    (*conn)->data = ctx;

    return APR_SUCCESS;
}
예제 #6
0
int send_to_server(gpgme_data_t key, char *host, unsigned short port, GPG_CTX *gpg_ctx)
{
	SSL_CTX *ssl_ctx;
	SSL *ssl;
	int sock;

	// connect to server
	init_ssl(&ssl_ctx, &ssl, NULL, NULL);
	sock = create_client_socket(host, port, ssl);
	if (sock < 0)
		return ERROR_SOCKET;

	// C -> S: REG|public key
	// opcode
	SSL_write(ssl, OP_CONNECT, OP_LENGTH);

	// public key
	uint64_t key_length_net;
	size_t key_length_var;
	char *key_buf;
	key_buf = gpgme_data_release_and_get_mem(key, &key_length_var);
	if (key_buf == NULL)
		error_ret("Failed to copy key data\n", ERROR_GPGME);

	// length|data
	key_length_net = htobe64(key_length_var);
	SSL_write(ssl, &key_length_net, sizeof key_length_net);
	SSL_write(ssl, key_buf, key_length_var);

	// TODO: receive challenge from server

	UNUSED(gpg_ctx);

	return ERROR_NO_ERROR;
}
예제 #7
0
파일: main.c 프로젝트: millken/zhuxianB30
int
main(int argc, char **argv)
{
	thread thread_obj;

	/* Allocate the room */
	req = (REQ *) MALLOC(sizeof (REQ));

	/* Command line parser */
	if (!parse_cmdline(argc, argv, req)) {
		FREE(req);
		exit(0);
	}

	/* Check minimum configuration need */
	if (!req->addr_ip && !req->addr_port && !req->url) {
		FREE(req);
		exit(0);
	}

	/* Init the reference timer */
	req->ref_time = timer_tol(timer_now());
	DBG("Reference timer = %lu\n", req->ref_time);

	/* Init SSL context */
	init_ssl();

	/* Signal handling initialization  */
	signal_init();

	/* Create the master thread */
	master = thread_make_master();

	/* Register the GET request */
	init_sock();

	/*
	 * Processing the master thread queues,
	 * return and execute one ready thread.
	 * Run until error, used for debuging only.
	 * Note that not calling launch_scheduler() does
	 * not activate SIGCHLD handling, however, this
	 * is no issue here.
	 */
	while (thread_fetch(master, &thread_obj))
		thread_call(&thread_obj);

	/* Finalize output informations */
	if (req->verbose)
		printf("Global response time for [%s] =%lu\n",
		       req->url, req->response_time - req->ref_time);

	/* exit cleanly */
	SSL_CTX_free(req->ctx);
	free_sock(sock);
	FREE(req);
	exit(0);
}
예제 #8
0
NOEXPORT void client_try(CLI *c) {
    init_local(c);
    if(!c->opt->option.client && c->opt->protocol<0
#ifndef OPENSSL_NO_TLSEXT
            && !c->opt->servername_list_head
#endif
            ) {
        /* server mode and no protocol negotiation needed */
        init_ssl(c);
        init_remote(c);
    } else { /* client mode or protocol negotiation enabled */
        protocol(c, PROTOCOL_PRE_CONNECT);
        init_remote(c);
        protocol(c, PROTOCOL_PRE_SSL);
        init_ssl(c);
        protocol(c, PROTOCOL_POST_SSL);
    }
    transfer(c);
}
예제 #9
0
static void
regress_bufferevent_openssl(void *arg)
{
	struct basic_test_data *data = arg;

	struct bufferevent *bev1, *bev2;
	SSL *ssl1, *ssl2;
	X509 *cert = getcert();
	EVP_PKEY *key = getkey();
	const int start_open = strstr((char*)data->setup_data, "open")!=NULL;
	const int filter = strstr((char*)data->setup_data, "filter")!=NULL;
	int flags = BEV_OPT_DEFER_CALLBACKS;
	struct bufferevent *bev_ll[2] = { NULL, NULL };
	evutil_socket_t *fd_pair = NULL;

	tt_assert(cert);
	tt_assert(key);

	init_ssl();

	if (strstr((char*)data->setup_data, "renegotiate")) {
		if (SSLeay() >= 0x10001000 &&
		    SSLeay() <  0x1000104f) {
			/* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2
			 * can't renegotiate with themselves. Disable. */
			disable_tls_11_and_12 = 1;
		}
		renegotiate_at = 600;
	}

	ssl1 = SSL_new(get_ssl_ctx());
	ssl2 = SSL_new(get_ssl_ctx());

	SSL_use_certificate(ssl2, cert);
	SSL_use_PrivateKey(ssl2, key);

	if (! start_open)
		flags |= BEV_OPT_CLOSE_ON_FREE;

	if (!filter) {
		tt_assert(strstr((char*)data->setup_data, "socketpair"));
		fd_pair = data->pair;
	} else {
		bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0],
		    BEV_OPT_CLOSE_ON_FREE);
		bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1],
		    BEV_OPT_CLOSE_ON_FREE);
	}

	open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2,
	    fd_pair, bev_ll);

	if (!filter) {
		tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]);
	} else {
예제 #10
0
파일: global.c 프로젝트: stewid/libgit2
int git_libgit2_init(void)
{
	static int ssl_inited = 0;

	if (!ssl_inited) {
		init_ssl();
		ssl_inited = 1;
	}

	return git_atomic_inc(&git__n_inits);
}
예제 #11
0
파일: global.c 프로젝트: DaneTheory/libgit2
int git_threads_init(void)
{
	static int ssl_inited = 0;

	if (!ssl_inited) {
		init_ssl();
		ssl_inited = 1;
	}

	git_atomic_inc(&git__n_inits);
	return 0;
}
예제 #12
0
static apr_status_t ssl_reset(serv_ctx_t *serv_ctx)
{
    ssl_context_t *ssl_ctx = serv_ctx->ssl_ctx;

    serf__log(TEST_VERBOSE, __FILE__, "Reset ssl context.\n");

    ssl_ctx->handshake_done = 0;
    if (ssl_ctx)
        SSL_clear(ssl_ctx->ssl);
    init_ssl(serv_ctx);

    return APR_SUCCESS;
}
예제 #13
0
/*
  mca_network_init (MCACnxn *cnxn)
  
  Completes initialization of MCACnxn 

  exec_net_cmd      --- callback used when network command is executed
  net_status_report --- callback for reporting connection status

  //ideally should also validate other cnxn members  

  returns value > 1 if successful
 */
gint32 
mca_network_init (MCACnxn *cnxn, cmd_callback_t exec_net_cmd, status_callback_t net_status_report)
{
  gint32 retval = 1; 
  
  cnxn->cmd_cb = exec_net_cmd;
  cnxn->status_cb = net_status_report;
  cnxn->retrysec = 3;  //retry connecting every 3 seconds
  if (!cnxn->port)
    cnxn->port = 2999;

	init_ssl("CA.pem", "cert.pem", cnxn->cert_passwd, cnxn->uses_ssl, &retval);

  return retval;
}
예제 #14
0
static void
regress_bufferevent_openssl(void *arg)
{
	struct basic_test_data *data = arg;

	struct bufferevent *bev1, *bev2;
	SSL *ssl1, *ssl2;
	X509 *cert = getcert();
	EVP_PKEY *key = getkey();
	const int start_open = strstr((char*)data->setup_data, "open")!=NULL;
	const int filter = strstr((char*)data->setup_data, "filter")!=NULL;
	int flags = BEV_OPT_DEFER_CALLBACKS;
	struct bufferevent *bev_ll[2] = { NULL, NULL };
	int *fd_pair = NULL;

	tt_assert(cert);
	tt_assert(key);

	init_ssl();

	ssl1 = SSL_new(get_ssl_ctx());
	ssl2 = SSL_new(get_ssl_ctx());

	SSL_use_certificate(ssl2, cert);
	SSL_use_PrivateKey(ssl2, key);

	if (! start_open)
		flags |= BEV_OPT_CLOSE_ON_FREE;

	if (strstr((char*)data->setup_data, "renegotiate"))
		renegotiate_at = 600;

	if (!filter) {
		tt_assert(strstr((char*)data->setup_data, "socketpair"));
		fd_pair = data->pair;
	} else {
		bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0],
		    BEV_OPT_CLOSE_ON_FREE);
		bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1],
		    BEV_OPT_CLOSE_ON_FREE);
	}

	open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2,
	    fd_pair, bev_ll);

	if (!filter) {
		tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]);
	} else {
예제 #15
0
파일: ne_socket.c 프로젝트: dveeden/Prestan
int ne_sock_init(void)
{
#ifdef WIN32
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
#endif

    if (init_result > 0) 
	return 0;
    else if (init_result < 0)
	return -1;

#ifdef WIN32    
    wVersionRequested = MAKEWORD(2, 2);
    
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
	init_result = -1;
	return -1;
    }

#endif

#ifdef NEON_SOCKS
    SOCKSinit("neon");
#endif

#if defined(HAVE_SIGNAL) && defined(SIGPIPE)
    (void) signal(SIGPIPE, SIG_IGN);
#endif

#ifdef USE_GETADDRINFO
    init_ipv6();
#endif

#ifdef NEON_SSL
    if (init_ssl()) {
	NE_DEBUG(NE_DBG_SOCKET, "SSL initialization failed; lacking PRNG?\n");
	init_result = -1;
	return -1;
    }
    prng_seeded = 1;
#endif

    init_result = 1;
    return 0;
}
예제 #16
0
파일: test_jwk.c 프로젝트: memre/jose-c
int main(void)
{
    int number_failed;
    Suite *s;
    SRunner *sr;

    s = jwk_suite();
    sr = srunner_create(s);

    init_ssl();
    //srunner_set_fork_status (sr, CK_NOFORK);
    srunner_run_all(sr, CK_NORMAL);
    number_failed = srunner_ntests_failed(sr);
    srunner_free(sr);
    return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
예제 #17
0
파일: global.c 프로젝트: DonkeyWs/libgit2
static void init_once(void)
{
	if ((init_error = git_mutex_init(&git__mwindow_mutex)) != 0)
		return;
	pthread_key_create(&_tls_key, &cb__free_status);


	/* Initialize any other subsystems that have global state */
	if ((init_error = git_hash_global_init()) >= 0)
		init_error = git_sysdir_global_init();

	/* OpenSSL needs to be initialized from the main thread */
	init_ssl();

	GIT_MEMORY_BARRIER;
}
예제 #18
0
파일: glib-util.c 프로젝트: code-mx/amanda
void
glib_init(void) {
    static gboolean did_glib_init = FALSE;
    if (did_glib_init) return;
    did_glib_init = TRUE;

    /* set up libcurl (this must happen before threading 
     * is initialized) */
#ifdef HAVE_LIBCURL
# ifdef G_THREADS_ENABLED
    if (glib_major_version < 2 ||
	(glib_major_version == 2 && glib_minor_version < 31))
	g_assert(!g_thread_supported()); /* assert threads aren't initialized yet */
# endif
    g_assert(curl_global_init(CURL_GLOBAL_ALL) == 0);
#endif

    /* do a version check */
#if GLIB_CHECK_VERSION(2,6,0)
    {
	const char *glib_err = glib_check_version(GLIB_MAJOR_VERSION,
						  GLIB_MINOR_VERSION,
						  GLIB_MICRO_VERSION);
	if (glib_err) {
	    error(_("%s: Amanda was compiled with glib-%d.%d.%d, but linking with %d.%d.%d"), glib_err,
		    GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION,
		    glib_major_version, glib_minor_version, glib_micro_version);
	    exit(1); /* glib_init may be called before error handling is set up */
	}
    }
#endif

    /* Initialize glib's type system.  On glib >= 2.24, this will initialize
     * threads, so it must be done after curl is initialized. */
    g_type_init();

    /* And set up glib's threads */
#if defined(G_THREADS_ENABLED) && !defined(G_THREADS_IMPL_NONE)
    if (!g_thread_supported())
	g_thread_init(NULL);
#endif

    /* initialize ssl */
    init_ssl();

}
예제 #19
0
파일: sinsp_curl.cpp 프로젝트: djc2k/sysdig
void sinsp_curl::init()
{
	if(!m_curl)
	{
		throw sinsp_exception("Cannot initialize CURL.");
	}

	check_error(curl_easy_setopt(m_curl, CURLOPT_FORBID_REUSE, 1L));

	if(m_ssl)
	{
		init_ssl(m_curl, m_ssl);
	}

	if(m_bt)
	{
		init_bt(m_curl, m_bt);
	}

	enable_debug(m_curl, m_debug);
}
예제 #20
0
/**
 * Initialize open SSL engine
 * Returns valid SSL context or null if failed to create it.
 */
SSLWrapper* SSLWrapper_new(enum MethodType type)
{
    init_ssl();

    SSL_METHOD *method;
    SSL_CTX *ctx;

    if (type == Server) {
        method = SSLv2_server_method();     
    }
    else if (type == Client) {
        method = SSLv2_client_method();
    }
    else {
#ifdef DEBUG_OUTPUT
        fprintf(stderr, "Invalid method type received %d\n", type);
#endif
        return NULL;
    }

    ctx = SSL_CTX_new(method);

    if (ctx == NULL) {
#ifdef DEBUG_OUTPUT
        ERR_print_errors_fp(stderr);
#endif
    }

    SSLWrapper *wrapper = (SSLWrapper *)malloc(sizeof(SSLWrapper));
    wrapper->ctx = ctx;
    wrapper->ssl = NULL;
    wrapper->type = type;
    wrapper->state_set = 0;
    wrapper->sock_fd = 0;

    return wrapper;
}
예제 #21
0
	bool httpclient::open(const lyramilk::data::string& rawurl)
	{
		int port = -1;
		lyramilk::data::string scheme;
		{
			std::size_t scheme_sep = rawurl.find(":");
			if(scheme_sep != rawurl.npos && rawurl.size() > scheme_sep+2 && rawurl.compare(scheme_sep,3,"://") == 0){
				scheme = rawurl.substr(0,scheme_sep);
				std::size_t host_sep = rawurl.find("/",scheme_sep+3);
				host = rawurl.substr(scheme_sep+3,host_sep - scheme_sep - 3);
				std::size_t port_sep = host.find_last_of(":");
				if(port_sep != host.npos){
					char *tmp;
					port = strtoll(host.c_str() + port_sep + 1,&tmp,10);
					host = host.substr(0,port_sep);
				}
				url = rawurl.substr(host_sep);
			}
		}

		if(scheme == "https"){
			if(port == -1) port = 443;
		}else if(scheme == "http"){
			if(port == -1) port = 80;
		}else{
			return false;	
		}

		if(scheme == "https"){
			init_ssl();
			ssl(true);
		}

COUT << "raw=" << rawurl << ",scheme=" << scheme << ",host=" << host << ",port=" << port << ",url=" << url << "," << std::endl;
		return lyramilk::netio::client::open(host.c_str(),(lyramilk::data::uint16)port);
	}
예제 #22
0
/*
 * Setup to handle new incoming connections
 */
static void
ssl_accept(
    const struct security_driver *driver,
    char *	(*conf_fn)(char *, void *),
    int		in,
    int		out,
    void	(*fn)(security_handle_t *, pkt_t *),
    void       *datap)
{
    sockaddr_union sin;
    socklen_t_equiv len = sizeof(struct sockaddr);
    struct tcp_conn *rc;
    char hostname[NI_MAXHOST];
    int result;
    char *errmsg = NULL;
    int   err;
    X509 *remote_cert;
    char *str;
    X509_NAME *x509_name;
    char *cert_hostname;
    SSL_CTX            *ctx;
    SSL                *ssl;
    int loc;
    char *ssl_dir = getconf_str(CNF_SSL_DIR);
    char *ssl_fingerprint_file = conf_fn("ssl_fingerprint_file", datap);
    char *ssl_cert_file        = conf_fn("ssl_cert_file", datap);
    char *ssl_key_file         = conf_fn("ssl_key_file", datap);
    char *ssl_ca_cert_file     = conf_fn("ssl_ca_cert_file", datap);
    char *ssl_cipher_list      = conf_fn("ssl_cipher_list", datap);
    int   ssl_check_host       = atoi(conf_fn("ssl_check_host", datap));
    int   ssl_check_certificate_host = atoi(conf_fn("ssl_check_certificate_host", datap));

    if (getpeername(in, (struct sockaddr *)&sin, &len) < 0) {
	g_debug(_("getpeername returned: %s"), strerror(errno));
	return;
    }
    if ((result = getnameinfo((struct sockaddr *)&sin, len,
			      hostname, NI_MAXHOST, NULL, 0, 0) != 0)) {
	g_debug(_("getnameinfo failed: %s"),
		  gai_strerror(result));
	return;
    }

    if (ssl_check_host && check_name_give_sockaddr(hostname,
				 (struct sockaddr *)&sin, &errmsg) < 0) {
	amfree(errmsg);
	return;
    }

    if (ssl_dir) {
	if (!ssl_cert_file || ssl_cert_file == '\0') {
	    ssl_cert_file = g_strdup_printf("%s/me/crt.pem", ssl_dir);
	}
	if (!ssl_key_file || ssl_key_file == '\0') {
	    ssl_key_file = g_strdup_printf("%s/me/private/key.pem", ssl_dir);
	}
	if (!ssl_ca_cert_file || ssl_ca_cert_file == '\0') {
	    ssl_ca_cert_file = g_strdup_printf("%s/CA/crt.pem", ssl_dir);
	}
    }

    if (!ssl_cert_file) {
	g_debug(_("ssl-cert-file must be set in amanda-remote.conf"));
	return;
    }

    if (!ssl_key_file) {
	g_debug(_("ssl-key-file must be set in amanda-remote.conf"));
	return;
    }

    if (!ssl_ca_cert_file) {
	g_debug(_("ssl_ca_cert_file must be set in amanda-remote.conf"));
	return;
    }

    len = sizeof(sin);
    init_ssl();

    /* Create a SSL_CTX structure */
    ctx = SSL_CTX_new(SSLv3_server_method());
    if (!ctx) {
	g_debug(_("SSL_CTX_new failed: %s"),
		 ERR_error_string(ERR_get_error(), NULL));
	return;
    }
    SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);

    if (ssl_cipher_list) {
	g_debug("Set ssl_cipher_list to %s", ssl_cipher_list);
	if (SSL_CTX_set_cipher_list(ctx, ssl_cipher_list) == 0) {
	    g_debug(_("SSL_CTX_set_cipher_list failed: %s"),
		     ERR_error_string(ERR_get_error(), NULL));
	    return;
	}
    }

    /* Load the me certificate into the SSL_CTX structure */
    g_debug(_("Loading ssl-cert-file certificate %s"), ssl_cert_file);
    if (SSL_CTX_use_certificate_file(ctx, ssl_cert_file,
				     SSL_FILETYPE_PEM) <= 0) {
	g_debug(_("Load ssl-cert-file failed: %s"),
		 ERR_error_string(ERR_get_error(), NULL));
	return;
    }

    /* Load the private-key corresponding to the me certificate */
    g_debug(_("Loading ssl-key-file private-key %s"), ssl_key_file);
    if (SSL_CTX_use_PrivateKey_file(ctx, ssl_key_file,
				    SSL_FILETYPE_PEM) <= 0) {
	g_debug(_("Load ssl-key-file failed: %s"),
		 ERR_error_string(ERR_get_error(), NULL));
	return;
    }

    if (ssl_ca_cert_file) {
        /* Load the RSA CA certificate into the SSL_CTX structure */
	g_debug(_("Loading ssl-ca-cert-file ca certificate %s"),
		 ssl_ca_cert_file);
        if (!SSL_CTX_load_verify_locations(ctx, ssl_ca_cert_file, NULL)) {
	    g_debug(_("Load ssl-ca-cert-file failed: %s"),
		     ERR_error_string(ERR_get_error(), NULL));
	    return;
        }

	/* Set to require peer (remote) certificate verification */
	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

	/* Set the verification depth to 1 */
	SSL_CTX_set_verify_depth(ctx,1);
    }

    ssl = SSL_new(ctx);
    if (!ssl) {
	g_debug(_("SSL_new failed: %s"),
		 ERR_error_string(ERR_get_error(), NULL));
	return;
    }
    SSL_set_accept_state(ssl);

    /* Assign the socket into the SSL structure (SSL and socket without BIO) */
    SSL_set_fd(ssl, in);

    /* Perform SSL Handshake on the SSL me */
    err = SSL_accept(ssl);
    if (err == -1) {
	g_debug(_("SSL_accept failed: %s"),
		 ERR_error_string(ERR_get_error(), NULL));
	return;
    }

    /* Get the me's certificate (optional) */
    remote_cert = SSL_get_peer_certificate (ssl);

    if (remote_cert == NULL) {
	g_debug(_("remote doesn't sent a certificate"));
	return;
    }

    x509_name = X509_get_subject_name(remote_cert);
    str = X509_NAME_oneline(X509_get_subject_name(remote_cert), 0, 0);
    auth_debug(1, _("\t subject: %s\n"), str);
    amfree (str);

    str = X509_NAME_oneline(X509_get_issuer_name(remote_cert), 0, 0);
    auth_debug(1, _("\t issuer: %s\n"), str);
    amfree(str);

    loc = -1;
    loc = X509_NAME_get_index_by_NID(x509_name, NID_commonName, loc);
    if (loc != -1) {
	X509_NAME_ENTRY *x509_entry = X509_NAME_get_entry(x509_name, loc);
	ASN1_STRING *asn1_string = X509_NAME_ENTRY_get_data(x509_entry);
	cert_hostname = (char *)ASN1_STRING_data(asn1_string);
	auth_debug(1, "common_name: %s\n", cert_hostname);

	if (ssl_check_certificate_host &&
	    check_name_give_sockaddr((char*)cert_hostname,
			 (struct sockaddr *)&sin, &errmsg) < 0) {
	    g_debug("Common name of certicate (%s) doesn't resolv to IP (%s)", cert_hostname, str_sockaddr(&sin));
	    amfree(errmsg);
	    X509_free(remote_cert);
	    return;
	}
    } else {
	g_debug("Certificate have no common name");
	X509_free(remote_cert);
	return;
    }

    if (ssl_dir) {
	if (!ssl_fingerprint_file || ssl_fingerprint_file == '\0') {
	    struct stat  statbuf;
	    ssl_fingerprint_file = g_strdup_printf("%s/remote/%s/fingerprint", ssl_dir, cert_hostname);
	    if (stat(ssl_fingerprint_file, &statbuf) == -1) {
		g_free(ssl_fingerprint_file);
		ssl_fingerprint_file = NULL;
	    }
	}
    }

    if (ssl_fingerprint_file) {
        g_debug(_("Loading ssl-fingerprint-file %s"), ssl_fingerprint_file);
	str = validate_fingerprints(remote_cert, ssl_fingerprint_file);
	if (str) {
	    g_debug("%s", str);
	    amfree(str);
	    X509_free(remote_cert);
	    return;
	}
    }
    X509_free(remote_cert);

    rc = sec_tcp_conn_get(hostname, 0);
    rc->recv_security_ok = &bsd_recv_security_ok;
    rc->prefix_packet = &bsd_prefix_packet;
    rc->need_priv_port = 0;
    copy_sockaddr(&rc->peer, &sin);
    rc->read = in;
    rc->write = out;
    rc->accept_fn = fn;
    rc->driver = driver;
    rc->conf_fn = conf_fn;
    rc->datap = datap;
    rc->ctx = ctx;
    rc->ssl = ssl;
    strncpy(rc->hostname, cert_hostname, sizeof(rc->hostname)-1);

    g_debug(_("SSL_cipher: %s"), SSL_get_cipher(rc->ssl));

    sec_tcp_conn_read(rc);
}
예제 #23
0
파일: global.c 프로젝트: DonkeyWs/libgit2
int git_threads_init(void)
{
	init_ssl();
	git_atomic_inc(&git__n_inits);
	return 0;
}
예제 #24
0
static int tport_ws_init_primary_secure(tport_primary_t *pri,
				 tp_name_t tpn[1],
				 su_addrinfo_t *ai,
				 tagi_t const *tags,
				 char const **return_culprit)
{
  tport_ws_primary_t *wspri = (tport_ws_primary_t *)pri;
  const char *cert = "/ssl.pem";
  const char *key = "/ssl.pem";
  char *homedir;
  char *tbf = NULL;
  su_home_t autohome[SU_HOME_AUTO_SIZE(1024)];
  char const *path = NULL;
  int ret = -1;

  su_home_auto(autohome, sizeof autohome);

  tl_gets(tags,
	  TPTAG_CERTIFICATE_REF(path),
	  TAG_END());

  if (!path) {
    homedir = getenv("HOME");
    if (!homedir)
      homedir = "";
    path = tbf = su_sprintf(autohome, "%s/.sip/auth", homedir);
  }

  if (path) {
    key  = su_sprintf(autohome, "%s/%s", path, "wss.key");
	if (access(key, R_OK) != 0) key = NULL;
	cert = su_sprintf(autohome, "%s/%s", path, "wss.crt");
	if (access(cert, R_OK) != 0) cert = NULL;
	if ( !key )  key  = su_sprintf(autohome, "%s/%s", path, "wss.pem");
	if ( !cert ) cert = su_sprintf(autohome, "%s/%s", path, "wss.pem");
	if (access(key, R_OK) != 0) key = NULL;
	if (access(cert, R_OK) != 0) cert = NULL;
  }

  init_ssl();

  //  OpenSSL_add_all_algorithms();   /* load & register cryptos */                                                                                       
  //  SSL_load_error_strings();     /* load all error messages */                                                                                         
  wspri->ssl_method = SSLv23_server_method();   /* create server instance */
  wspri->ssl_ctx = SSL_CTX_new((SSL_METHOD *)wspri->ssl_method);         /* create context */
  SSL_CTX_sess_set_remove_cb(wspri->ssl_ctx, NULL);
  wspri->ws_secure = 1;

  if ( !wspri->ssl_ctx ) goto done;

  /* set the local certificate from CertFile */
  SSL_CTX_use_certificate_file(wspri->ssl_ctx, cert, SSL_FILETYPE_PEM);
  /* set the private key from KeyFile */
  SSL_CTX_use_PrivateKey_file(wspri->ssl_ctx, key, SSL_FILETYPE_PEM);
  /* verify private key */
  if ( !SSL_CTX_check_private_key(wspri->ssl_ctx) ) {
	  goto done;
  }

  SSL_CTX_set_cipher_list(wspri->ssl_ctx, "HIGH:!DSS:!aNULL@STRENGTH");

  ret = tport_ws_init_primary(pri, tpn, ai, tags, return_culprit);

 done:
  su_home_zap(autohome);
  return ret;
}
예제 #25
0
파일: server.c 프로젝트: 0pq76r/lunkwill
int start_server(int fd_ro, int fd_wr)
{
	struct sockaddr_in server_addr, client_addr;
	int server_sock, client_sock, addr_len;

	pthread_t thread;
	pthread_mutex_t lock;

	pthread_mutex_init(&lock, NULL);

	SSL_CTX *ctx=init_ssl();

	//Read config
	int port=3000;
	int listen_queue=10;
	int timeout=100;
	int optval = 1;
	struct timeval tv;

	port=*(int*)_("SOCKET.PORT", memdup(port));
	listen_queue=*(int*)_("SOCKET.LISTEN_QUEUE", memdup(listen_queue));
	timeout=*(int*)_("SOCKET.RCV_TIMEOUT", memdup(timeout));

	log_write(LOG_WARN, "Server started (Port: %d). Hit Ctrl-C to shutdown the server", port);

	tv.tv_sec = timeout/1000;
	tv.tv_usec = (timeout*1000)%1000000;

	//Set socket options
	if((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		log_write(LOG_ERR, "Error retrieving socket from system");
		goto ERROR;
	}

	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(port);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr_len = sizeof(client_addr);
	memset(&(server_addr.sin_zero), '\0', 8);


	// Configure sockets
	if(timeout!=0)
	{
		if(setsockopt(server_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval)))
		{
			log_write(LOG_ERR, "Error configuring sockets");
			goto ERROR_CLOSE_SOCK;
		}
	}

	if(setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)))
	{
		log_write(LOG_ERR, "Error configuring sockets");
		goto ERROR_CLOSE_SOCK;
	}

	if(bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
	{
		log_write(LOG_ERR, "Error binding server to port");
		goto ERROR_CLOSE_SOCK;
	}

	if((listen(server_sock, listen_queue)) < 0)
	{
		log_write(LOG_ERR, "Error listening on port");
		goto ERROR_CLOSE_SOCK;
	}


	setvbuf(stdin,NULL,_IONBF,0);


	// Responder thread
	if((pthread_create(&thread, NULL, responder, &fd_ro))!=0)
	{
		log_write(LOG_ERR, "Could not create thread");
		goto ERROR_CLOSE_SOCK;
	}
	else
	{
		pthread_detach(thread);
	}


	while(!ExitServer)
	{
		SSL* ssl = SSL_new(ctx);
		struct pipe_rxtx *p=malloc(sizeof(struct pipe_rxtx));

		if((client_sock = accept(server_sock, (struct sockaddr *)&client_addr, (socklen_t*)&addr_len)) <0)
		{
			nfree(p);
			continue;
		}

		SSL_set_fd(ssl, client_sock);


		p->fd=client_sock;
		p->fd_pipe=fd_wr;
		p->ssl=ssl;
		p->lock=&lock;

		if((pthread_create(&thread, NULL, receiver, p))!=0)
		{
			log_write(LOG_ERR, "Could not create thread");
			goto ERROR_CLIENT;
		}
		else
		{
			pthread_detach(thread);
		}

		continue;

ERROR_CLIENT:
		nfree(p);
		SSL_free(ssl);
		close(client_sock);
	}

ERROR_CLOSE_SOCK:
	close(server_sock);
ERROR:
	return 1;
}
예제 #26
0
int
run_main (int, ACE_TCHAR *[])
{
  ACE_START_TEST (ACE_TEXT ("Bug_2912_Regression_Test"));

  // SSL_CTX_set_cipher_list, etc.
  init_ssl ();

  // Keep RT signals on POSIX from killing us.
  disable_signal (ACE_SIGRTMIN, ACE_SIGRTMAX);

  int ret = 0;
  Client_Service_Handler client_handler;
  Server_Service_Handler server_handler;
  ACE_Time_Value wait_time (10, 0);

  // Client and Server will utilize different proactors since this test
  // depends on SSL thread error state behavior.

  CLIENT_PROACTOR_TASK->activate ();
  SERVER_PROACTOR_TASK->activate ();

  // Open server acceptor and client connector

  if (0 == ret)
  {
    ret = ACCEPTOR->open (
      ACE_INET_Addr (ACE_DEFAULT_SERVER_PORT),
      0,
      0,
      ACE_DEFAULT_ASYNCH_BACKLOG,
      1,
      SERVER_PROACTOR,
      1);

      if (-1 == ret)
      {
        ACE_DEBUG ((LM_DEBUG, ACE_TEXT (
          "ACE_Asynch_Acceptor::open failed, %d\n"), (int)errno));
      }
  }

  if (0 == ret)
  {
    ret = CONNECTOR->open (0, CLIENT_PROACTOR, 1);

    if (-1 == ret)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT (
        "ACE_Asynch_Connector::open failed, %d\n"), (int)errno));
    }
  }

  // Supply server_handler and client_handler to acceptor and connector and
  // connect client to the server.

  if (0 == ret)
  {
    ACCEPTOR->prepare_for_connection (&server_handler);
    CONNECTOR->prepare_for_connection (&client_handler);

    ret = CONNECTOR->connect (
      ACE_INET_Addr (ACE_DEFAULT_SERVER_PORT, ACE_LOCALHOST));

    if (-1 == ret)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT (
        "ACE_Asynch_Connector::connect failed, %d\n"), (int)errno));
    }
  }

  if (0 == ret)
  {
    ret = client_handler.wait_for_external_write_queue (&wait_time);
    if (-1 == ret)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT (
        "Timed out waiting for client's write readiness\n")));
    }
  }

  // Client sends data to server

  if (0 == ret)
  {
    ret = client_handler.write_data ();
  }

  // Client waits for echo reply from server

  if (0 == ret)
  {
    ret = client_handler.wait_for_read_completed (&wait_time);

    if (-1 == ret)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT (
        "Timed out waiting for client's read to complete\n")));
    }
  }

  if (0 == ret)
  {
    if (client_handler.read_successful () == 1)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Success\n")));
      ret = 0;
    }
    else
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Client's read failed\n")));
      ret = -1;
    }
  }

  // Cleanup and shutdown

  ACCEPTOR->cancel ();
  while (!ACCEPTOR->safe_to_delete ())
    ACE_OS::sleep (ACE_Time_Value (0, 500000));

  CONNECTOR->cancel ();
  while (!CONNECTOR->safe_to_delete ())
    ACE_OS::sleep (ACE_Time_Value (0, 500000));

  client_handler.cancel_and_close ();
  while (!client_handler.safe_to_delete ())
    ACE_OS::sleep (ACE_Time_Value (0, 500000));

  server_handler.cancel_and_close ();
  while (!server_handler.safe_to_delete ())
    ACE_OS::sleep (ACE_Time_Value (0, 500000));

  CLIENT_PROACTOR->proactor_end_event_loop ();
  CLIENT_PROACTOR_TASK->wait ();

  SERVER_PROACTOR->proactor_end_event_loop ();
  SERVER_PROACTOR_TASK->wait ();

  ACE_END_TEST;

  return 0;
}
예제 #27
0
/*
 * Here's where it all begins.
 */
int main(int argc, char **argv)
{
	uid_t UID = -1;
	size_t basesize = 2;            /* how big should strbufs be on creation? */
	pthread_t SessThread;		/* Thread descriptor */
	pthread_attr_t attr;		/* Thread attributes */
	int a;		        	/* General-purpose variable */
	char ip_addr[256]="*";
	int relh=0;
	int home=0;
	char relhome[PATH_MAX]="";
	char webcitdir[PATH_MAX] = DATADIR;
	char *pidfile = NULL;
	char *hdir;
	const char *basedir = NULL;
	char uds_listen_path[PATH_MAX];	/* listen on a unix domain socket? */
	const char *I18nDumpFile = NULL;

	WildFireInitBacktrace(argv[0], 2);

	start_modules();

#ifdef DBG_PRINNT_HOOKS_AT_START
/*	dbg_PrintHash(HandlerHash, nix, NULL);*/
#endif

	/* Ensure that we are linked to the correct version of libcitadel */
	if (libcitadel_version_number() < LIBCITADEL_VERSION_NUMBER) {
		fprintf(stderr, " You are running libcitadel version %d\n", libcitadel_version_number() );
		fprintf(stderr, "WebCit was compiled against version %d\n", LIBCITADEL_VERSION_NUMBER );
		return(1);
	}

	strcpy(uds_listen_path, "");

	/* Parse command line */
#ifdef HAVE_OPENSSL
	while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:g:dD:G:cfsS:Z:v:")) != EOF)
#else
	while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:g:dD:G:cfZ:v:")) != EOF)
#endif
		switch (a) {
		case 'u':
			UID = atol(optarg);
			break;
		case 'h':
			hdir = strdup(optarg);
			relh=hdir[0]!='/';
			if (!relh) {
				safestrncpy(webcitdir, hdir, sizeof webcitdir);
			}
			else {
				safestrncpy(relhome, relhome, sizeof relhome);
			}
			/* free(hdir); TODO: SHOULD WE DO THIS? */
			home=1;
			break;
		case 'd':
			running_as_daemon = 1;
			break;
		case 'D':
			pidfile = strdup(optarg);
			running_as_daemon = 1;
			break;
		case 'g':
			default_landing_page = strdup(optarg);
			break;
		case 'B': /* Basesize */
			basesize = atoi(optarg);
			if (basesize > 2)
				StartLibCitadel(basesize);
			break;
		case 'i':
			safestrncpy(ip_addr, optarg, sizeof ip_addr);
			break;
		case 'p':
			http_port = atoi(optarg);
			if (http_port == 0) {
				safestrncpy(uds_listen_path, optarg, sizeof uds_listen_path);
			}
			break;
		case 't':
			/* no longer used, but ignored so old scripts don't break */
			break;
		case 'T':
			LoadTemplates = atoi(optarg);
			dbg_analyze_msg = (LoadTemplates & (1<<1)) != 0;
			dbg_backtrace_template_errors = (LoadTemplates & (1<<2)) != 0;
			break;
		case 'Z':
			DisableGzip = 1;
			break;
		case 'x':
			/* no longer used, but ignored so old scripts don't break */
			break;
		case 'f':
			follow_xff = 1;
			break;
		case 'c':
			server_cookie = malloc(256);
			if (server_cookie != NULL) {
				safestrncpy(server_cookie,
				       "Set-cookie: wcserver=",
					256);
				if (gethostname
				    (&server_cookie[strlen(server_cookie)],
				     200) != 0) {
					syslog(LOG_INFO, "gethostname: %s", strerror(errno));
					free(server_cookie);
				}
			}
			break;
#ifdef HAVE_OPENSSL
		case 's':
			is_https = 1;
			break;
		case 'S':
			is_https = 1;
			ssl_cipher_list = strdup(optarg);
			break;
#endif
		case 'G':
			DumpTemplateI18NStrings = 1;
			I18nDump = NewStrBufPlain(HKEY("int templatestrings(void)\n{\n"));
			I18nDumpFile = optarg;
			break;
		case 'v':
			verbose=1;
			break;
		default:
			fprintf(stderr, "usage:\nwebcit "
				"[-i ip_addr] [-p http_port] "
				"[-c] [-f] "
				"[-T Templatedebuglevel] "
				"[-d] [-Z] [-G i18ndumpfile] "
				"[-u uid] [-h homedirectory] "
				"[-D daemonizepid] [-v] "
				"[-g defaultlandingpage] [-B basesize] "
#ifdef HAVE_OPENSSL
				"[-s] [-S cipher_suites]"
#endif
				"[remotehost [remoteport]]\n");
			return 1;
		}

	/* Start the logger */
	openlog("webcit",
		( running_as_daemon ? (LOG_PID) : (LOG_PID | LOG_PERROR) ),
		LOG_DAEMON
	);

	if (optind < argc) {
		ctdlhost = argv[optind];
		if (++optind < argc)
			ctdlport = argv[optind];
	}

	/* daemonize, if we were asked to */
	if (!DumpTemplateI18NStrings && running_as_daemon) {
		start_daemon(pidfile);
	}
	else {
		signal(SIGINT, graceful_shutdown);
		signal(SIGHUP, graceful_shutdown);
	}

	webcit_calc_dirs_n_files(relh, basedir, home, webcitdir, relhome);
	LoadMimeBlacklist();
	LoadIconDir(static_icon_dir);

	/* Tell 'em who's in da house */
	syslog(LOG_NOTICE, "%s", PACKAGE_STRING);
	syslog(LOG_NOTICE, "Copyright (C) 1996-2015 by the citadel.org team");
	syslog(LOG_NOTICE, " ");
	syslog(LOG_NOTICE, "This program is open source software: you can redistribute it and/or");
	syslog(LOG_NOTICE, "modify it under the terms of the GNU General Public License, version 3.");
	syslog(LOG_NOTICE, " ");
	syslog(LOG_NOTICE, "This program is distributed in the hope that it will be useful,");
	syslog(LOG_NOTICE, "but WITHOUT ANY WARRANTY; without even the implied warranty of");
	syslog(LOG_NOTICE, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the");
	syslog(LOG_NOTICE, "GNU General Public License for more details.");
	syslog(LOG_NOTICE, " ");

	/* initialize various subsystems */

	initialise_modules();
	initialise2_modules();
	InitTemplateCache();
	if (DumpTemplateI18NStrings) {
		FILE *fd;
		StrBufAppendBufPlain(I18nDump, HKEY("}\n"), 0);
	        if (StrLength(I18nDump) < 50) {
			syslog(LOG_INFO, "*******************************************************************\n");
			syslog(LOG_INFO, "*   No strings found in templates!  Are you sure they're there?   *\n");
			syslog(LOG_INFO, "*******************************************************************\n");
			return -1;
		}
		fd = fopen(I18nDumpFile, "w");
	        if (fd == NULL) {
			syslog(LOG_INFO, "***********************************************\n");
			syslog(LOG_INFO, "*   unable to open I18N dumpfile [%s]         *\n", I18nDumpFile);
			syslog(LOG_INFO, "***********************************************\n");
			return -1;
		}
		fwrite(ChrPtr(I18nDump), 1, StrLength(I18nDump), fd);
		fclose(fd);
		return 0;
	}

	/* Tell libical to return an error instead of aborting if it sees badly formed iCalendar data. */
	icalerror_errors_are_fatal = 0;

	/* Use our own prefix on tzid's generated from system tzdata */
	icaltimezone_set_tzid_prefix("/citadel.org/");

	/*
	 * Set up a place to put thread-specific data.
	 * We only need a single pointer per thread - it points to the
	 * wcsession struct to which the thread is currently bound.
	 */
	if (pthread_key_create(&MyConKey, NULL) != 0) {
		syslog(LOG_EMERG, "Can't create TSD key: %s", strerror(errno));
	}
	InitialiseSemaphores();

	/*
	 * Set up a place to put thread-specific SSL data.
	 * We don't stick this in the wcsession struct because SSL starts
	 * up before the session is bound, and it gets torn down between
	 * transactions.
	 */
#ifdef HAVE_OPENSSL
	if (pthread_key_create(&ThreadSSL, NULL) != 0) {
		syslog(LOG_EMERG, "Can't create TSD key: %s", strerror(errno));
	}
#endif

	/*
	 * Bind the server to our favorite port.
	 * There is no need to check for errors, because webcit_tcp_server()
	 * exits if it doesn't succeed.
	 */

	if (!IsEmptyStr(uds_listen_path)) {
		syslog(LOG_DEBUG, "Attempting to create listener socket at %s...", uds_listen_path);
		msock = webcit_uds_server(uds_listen_path, LISTEN_QUEUE_LENGTH);
	}
	else {
		syslog(LOG_DEBUG, "Attempting to bind to port %d...", http_port);
		msock = webcit_tcp_server(ip_addr, http_port, LISTEN_QUEUE_LENGTH);
	}
	if (msock < 0)
	{
		ShutDownWebcit();
		return -msock;
	}

	syslog(LOG_INFO, "Listening on socket %d", msock);
	signal(SIGPIPE, SIG_IGN);

	pthread_mutex_init(&SessionListMutex, NULL);

	/*
	 * Start up the housekeeping thread
	 */
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	pthread_create(&SessThread, &attr, (void *(*)(void *)) housekeeping_loop, NULL);

	/*
	 * If this is an HTTPS server, fire up SSL
	 */
#ifdef HAVE_OPENSSL
	if (is_https) {
		init_ssl();
	}
#endif
	drop_root(UID);

	/* Become a worker thread.  More worker threads will be spawned as they are needed. */
	worker_entry();
	ShutDownLibCitadel();
	return 0;
}
예제 #28
0
static apr_status_t
init_ssl_context(serv_ctx_t *serv_ctx,
                 const char *keyfile,
                 const char **certfiles,
                 const char *client_cn)
{
    ssl_context_t *ssl_ctx = apr_pcalloc(serv_ctx->pool, sizeof(*ssl_ctx));
    serv_ctx->ssl_ctx = ssl_ctx;
    serv_ctx->client_cn = client_cn;
    serv_ctx->bio_read_status = APR_SUCCESS;

    /* Init OpenSSL globally */
    if (!init_done)
    {
        CRYPTO_malloc_init();
        ERR_load_crypto_strings();
        SSL_load_error_strings();
        SSL_library_init();
        OpenSSL_add_all_algorithms();
        init_done = 1;
    }

    /* Init this connection */
    if (!ssl_ctx->ctx) {
        X509_STORE *store;
        const char *certfile;
        int i;
        int rv;

        ssl_ctx->ctx = SSL_CTX_new(SSLv23_server_method());
        SSL_CTX_set_default_passwd_cb(ssl_ctx->ctx, pem_passwd_cb);
        rv = SSL_CTX_use_PrivateKey_file(ssl_ctx->ctx, keyfile,
                                         SSL_FILETYPE_PEM);
        if (rv != 1) {
            fprintf(stderr, "Cannot load private key from file '%s'\n", keyfile);
            exit(1);
        }

        /* Set server certificate, add ca certificates if provided. */
        certfile = certfiles[0];
        rv = SSL_CTX_use_certificate_file(ssl_ctx->ctx, certfile, SSL_FILETYPE_PEM);
        if (rv != 1) {
            fprintf(stderr, "Cannot load certficate from file '%s'\n", keyfile);
            exit(1);
        }

        i = 1;
        certfile = certfiles[i++];
        store = SSL_CTX_get_cert_store(ssl_ctx->ctx);

        while(certfile) {
            FILE *fp = fopen(certfile, "r");
            if (fp) {
                X509 *ssl_cert = PEM_read_X509(fp, NULL, NULL, NULL);
                fclose(fp);

                SSL_CTX_add_extra_chain_cert(ssl_ctx->ctx, ssl_cert);

                X509_STORE_add_cert(store, ssl_cert);
            }
            certfile = certfiles[i++];
        }

        /* This makes the server send a client certificate request during
           handshake. The client certificate is optional (most tests don't
           send one) by default, but mandatory if client_cn was specified. */
        SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_PEER,
                           validate_client_certificate);

        SSL_CTX_set_mode(ssl_ctx->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);

        ssl_ctx->bio = BIO_new(&bio_apr_socket_method);
        ssl_ctx->bio->ptr = serv_ctx;
        init_ssl(serv_ctx);
    }

    return APR_SUCCESS;
}
예제 #29
0
int main(int argc, char **argv)
{
	int ret;
	struct server_settings settings;

	// load arguments
	ret = parse_server_settings(argc, (char **) argv, &settings);

	if (is_failure(ret))
	{
		print_usage;
		return ret;
	}

	int sock;
	SSL_CTX *ssl_ctx;
	SSL *ssl;
	pthread_t thread_id;
	struct client client = {&settings, NULL};

	// init ssl
	if (is_failure(init_ssl(&ssl_ctx, NULL, settings.cert_path, settings.key_path)))
		goto GENERAL_CLEAN_UP;

	sock = create_server_socket(settings.port);

	printf("Listening on port %d\n", settings.port);
	register_signal_handler();

	while (server_running)
	{
		struct sockaddr_in addr;
		uint len = sizeof addr;

		int client_sock = accept(sock, (struct sockaddr *) &addr, &len);
		if (client_sock < 0)
		{
			// not clean
			if (server_running)
			{
				error_print("Failed to accept client connection\n");
				ret = ERROR_SOCKET;
			}

			break;
		}

		puts("Client connected");
		if (is_failure(accept_ssl(ssl_ctx, &ssl, client_sock)))
			continue;

		// spawn thread
		client.ssl = ssl;
		if (pthread_create(&thread_id, NULL, client_handler, (void *) &client) < 0)
			error_print("Failed to spawn client thread\n");
	}


GENERAL_CLEAN_UP:
	puts("\nCleaning up");

	if (ssl_ctx != NULL)
		SSL_CTX_free(ssl_ctx);

	ERR_free_strings();
	EVP_cleanup();

	return ret;
}
예제 #30
0
/*
 * Open a ssl connection to the host listed in rc->hostname
 * Returns negative on error, with an errmsg in rc->errmsg.
 */
static int
runssl(
    struct sec_handle *	rh,
    in_port_t port,
    char *src_ip,
    char *ssl_fingerprint_file,
    char *ssl_cert_file,
    char *ssl_key_file,
    char *ssl_ca_cert_file,
    char *ssl_cipher_list,
    int   ssl_check_certificate_host)
{
    int		     my_socket;
    in_port_t	     my_port;
    struct tcp_conn *rc = rh->rc;
    int              err;
    X509            *remote_cert;
    sockaddr_union   sin;
    socklen_t_equiv  len;

    if (!ssl_key_file) {
	security_seterror(&rh->sech, _("ssl-key-file must be set"));
	return -1;
    }

    if (!ssl_cert_file) {
	security_seterror(&rh->sech, _("ssl-cert-file must be set"));
	return -1;
    }

    my_socket = stream_client(src_ip,
				  rc->hostname,
				  port,
				  STREAM_BUFSIZE,
				  STREAM_BUFSIZE,
				  &my_port,
				  0);

    if(my_socket < 0) {
	security_seterror(&rh->sech,
	    "%s", strerror(errno));

	return -1;
    }

    rc->read = rc->write = my_socket;

    len = sizeof(sin);
    if (getpeername(my_socket, (struct sockaddr *)&sin, &len) < 0) {
	security_seterror(&rh->sech, _("getpeername returned: %s\n"), strerror(errno));
	return -1;
    }
    copy_sockaddr(&rc->peer, &sin);

    init_ssl();

    /* Create an SSL_CTX structure */
    rc->ctx = SSL_CTX_new(SSLv3_client_method());
    if (!rc->ctx) {
	security_seterror(&rh->sech, "%s",
			  ERR_error_string(ERR_get_error(), NULL));
	return -1;
    }
    SSL_CTX_set_mode(rc->ctx, SSL_MODE_AUTO_RETRY);

    if (ssl_cipher_list) {
	g_debug("Set ssl_cipher_list to %s", ssl_cipher_list);
	if (SSL_CTX_set_cipher_list(rc->ctx, ssl_cipher_list) == 0) {
	    security_seterror(&rh->sech, "%s",
		              ERR_error_string(ERR_get_error(), NULL));
	    return -1;
	}
    }

    /* Load the private-key corresponding to the remote certificate */
    g_debug("Loading ssl-key-file private-key %s", ssl_key_file);
    if (SSL_CTX_use_PrivateKey_file(rc->ctx, ssl_key_file,
				    SSL_FILETYPE_PEM) <= 0) {
	security_seterror(&rh->sech, "%s",
			  ERR_error_string(ERR_get_error(), NULL));
	return -1;
    }

    /* Load the me certificate into the SSL_CTX structure */
    g_debug("Loading ssl-cert-file certificate %s", ssl_cert_file);
    if (SSL_CTX_use_certificate_file(rc->ctx, ssl_cert_file,
				     SSL_FILETYPE_PEM) <= 0) {
	security_seterror(&rh->sech, "%s",
			  ERR_error_string(ERR_get_error(), NULL));
	return -1;
    }

    /* Check if the remote certificate and private-key matches */
    if (ssl_cert_file) {
	if (!SSL_CTX_check_private_key(rc->ctx)) {
	security_seterror(&rh->sech,
		_("Private key does not match the certificate public key"));
	return -1;
	}
    }

    if (ssl_ca_cert_file) {
        /* Load the RSA CA certificate into the SSL_CTX structure */
        /* This will allow this remote to verify the me's     */
        /* certificate.                                           */
	g_debug("Loading ssl-ca-cert-file ca %s", ssl_ca_cert_file);
        if (!SSL_CTX_load_verify_locations(rc->ctx, ssl_ca_cert_file, NULL)) {
	    security_seterror(&rh->sech, "%s",
			      ERR_error_string(ERR_get_error(), NULL));
	    return -1;
        }
    } else {
	g_debug(_("no ssl-ca-cert-file defined"));
    }

    /* Set flag in context to require peer (me) certificate */
    /* verification */
    if (ssl_ca_cert_file) {
	g_debug("Enabling certification verification");
	SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL);
	SSL_CTX_set_verify_depth(rc->ctx, 1);
    } else {
	g_debug("Not enabling certification verification");
    }

    /* ----------------------------------------------- */
    rc->ssl = SSL_new(rc->ctx);
    if (!rc->ssl) {
	security_seterror(&rh->sech, _("SSL_new failed: %s"),
			  ERR_error_string(ERR_get_error(), NULL));
	return -1;
    }
    SSL_set_connect_state(rc->ssl);

    /* Assign the socket into the SSL structure (SSL and socket without BIO) */
    SSL_set_fd(rc->ssl, my_socket);

    /* Perform SSL Handshake on the SSL remote */
    err = SSL_connect(rc->ssl);
    if (err == -1) {
	security_seterror(&rh->sech, _("SSL_connect failed: %s"),
			  ERR_error_string(ERR_get_error(), NULL));
	return -1;
    }

    /* Get the me's certificate (optional) */
    remote_cert = SSL_get_peer_certificate(rc->ssl);

    if (remote_cert == NULL) {
	security_seterror(&rh->sech, _("server have no certificate"));
	return -1;
    } else {
        char *str;

        str = X509_NAME_oneline(X509_get_subject_name(remote_cert), 0, 0);
        auth_debug(1, _("\t subject: %s\n"), str);
        amfree (str);

        str = X509_NAME_oneline(X509_get_issuer_name(remote_cert), 0, 0);
        auth_debug(1, _("\t issuer: %s\n"), str);
        amfree(str);

	if (ssl_check_certificate_host) {
	    int   loc = -1;
	    char *errmsg = NULL;
	    X509_NAME *x509_name = X509_get_subject_name(remote_cert);

	    loc = X509_NAME_get_index_by_NID(x509_name, NID_commonName, loc);
	    if (loc != -1) {
		X509_NAME_ENTRY *x509_entry = X509_NAME_get_entry(x509_name, loc);
		ASN1_STRING *asn1_string = X509_NAME_ENTRY_get_data(x509_entry);
		char *cert_hostname =  (char *)ASN1_STRING_data(asn1_string);
		auth_debug(1, "common_name: %s\n", cert_hostname);

		if (check_name_give_sockaddr((char*)cert_hostname,
				 (struct sockaddr *)&rc->peer, &errmsg) < 0) {
		    security_seterror(&rh->sech,
		       _("Common name of certicate (%s) doesn't resolv to IP (%s): %s"),
		       cert_hostname, str_sockaddr(&rc->peer), errmsg);
		    amfree(errmsg);
		    return -1;
		}
		auth_debug(1,
		         _("Certificate common name (%s) resolve to IP (%s)\n"),
			 cert_hostname, str_sockaddr(&rc->peer));
	    } else {
		security_seterror(&rh->sech,
				  _("Certificate have no common name"));
		g_debug("Certificate have no common name");
		return -1;
	    }
	}

/*
	if (ssl_dir) {
	    if (!ssl_fingerprint_file || ssl_fingerprint_file == '\0') {
		struct stat  statbuf;
		ssl_fingerprint_file = g_strdup_printf("%s/remote/%s/fingerprint", ssl_dir, cert_hostname);
		if (stat(ssl_fingerprint_file, &statbuf) == -1) {
		    g_free(ssl_fingerprint_file);
		    ssl_fingerprint_file = NULL;
		}
	    }
	}
*/

	if (ssl_fingerprint_file) {
            g_debug(_("run_ssl: Loading ssl-fingerprint-file %s"), ssl_fingerprint_file);
	    str = validate_fingerprints(remote_cert, ssl_fingerprint_file);
	    if (str) {
		security_seterror(&rh->sech, "%s", str);
		amfree(str);
		return -1;
	    }
	}
	X509_free (remote_cert);
    }

    g_debug(_("SSL_cipher: %s"), SSL_get_cipher(rc->ssl));

    return 0;
}