예제 #1
0
wi_string_t * wi_socket_cipher_name(wi_socket_t *socket) {
#ifdef HAVE_OPENSSL_SSL_H
	return wi_string_with_cstring(SSL_get_cipher_name(socket->ssl));
#else
	return NULL;
#endif
}
예제 #2
0
파일: ioev.c 프로젝트: Vaelatern/OpenSMTPD
const char*
io_strio(struct io *io)
{
	static char	buf[128];
	char		ssl[128];

	ssl[0] = '\0';
#ifdef IO_SSL
	if (io->ssl) {
		(void)snprintf(ssl, sizeof ssl, " ssl=%s:%s:%d",
		    SSL_get_version(io->ssl),
		    SSL_get_cipher_name(io->ssl),
		    SSL_get_cipher_bits(io->ssl, NULL));
	}
#endif

	if (io->iobuf == NULL)
		(void)snprintf(buf, sizeof buf,
		    "<io:%p fd=%d to=%d fl=%s%s>",
		    io, io->sock, io->timeout, io_strflags(io->flags), ssl);
	else
		(void)snprintf(buf, sizeof buf,
		    "<io:%p fd=%d to=%d fl=%s%s ib=%zu ob=%zu>",
		    io, io->sock, io->timeout, io_strflags(io->flags), ssl,
		    io_pending(io), io_queued(io));

	return (buf);
}
예제 #3
0
파일: ssl.c 프로젝트: ezc/elinks
unsigned char *
get_ssl_connection_cipher(struct socket *socket)
{
	ssl_t *ssl = socket->ssl;
	struct string str;

	if (!init_string(&str)) return NULL;

#ifdef USE_OPENSSL
	add_format_to_string(&str, "%ld-bit %s %s",
		SSL_get_cipher_bits(ssl, NULL),
		SSL_get_cipher_version(ssl),
		SSL_get_cipher_name(ssl));
#elif defined(CONFIG_GNUTLS)
	/* XXX: How to get other relevant parameters? */
	add_format_to_string(&str, "%s - %s - %s - %s - %s (compr: %s)",
		gnutls_protocol_get_name(gnutls_protocol_get_version(*ssl)),
		gnutls_kx_get_name(gnutls_kx_get(*ssl)),
		gnutls_cipher_get_name(gnutls_cipher_get(*ssl)),
		gnutls_mac_get_name(gnutls_mac_get(*ssl)),
		gnutls_certificate_type_get_name(gnutls_certificate_type_get(*ssl)),
		gnutls_compression_get_name(gnutls_compression_get(*ssl)));
#endif

	return str.source;
}
예제 #4
0
파일: sslio.c 프로젝트: ewalshe/hiredis
/**
 * Callback used for debugging
 */
static void sslLogCallback(const SSL *ssl, int where, int ret) {
    const char *retstr = "";
    int should_log = 1;
    /* Ignore low-level SSL stuff */

    if (where & SSL_CB_ALERT) {
        should_log = 1;
    }
    if (where == SSL_CB_HANDSHAKE_START || where == SSL_CB_HANDSHAKE_DONE) {
        should_log = 1;
    }
    if ((where & SSL_CB_EXIT) && ret == 0) {
        should_log = 1;
    }

    if (!should_log) {
        return;
    }

    retstr = SSL_alert_type_string(ret);
    printf("ST(0x%x). %s. R(0x%x)%s\n", where, SSL_state_string_long(ssl), ret, retstr);

    if (where == SSL_CB_HANDSHAKE_DONE) {
        printf("Using SSL version %s. Cipher=%s\n", SSL_get_version(ssl), SSL_get_cipher_name(ssl));
    }
}
예제 #5
0
파일: apn_ssl.c 프로젝트: edwiincao/libcapn
static void __apn_ssl_info_callback(const SSL *ssl, int where, int ret) {
    apn_ctx_t *ctx = SSL_CTX_get_ex_data(ssl->ctx, 0);
    if (!ctx) {
        return;
    }
    if (where & SSL_CB_LOOP) {
        apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: %s:%s:%s",
                (where & SSL_ST_CONNECT) ? "connect" : "undef",
                SSL_state_string_long(ssl),
                SSL_get_cipher_name(ssl));
    } else if (where & SSL_CB_EXIT) {
        apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: %s:%s", (where & SSL_ST_CONNECT) ? "connect" : "undef",
                SSL_state_string_long(ssl));
    } else if (where & SSL_CB_ALERT) {
        apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: alert %s:%s", (where & SSL_CB_READ) ? "read" : "write",
                SSL_state_string_long(ssl), SSL_alert_desc_string_long(ret));
    } else if (where & SSL_CB_HANDSHAKE_START) {
        apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: handshake started %s:%s:%s", (where & SSL_CB_READ) ? "read" : "write",
                SSL_state_string_long(ssl), SSL_alert_desc_string_long(ret));
    }
    else if (where & SSL_CB_HANDSHAKE_DONE) {
        apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: handshake done %s:%s:%s", (where & SSL_CB_READ) ? "read" : "write",
                SSL_state_string_long(ssl), SSL_alert_desc_string_long(ret));
    } else {
        apn_log(ctx, APN_LOG_LEVEL_INFO, "ssl: state %s:%s:%s", SSL_state_string_long(ssl),
                SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
    }
}
예제 #6
0
파일: SSLSocket.cpp 프로젝트: Caraul/airgit
std::string SSLSocket::getEncryptionInfo() const noexcept {
	if (!ssl)
		return Util::emptyString;

	string cipher = SSL_get_cipher_name(ssl);
	string protocol = SSL_get_version(ssl);
	return protocol + " / " + cipher;
}
예제 #7
0
  bool OpenSSLBase::handshake()
  {

    doTLSOperation( TLSHandshake );

    if( !m_secure )
      return true;

    int res = SSL_get_verify_result( m_ssl );
    if( res != X509_V_OK )
      m_certInfo.status = CertInvalid;
    else
      m_certInfo.status = CertOk;

    X509* peer = SSL_get_peer_certificate( m_ssl );
    if( peer )
    {
      char peer_CN[256];
      X509_NAME_get_text_by_NID( X509_get_issuer_name( peer ), NID_commonName, peer_CN, sizeof( peer_CN ) );
      m_certInfo.issuer = peer_CN;
      X509_NAME_get_text_by_NID( X509_get_subject_name( peer ), NID_commonName, peer_CN, sizeof( peer_CN ) );
      m_certInfo.server = peer_CN;
      m_certInfo.date_from = openSSLTime2UnixTime( (char*) (peer->cert_info->validity->notBefore->data) );
      m_certInfo.date_to = openSSLTime2UnixTime( (char*) (peer->cert_info->validity->notAfter->data) );
      std::string p( peer_CN );
      std::transform( p.begin(), p.end(), p.begin(), tolower );
      if( p != m_server )
        m_certInfo.status |= CertWrongPeer;

      if( ASN1_UTCTIME_cmp_time_t( X509_get_notBefore( peer ), time( 0 ) ) != -1 )
        m_certInfo.status |= CertNotActive;

      if( ASN1_UTCTIME_cmp_time_t( X509_get_notAfter( peer ), time( 0 ) ) != 1 )
        m_certInfo.status |= CertExpired;
    }
    else
    {
      m_certInfo.status = CertInvalid;
    }

    const char* tmp;
    tmp = SSL_get_cipher_name( m_ssl );
    if( tmp )
      m_certInfo.cipher = tmp;

    tmp = SSL_get_cipher_version( m_ssl );
    if( tmp )
      m_certInfo.protocol = tmp;

    tmp = SSL_COMP_get_name( SSL_get_current_compression( m_ssl ) );
    if( tmp )
      m_certInfo.compression = tmp;

    m_valid = true;

    m_handler->handleHandshakeResult( this, true, m_certInfo );
    return true;
  }
예제 #8
0
const char* irc_get_ssl_ciphers_used(irc_session_t *session) {
    const char *ciphers_used = "None";

    if (session->ssl != NULL) {
        ciphers_used = SSL_get_cipher_name(session->ssl);
    }

    return ciphers_used;
}
예제 #9
0
파일: ssl.c 프로젝트: lucasad/OpenSMTPD
const char *
ssl_to_text(const SSL *ssl)
{
	static char buf[256];

	(void)snprintf(buf, sizeof buf, "version=%s, cipher=%s, bits=%d",
	    SSL_get_cipher_version(ssl),
	    SSL_get_cipher_name(ssl),
	    SSL_get_cipher_bits(ssl, NULL));

	return (buf);
}
예제 #10
0
/** wrapper around SSL_connect, using SSL return convention.
 * It will also log critical errors and certificate debugging info.
 * @param c - tcp connection with tls (extra_data must be a filled
 *            tcp_extra_data structure). The state must be S_TLS_CONNECTING.
 * @param error  set to the error reason (SSL_ERROR_*).
 *            Note that it can be SSL_ERROR_NONE while the return is < 0
 *            ("internal" error, not at the SSL level, see below).
 * @return >=1 on success, 0 and <0 on error. 0 means the underlying SSL
 *           connection was closed/shutdown. < 0 is returned for any
 *           SSL_ERROR (including  WANT_READ or WANT_WRITE), but also
 *           for internal non SSL related errors (in this case -2 is
 *           returned and error==SSL_ERROR_NONE).
 *
 */
int tls_connect(struct tcp_connection *c, int* error)
{
	SSL *ssl;
	int ret;
	X509* cert;
	struct tls_extra_data* tls_c;
	int tls_log;

	*error = SSL_ERROR_NONE;
	tls_c=(struct tls_extra_data*)c->extra_data;
	ssl=tls_c->ssl;
	
	if (unlikely(tls_c->state != S_TLS_CONNECTING)) {
		BUG("Invalid connection state %d (bug in TLS code)\n", tls_c->state);
		goto err;
	}
	ret = SSL_connect(ssl);
	if (unlikely(ret == 1)) {
		DBG("TLS connect successful\n");
		tls_c->state = S_TLS_ESTABLISHED;
		tls_log = cfg_get(tls, tls_cfg, log);
		LOG(tls_log, "tls_connect: new connection to %s:%d using %s %s %d\n", 
		    ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
		    SSL_get_cipher_version(ssl), SSL_get_cipher_name(ssl),
		    SSL_get_cipher_bits(ssl, 0)
		    );
		LOG(tls_log, "tls_connect: sending socket: %s:%d \n", 
		    ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port
		    );
		cert = SSL_get_peer_certificate(ssl);
		if (cert != 0) { 
			tls_dump_cert_info("tls_connect: server certificate", cert);
			if (SSL_get_verify_result(ssl) != X509_V_OK) {
				LOG(tls_log, "WARNING: tls_connect: server certificate "
				    "verification failed!!!\n");
				tls_dump_verification_failure(SSL_get_verify_result(ssl));
			}
			X509_free(cert);
		} else {
			/* this should not happen, servers always present a cert */
			LOG(tls_log, "tls_connect: server did not "
							"present a certificate\n");
		}
		tls_run_event_routes(c);
	} else { /* 0 or < 0 */
		*error = SSL_get_error(ssl, ret);
	}
	return ret;
err:
	/* internal non openssl related errors */
	return -2;
}
예제 #11
0
   CipherInfo
   TCPConnection::GetCipherInfo()
   {
      if (!is_ssl_)
      {
         throw std::logic_error("Session is not SSL/TLS. Cipher info cannot be retrieved.");
      }

      auto ssl_handle = ssl_socket_.native_handle();
      AnsiString name = SSL_get_cipher_name(ssl_handle);
      AnsiString version = SSL_get_version(ssl_handle);
      int bits = SSL_get_cipher_bits(ssl_handle, 0);
      return CipherInfo(name, version, bits);
   }
예제 #12
0
/** wrapper around SSL_accept, usin SSL return convention.
 * It will also log critical errors and certificate debugging info.
 * @param c - tcp connection with tls (extra_data must be a filled
 *            tcp_extra_data structure). The state must be S_TLS_ACCEPTING.
 * @param error  set to the error reason (SSL_ERROR_*).
 *            Note that it can be SSL_ERROR_NONE while the return is < 0
 *            ("internal" error, not at the SSL level, see below).
 * @return >=1 on success, 0 and <0 on error. 0 means the underlying SSL
 *           connection was closed/shutdown.  < 0 is returned for any
 *           SSL_ERROR (including  WANT_READ or WANT_WRITE), but also
 *           for internal non SSL related errors (in this case -2 is
 *           returned and error==SSL_ERROR_NONE).
 *
 */
int tls_accept(struct tcp_connection *c, int* error)
{
	int ret;
	SSL *ssl;
	X509* cert;
	struct tls_extra_data* tls_c;
	int tls_log;

	*error = SSL_ERROR_NONE;
	tls_c=(struct tls_extra_data*)c->extra_data;
	ssl=tls_c->ssl;
	
	if (unlikely(tls_c->state != S_TLS_ACCEPTING)) {
		BUG("Invalid connection state %d (bug in TLS code)\n", tls_c->state);
		goto err;
	}
	ret = SSL_accept(ssl);
	if (unlikely(ret == 1)) {
		DBG("TLS accept successful\n");
		tls_c->state = S_TLS_ESTABLISHED;
		tls_log = cfg_get(tls, tls_cfg, log);
		LOG(tls_log, "tls_accept: new connection from %s:%d using %s %s %d\n",
		    ip_addr2a(&c->rcv.src_ip), c->rcv.src_port,
		    SSL_get_cipher_version(ssl), SSL_get_cipher_name(ssl), 
		    SSL_get_cipher_bits(ssl, 0)
		    );
		LOG(tls_log, "tls_accept: local socket: %s:%d\n", 
		    ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port
		    );
		cert = SSL_get_peer_certificate(ssl);
		if (cert != 0) { 
			tls_dump_cert_info("tls_accept: client certificate", cert);
			if (SSL_get_verify_result(ssl) != X509_V_OK) {
				LOG(tls_log, "WARNING: tls_accept: client certificate "
				    "verification failed!!!\n");
				tls_dump_verification_failure(SSL_get_verify_result(ssl));
			}
			X509_free(cert);
		} else {
			LOG(tls_log, "tls_accept: client did not present a certificate\n");
		}
	} else { /* ret == 0 or < 0 */
		*error = SSL_get_error(ssl, ret);
	}
	return ret;
err:
	/* internal non openssl related errors */
	return -2;
}
예제 #13
0
파일: mutt_ssl.c 프로젝트: Ishpeck/mutt-kz
/* ssl_negotiate: After SSL state has been initialised, attempt to negotiate
 *   SSL over the wire, including certificate checks. */
static int ssl_negotiate (CONNECTION *conn, sslsockdata* ssldata)
{
  int err;
  const char* errmsg;

#if OPENSSL_VERSION_NUMBER >= 0x00906000L
  /* This only exists in 0.9.6 and above. Without it we may get interrupted
   *   reads or writes. Bummer. */
  SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY);
#endif

  if ((err = SSL_connect (ssldata->ssl)) != 1)
  {
    switch (SSL_get_error (ssldata->ssl, err))
    {
    case SSL_ERROR_SYSCALL:
      errmsg = _("I/O error");
      break;
    case SSL_ERROR_SSL:
      errmsg = ERR_error_string (ERR_get_error (), NULL);
      break;
    default:
      errmsg = _("unknown error");
    }

    mutt_error (_("SSL failed: %s"), errmsg);
    mutt_sleep (1);

    return -1;
  }

  ssldata->cert = SSL_get_peer_certificate (ssldata->ssl);
  if (!ssldata->cert)
  {
    mutt_error (_("Unable to get certificate from peer"));
    mutt_sleep (1);
    return -1;
  }

  if (!ssl_check_certificate (conn, ssldata))
    return -1;

  mutt_message (_("%s connection using %s (%s)"),
    SSL_get_version(ssldata->ssl), SSL_get_cipher_version (ssldata->ssl), SSL_get_cipher_name (ssldata->ssl));
  mutt_sleep (0);

  return 0;
}
예제 #14
0
파일: mutt_ssl.c 프로젝트: aschrab/mutt
/* ssl_negotiate: After SSL state has been initialized, attempt to negotiate
 *   SSL over the wire, including certificate checks. */
static int ssl_negotiate (CONNECTION *conn, sslsockdata* ssldata)
{
  int err;
  const char* errmsg;

  SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY);

  if ((err = SSL_connect (ssldata->ssl)) != 1)
  {
    switch (SSL_get_error (ssldata->ssl, err))
    {
    case SSL_ERROR_SYSCALL:
      errmsg = _("I/O error");
      break;
    case SSL_ERROR_SSL:
      errmsg = ERR_error_string (ERR_get_error (), NULL);
      break;
    default:
      errmsg = _("unknown error");
    }

    mutt_error (_("SSL failed: %s"), errmsg);
    mutt_sleep (1);

    return -1;
  }

  ssldata->cert = SSL_get_peer_certificate (ssldata->ssl);
  if (!ssldata->cert)
  {
    mutt_error (_("Unable to get certificate from peer"));
    mutt_sleep (1);
    return -1;
  }

  if (!ssl_check_certificate (conn, ssldata))
    return -1;

  /* L10N:
     %1$s is version (e.g. "TLSv1.2")
     %2$s is cipher_version (e.g. "TLSv1/SSLv3")
     %3$s is cipher_name (e.g. "ECDHE-RSA-AES128-GCM-SHA256") */
  mutt_message (_("%s connection using %s (%s)"),
    SSL_get_version(ssldata->ssl), SSL_get_cipher_version (ssldata->ssl), SSL_get_cipher_name (ssldata->ssl));
  mutt_sleep (0);

  return 0;
}
예제 #15
0
int verify_ssl_cipher(SSL *ssl)
{
	unsigned char *cipher;
#ifdef HAVE_SSLV2_CLIENT_METHOD
	if (SSL_get_ssl_method(ssl) == SSLv2_client_method())
		return S_INSECURE_CIPHER;
#endif
#ifdef HAVE_SSLV3_CLIENT_METHOD
	if (SSL_get_ssl_method(ssl) == SSLv3_client_method())
		return S_INSECURE_CIPHER;
#endif
	if (SSL_get_cipher_bits(ssl, NULL) < 112)
		return S_INSECURE_CIPHER;
	cipher = cast_uchar SSL_get_cipher_name(ssl);
	if (cipher && strstr(cast_const_char cipher, "RC4-"))
		return S_INSECURE_CIPHER;
	return 0;
}
예제 #16
0
void SSL_CTX_info_callback(const SSL* ssl, int where, int ret)
{
    FUNC_ENTRY;

	if (where & SSL_CB_LOOP)
	{
		Log(TRACE_PROTOCOL, 1, "SSL state %s:%s:%s",
                  (where & SSL_ST_CONNECT) ? "connect" : (where & SSL_ST_ACCEPT) ? "accept" : "undef",
                    SSL_state_string_long(ssl), SSL_get_cipher_name(ssl));
	}
	else if (where & SSL_CB_EXIT)
	{
		Log(TRACE_PROTOCOL, 1, "SSL %s:%s",
                  (where & SSL_ST_CONNECT) ? "connect" : (where & SSL_ST_ACCEPT) ? "accept" : "undef",
                    SSL_state_string_long(ssl));
	}
	else if (where & SSL_CB_ALERT)
	{
		Log(TRACE_PROTOCOL, 1, "SSL alert %s:%s:%s",
                  (where & SSL_CB_READ) ? "read" : "write",
                    SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
	}
	else if (where & SSL_CB_HANDSHAKE_START)
	{
		Log(TRACE_PROTOCOL, 1, "SSL handshake started %s:%s:%s",
                  (where & SSL_CB_READ) ? "read" : "write",
                    SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
	}
	else if (where & SSL_CB_HANDSHAKE_DONE)
	{
		Log(TRACE_PROTOCOL, 1, "SSL handshake done %s:%s:%s",
                  (where & SSL_CB_READ) ? "read" : "write",
                    SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
		Log(TRACE_PROTOCOL, 1, "SSL certificate verification: %s",
                    SSL_get_verify_result_string(SSL_get_verify_result(ssl)));
	}
	else
	{
		Log(TRACE_PROTOCOL, 1, "SSL state %s:%s:%s", SSL_state_string_long(ssl),
                   SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
	}
	FUNC_EXIT;
}
예제 #17
0
int ssl_session_vars(SSL *ssl) {
  char *x;
  SSL_SESSION *session;
  int n;
  int m;
  const SSL_CIPHER *cipher;
  unsigned char u;
  unsigned char c;

  if (!env_str("SSL_PROTOCOL",SSL_get_version(ssl)))
    return 0;

  session = SSL_get_session(ssl);
  x = session->session_id;
  n = session->session_id_length;
  if (!stralloc_ready(&btemp,2 * n)) return 0;
  btemp.len = 2 * n;
  while (n--) {
    u = x[n];
    c = '0' + (u & 15); if (c > '0' + 9) c += 'a' - '0' - 10;
    btemp.s[2 * n + 1] = c;
    u >>= 4;
    c = '0' + (u & 15); if (c > '0' + 9) c += 'a' - '0' - 10;
    btemp.s[2 * n] = c;
  }
  if (!env_val("SSL_SESSION_ID",btemp.s,btemp.len)) return 0;

  if (!env_str("SSL_CIPHER",SSL_get_cipher_name(ssl))) return 0;
  
  cipher = SSL_get_current_cipher(ssl);
  if (!cipher) return 0;
  n = SSL_CIPHER_get_bits(cipher,&m);
  if (!env_str("SSL_CIPHER_EXPORT",n < 56 ? "true" : "false")) return 0;
  if (!env_val("SSL_CIPHER_USEKEYSIZE",strnum,fmt_ulong(strnum,n))) return 0;
  if (!env_val("SSL_CIPHER_ALGKEYSIZE",strnum,fmt_ulong(strnum,m))) return 0;

  if (!env_str("SSL_VERSION_INTERFACE","ucspi-ssl")) return 0;
  if (!env_str("SSL_VERSION_LIBRARY",OPENSSL_VERSION_TEXT)) return 0;

  return 1;
}
예제 #18
0
파일: tls_client.c 프로젝트: lra/core
/**
 * We directly initiate a TLS handshake with the server. If the server is old
 * version (does not speak TLS) the connection will be denied.
 * @note the socket file descriptor in #conn_info must be connected and *not*
 *       non-blocking
 * @return -1 in case of error
 */
int TLSTry(ConnectionInfo *conn_info)
{
    /* SSL Context might not be initialised up to now due to lack of keys, as
     * they might be generated as part of the policy (e.g. failsafe.cf). */
    if (!TLSClientInitialize())
    {
        return -1;
    }
    assert(SSLCLIENTCONTEXT != NULL && PRIVKEY != NULL && PUBKEY != NULL);

    ConnectionInfoSetSSL(conn_info, SSL_new(SSLCLIENTCONTEXT));
    SSL *ssl = ConnectionInfoSSL(conn_info);
    if (ssl == NULL)
    {
        Log(LOG_LEVEL_ERR, "SSL_new: %s",
            ERR_reason_error_string(ERR_get_error()));
        return -1;
    }

    /* Pass conn_info inside the ssl struct for TLSVerifyCallback(). */
    SSL_set_ex_data(ssl, CONNECTIONINFO_SSL_IDX, conn_info);

    /* Initiate the TLS handshake over the already open TCP socket. */
    SSL_set_fd(ssl, ConnectionInfoSocket(conn_info));

    int ret = SSL_connect(ssl);
    if (ret <= 0)
    {
        TLSLogError(ssl, LOG_LEVEL_ERR,
                    "Failed to establish TLS connection", ret);
        return -1;
    }

    Log(LOG_LEVEL_VERBOSE, "TLS cipher negotiated: %s, %s",
        SSL_get_cipher_name(ssl),
        SSL_get_cipher_version(ssl));
    Log(LOG_LEVEL_VERBOSE, "TLS session established, checking trust...");

    return 0;
}
예제 #19
0
/**
 * We directly initiate a TLS handshake with the server. If the server is old
 * version (does not speak TLS) the connection will be denied.
 * @note the socket file descriptor in #conn_info must be connected and *not*
 *       non-blocking
 * @return -1 in case of error
 */
int TLSTry(ConnectionInfo *conn_info)
{
    if (PRIVKEY == NULL || PUBKEY == NULL)
    {
        Log(LOG_LEVEL_ERR, "No public/private key pair is loaded,"
            " please create one using cf-key");
        return -1;
    }
    assert(SSLCLIENTCONTEXT != NULL);

    conn_info->ssl = SSL_new(SSLCLIENTCONTEXT);
    if (conn_info->ssl == NULL)
    {
        Log(LOG_LEVEL_ERR, "SSL_new: %s",
            TLSErrorString(ERR_get_error()));
        return -1;
    }

    /* Pass conn_info inside the ssl struct for TLSVerifyCallback(). */
    SSL_set_ex_data(conn_info->ssl, CONNECTIONINFO_SSL_IDX, conn_info);

    /* Initiate the TLS handshake over the already open TCP socket. */
    SSL_set_fd(conn_info->ssl, conn_info->sd);

    int ret = SSL_connect(conn_info->ssl);
    if (ret <= 0)
    {
        TLSLogError(conn_info->ssl, LOG_LEVEL_ERR,
                    "Failed to establish TLS connection", ret);
        return -1;
    }

    Log(LOG_LEVEL_VERBOSE, "TLS version negotiated: %8s; Cipher: %s,%s",
        SSL_get_version(conn_info->ssl),
        SSL_get_cipher_name(conn_info->ssl),
        SSL_get_cipher_version(conn_info->ssl));
    Log(LOG_LEVEL_VERBOSE, "TLS session established, checking trust...");

    return 0;
}
예제 #20
0
const char *
ssl_to_text(const SSL *ssl)
{
	static char	buf[256];
	static char	description[128];
	char	       *tls_version = NULL;

	/*
	 * SSL_get_cipher_version() does not know about the exact TLS version...
	 * you have to pick it up from second field of the SSL cipher description !
	 */
	SSL_CIPHER_description(SSL_get_current_cipher(ssl), description, sizeof description);
	tls_version = strchr(description, ' ') + 1;
	tls_version[strcspn(tls_version, " ")] = '\0';
	(void)snprintf(buf, sizeof buf, "version=%s (%s), cipher=%s, bits=%d",
	    SSL_get_cipher_version(ssl),
	    tls_version,
	    SSL_get_cipher_name(ssl),
	    SSL_get_cipher_bits(ssl, NULL));

	return (buf);
}
bool SSLConnection::doOpen() {
  if (!did_init) return false;

  ctx = SSL_CTX_new (SSLv23_client_method ());

  /* disable SSL protocols as needed */
  if (!UseTLS1) {
    SSL_CTX_set_options (ctx, SSL_OP_NO_TLSv1);
  }
  if (!UseSSL3) {
    SSL_CTX_set_options (ctx, SSL_OP_NO_SSLv3);
  }
  if (!UseTLS1 && !UseSSL3)
    return false;

  getClientCert ();

  ssl = SSL_new (ctx);
  SSL_set_fd (ssl,fd);

  if (!negotiate ())
    return false;

  int maxbits;
  ssf = SSL_CIPHER_get_bits (SSL_get_current_cipher (ssl),&maxbits);

  buffer_t msg;
  buffer_init(&msg);
  buffer_add_str(&msg,_("SSL/TLS connection using "),-1);
  buffer_add_str(&msg,SSL_get_cipher_version(ssl),-1);
  buffer_add_str(&msg," (",2);
  buffer_add_str(&msg,SSL_get_cipher_name(ssl),-1);
  buffer_add_ch(&msg,')');
  displayProgress.emit(&msg);
  buffer_free(&msg);

  return true;
}
예제 #22
0
const char *ma_tls_get_cipher(MARIADB_TLS *ctls)
{
  if (!ctls || !ctls->ssl)
    return NULL;
  return SSL_get_cipher_name(ctls->ssl);
}
예제 #23
0
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
                  ssl_handshake_func_t func,
                  unsigned long *ssl_errno_holder)
{
  int r;
  SSL *ssl;
  my_socket sd= mysql_socket_getfd(vio->mysql_socket);
  DBUG_ENTER("ssl_do");
  DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d  ctx: 0x%lx",
                       (long) ptr, sd, (long) ptr->ssl_context));

  if (!(ssl= SSL_new(ptr->ssl_context)))
  {
    DBUG_PRINT("error", ("SSL_new failure"));
    *ssl_errno_holder= ERR_get_error();
    DBUG_RETURN(1);
  }
  DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
  SSL_clear(ssl);
  SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
  SSL_set_fd(ssl, sd);
#ifndef HAVE_YASSL
  SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
#endif

  /*
    Since yaSSL does not support non-blocking send operations, use
    special transport functions that properly handles non-blocking
    sockets. These functions emulate the behavior of blocking I/O
    operations by waiting for I/O to become available.
  */
#ifdef HAVE_YASSL
  /* Set first argument of the transport functions. */
  yaSSL_transport_set_ptr(ssl, vio);
  /* Set functions to use in order to send and receive data. */
  yaSSL_transport_set_recv_function(ssl, yassl_recv);
  yaSSL_transport_set_send_function(ssl, yassl_send);
#endif

  if ((r= ssl_handshake_loop(vio, ssl, func, ssl_errno_holder)) < 1)
  {
    DBUG_PRINT("error", ("SSL_connect/accept failure"));
    SSL_free(ssl);
    DBUG_RETURN(1);
  }

  /*
    Connection succeeded. Install new function handlers,
    change type, set sd to the fd used when connecting
    and set pointer to the SSL structure
  */
  if (vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), ssl, 0))
    DBUG_RETURN(1);

#ifndef DBUG_OFF
  {
    /* Print some info about the peer */
    X509 *cert;
    char buf[512];

    DBUG_PRINT("info",("SSL connection succeeded"));
    DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));

    if ((cert= SSL_get_peer_certificate (ssl)))
    {
      DBUG_PRINT("info",("Peer certificate:"));
      X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t subject: '%s'", buf));
      X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t issuer: '%s'", buf));
      X509_free(cert);
    }
    else
      DBUG_PRINT("info",("Peer does not have certificate."));

    if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
    {
      DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
    }
    else
      DBUG_PRINT("info",("no shared ciphers!"));
  }
#endif

  DBUG_RETURN(0);
}
예제 #24
0
void http_got_header(struct connection *c, struct read_buffer *rb)
{
    int cf;
    int state = c->state != S_PROC ? S_GETH : S_PROC;
    unsigned char *head;
    unsigned char *cookie, *ch;
    int a, h, version;
    unsigned char *d;
    struct cache_entry *e;
    struct http_connection_info *info;
    unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url);
    set_timeout(c);
    info = c->info;
    if (rb->close == 2) {
        unsigned char *h;
        if (!c->tries && (h = get_host_name(host))) {
            if (info->bl_flags & BL_NO_CHARSET) {
                del_blacklist_entry(h, BL_NO_CHARSET);
            } else {
                add_blacklist_entry(h, BL_NO_CHARSET);
                c->tries = -1;
            }
            mem_free(h);
        }
        setcstate(c, S_CANT_READ);
        retry_connection(c);
        return;
    }
    rb->close = 0;
again:
    if ((a = get_header(rb)) == -1) {
        setcstate(c, S_HTTP_ERROR);
        abort_connection(c);
        return;
    }
    if (!a) {
        read_from_socket(c, c->sock1, rb, http_got_header);
        setcstate(c, state);
        return;
    }
    if (a != -2) {
        head = mem_alloc(a + 1);
        memcpy(head, rb->data, a);
        head[a] = 0;
        kill_buffer_data(rb, a);
    } else {
        head = stracpy("HTTP/0.9 200 OK\r\nContent-Type: text/html\r\n\r\n");
    }
    if (get_http_code(head, &h, &version) || h == 101) {
        mem_free(head);
        setcstate(c, S_HTTP_ERROR);
        abort_connection(c);
        return;
    }
    if (check_http_server_bugs(host, c->info, head) && is_connection_restartable(c)) {
        mem_free(head);
        setcstate(c, S_RESTART);
        retry_connection(c);
        return;
    }
    ch = head;
    while ((cookie = parse_http_header(ch, "Set-Cookie", &ch))) {
        unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url);
        set_cookie(NULL, host, cookie);
        mem_free(cookie);
    }
    if (h == 100) {
        mem_free(head);
        state = S_PROC;
        goto again;
    }
    if (h < 200) {
        mem_free(head);
        setcstate(c, S_HTTP_ERROR);
        abort_connection(c);
        return;
    }
    if (h == 204) {
        mem_free(head);
        setcstate(c, S_HTTP_204);
        http_end_request(c, 0);
        return;
    }
    if (h == 304) {
        mem_free(head);
        setcstate(c, S_OK);
        http_end_request(c, 1);
        return;
    }
    if ((h == 500 || h == 502 || h == 503 || h == 504) && http_bugs.retry_internal_errors && is_connection_restartable(c)) {
        /* !!! FIXME: wait some time ... */
        mem_free(head);
        setcstate(c, S_RESTART);
        retry_connection(c);
        return;
    }
    if (!c->cache && get_cache_entry(c->url, &c->cache)) {
        mem_free(head);
        setcstate(c, S_OUT_OF_MEM);
        abort_connection(c);
        return;
    }
    e = c->cache;
    e->http_code = h;
    if (e->head) mem_free(e->head);
    e->head = head;
    if ((d = parse_http_header(head, "Expires", NULL))) {
        time_t t = parse_http_date(d);
        if (t && e->expire_time != 1) e->expire_time = t;
        mem_free(d);
    }
    if ((d = parse_http_header(head, "Pragma", NULL))) {
        if (!casecmp(d, "no-cache", 8)) e->expire_time = 1;
        mem_free(d);
    }
    if ((d = parse_http_header(head, "Cache-Control", NULL))) {
        char *f = d;
        while (1) {
            while (*f && (*f == ' ' || *f == ',')) f++;
            if (!*f) break;
            if (!casecmp(f, "no-cache", 8) || !casecmp(f, "must-revalidate", 15)) {
                e->expire_time = 1;
            }
            if (!casecmp(f, "max-age=", 8)) {
                if (e->expire_time != 1) e->expire_time = time(NULL) + atoi(f + 8);
            }
            while (*f && *f != ',') f++;
        }
        mem_free(d);
    }
#ifdef HAVE_SSL
    if (c->ssl) {
        int l = 0;
        if (e->ssl_info) mem_free(e->ssl_info);
        e->ssl_info = init_str();
        add_num_to_str(&e->ssl_info, &l, SSL_get_cipher_bits(c->ssl, NULL));
        add_to_str(&e->ssl_info, &l, "-bit ");
        add_to_str(&e->ssl_info, &l, SSL_get_cipher_version(c->ssl));
        add_to_str(&e->ssl_info, &l, " ");
        add_to_str(&e->ssl_info, &l, (unsigned  char *)SSL_get_cipher_name(c->ssl));
    }
#endif
    if (e->redirect) mem_free(e->redirect), e->redirect = NULL;
    if (h == 301 || h == 302 || h == 303 || h == 307) {
        if ((h == 302 || h == 307) && !e->expire_time) e->expire_time = 1;
        if ((d = parse_http_header(e->head, "Location", NULL))) {
            unsigned char *user, *ins;
            unsigned char *newuser, *newpassword;
            if (!parse_url(d, NULL, &user, NULL, NULL, NULL, &ins, NULL, NULL, NULL, NULL, NULL, NULL) && !user && ins && (newuser = get_user_name(host))) {
                if (*newuser) {
                    int ins_off = ins - d;
                    newpassword = get_pass(host);
                    if (!newpassword) newpassword = stracpy("");
                    add_to_strn(&newuser, ":");
                    add_to_strn(&newuser, newpassword);
                    add_to_strn(&newuser, "@");
                    extend_str(&d, strlen(newuser));
                    ins = d + ins_off;
                    memmove(ins + strlen(newuser), ins, strlen(ins) + 1);
                    memcpy(ins, newuser, strlen(newuser));
                    mem_free(newpassword);
                }
                mem_free(newuser);
            }
            if (e->redirect) mem_free(e->redirect);
            e->redirect = d;
            e->redirect_get = h == 303;
        }
    }
    if (!e->expire_time && strchr(c->url, POST_CHAR)) e->expire_time = 1;
    info->close = 0;
    info->length = -1;
    info->version = version;
    if ((d = parse_http_header(e->head, "Connection", NULL)) || (d = parse_http_header(e->head, "Proxy-Connection", NULL))) {
        if (!strcasecmp(d, "close")) info->close = 1;
        mem_free(d);
    } else if (version < 11) info->close = 1;
    cf = c->from;
    c->from = 0;
    if ((d = parse_http_header(e->head, "Content-Range", NULL))) {
        if (strlen(d) > 6) {
            d[5] = 0;
            if (!(strcasecmp(d, "bytes")) && d[6] >= '0' && d[6] <= '9') {
#if defined(HAVE_STRTOLL)
                long long f = strtoll(d + 6, NULL, 10);
#elif defined(HAVE_STRTOQ)
                longlong f = strtoq(d + 6, NULL, 10);
#else
                long f = strtol(d + 6, NULL, 10);
                if (f == MAXLONG) f = -1;
#endif
                if (f >= 0 && (off_t)f >= 0 && (off_t)f == f) c->from = f;
            }
        }
        mem_free(d);
    }
    if (cf && !c->from && !c->unrestartable) c->unrestartable = 1;
    if (c->from > cf || c->from < 0) {
        setcstate(c, S_HTTP_ERROR);
        abort_connection(c);
        return;
    }
    if ((d = parse_http_header(e->head, "Content-Length", NULL))) {
        unsigned char *ep;
#if defined(HAVE_STRTOLL)
        long long l = strtoll(d, (char **)(void *)&ep, 10);
#elif defined(HAVE_STRTOQ)
        longlong l = strtoq(d, (char **)(void *)&ep, 10);
#else
        long l = strtol(d, (char **)(void *)&ep, 10);
        if (l == MAXLONG) l = -1;
#endif
        if (!*ep && l >= 0 && (off_t)l >= 0 && (off_t)l == l) {
            if (!info->close || version >= 11) info->length = l;
            if (c->from + l >= 0) c->est_length = c->from + l;
        }
        mem_free(d);
    }
    if ((d = parse_http_header(e->head, "Accept-Ranges", NULL))) {
        if (!strcasecmp(d, "none") && !c->unrestartable) c->unrestartable = 1;
        mem_free(d);
    } else {
        if (!c->unrestartable && !c->from) c->unrestartable = 1;
    }
    if (info->bl_flags & BL_NO_RANGE && !c->unrestartable) c->unrestartable = 1;
    if ((d = parse_http_header(e->head, "Transfer-Encoding", NULL))) {
        if (!strcasecmp(d, "chunked")) {
            info->length = -2;
            info->chunk_remaining = -1;
        }
        mem_free(d);
    }
    if (!info->close && info->length == -1) info->close = 1;
    if ((d = parse_http_header(e->head, "Last-Modified", NULL))) {
        if (e->last_modified && strcasecmp(e->last_modified, d)) {
            delete_entry_content(e);
            if (c->from) {
                c->from = 0;
                mem_free(d);
                setcstate(c, S_MODIFIED);
                retry_connection(c);
                return;
            }
        }
        if (!e->last_modified) e->last_modified = d;
        else mem_free(d);
    }
    if (!e->last_modified && (d = parse_http_header(e->head, "Date", NULL)))
        e->last_modified = d;
    if (info->length == -1 || (version < 11 && info->close)) rb->close = 1;
    read_http_data(c, rb);
}
예제 #25
0
파일: socket.c 프로젝트: deweerdt/h2o
const char *h2o_socket_get_ssl_cipher(h2o_socket_t *sock)
{
    return sock->ssl != NULL ? SSL_get_cipher_name(sock->ssl->ssl) : NULL;
}
예제 #26
0
const char *
eventer_ssl_get_current_cipher(eventer_ssl_ctx_t *ctx) {
  return SSL_get_cipher_name(ctx->ssl);
}
예제 #27
0
파일: client.c 프로젝트: ProfDrLuigi/zanka
void wr_connect(char *host, int port, char *login, char *password) {
	SHA_CTX					c;
	static unsigned char	hex[] = "0123456789abcdef";
	unsigned char			sha[SHA_DIGEST_LENGTH];
	struct hostent			*hp;
	int						i, on = 1;

	/* disconnect active socket */
	if(wr_socket >= 0)
		wr_close();

	/* reset current working directory */
	strlcpy(wr_files_cwd, "/", sizeof(wr_files_cwd));

	/* copy values */
	wr_port = port;
	
	if(port != 2000)
		snprintf(wr_host, sizeof(wr_host), "%s:%d", host, port);
	else
		strlcpy(wr_host, host, sizeof(wr_host));

	strlcpy(wr_login, login, sizeof(wr_login));
	strlcpy(wr_password, password, sizeof(wr_password));

	/* log */
	wr_printf_prefix("Connecting to %s...\n", wr_host);

	/* create new socket */
	wr_socket = socket(AF_INET, SOCK_STREAM, 0);

	if(wr_socket < 0) {
		wr_printf_prefix("Could not create a socket: %s\n",
			strerror(errno));
		wr_close();

		return;
	}

	/* set socket options */
	if(setsockopt(wr_socket, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) {
		wr_printf_prefix("Could not set socket options: %s\n",
			strerror(errno));
		wr_close();

		return;
	}

	/* init address */
	memset(&wr_addr, 0, sizeof(wr_addr));
	wr_addr.sin_family	= AF_INET;
	wr_addr.sin_port	= htons(port);

	if(!inet_aton(host, &wr_addr.sin_addr)) {
		hp = gethostbyname(host);

		if(!hp) {
			wr_printf_prefix("Could not resolve hostname %s: %s\n",
				host, hstrerror(h_errno));
			wr_close();

			return;
		}

		memcpy(&wr_addr.sin_addr, hp->h_addr, sizeof(wr_addr.sin_addr));
	}

	/* connect TCP socket */
	if(connect(wr_socket, (struct sockaddr *) &wr_addr, sizeof(wr_addr)) < 0) {
		wr_printf_prefix("Could not connect to %s: %s\n",
			host, strerror(errno));
		wr_close();

		return;
	}

	/* create SSL context */
	wr_ssl_ctx = SSL_CTX_new(TLSv1_client_method());

	if(!wr_ssl_ctx) {
		wr_printf_prefix("Could not create SSL context: %s\n",
			ERR_reason_error_string(ERR_get_error()));
		wr_close();

		return;
	}

	if(SSL_CTX_set_cipher_list(wr_ssl_ctx, "ALL") != 1) {
		wr_printf_prefix("Could not set SSL cipher list: %s\n",
			ERR_reason_error_string(ERR_get_error()));
		wr_close();

		return;
	}

	/* create SSL socket */
	wr_ssl = SSL_new(wr_ssl_ctx);

	if(!wr_ssl) {
		wr_printf_prefix("Could not create SSL socket: %s\n",
			ERR_reason_error_string(ERR_get_error()));
		wr_close();

		return;
	}

	if(SSL_set_fd(wr_ssl, wr_socket) != 1) {
		wr_printf_prefix("Could not set SSL file descriptor: %s\n",
			ERR_reason_error_string(ERR_get_error()));
		wr_close();

		return;
	}

	if(SSL_connect(wr_ssl) != 1) {
		wr_printf_prefix("Could not connect to %s via SSL: %s\n",
			host, ERR_reason_error_string(ERR_get_error()));
		wr_close();

		return;
	}

	/* log */
	wr_printf_prefix("Connected using %s/%s/%u bits, logging in...\n",
		SSL_get_cipher_version(wr_ssl),
		SSL_get_cipher_name(wr_ssl),
		SSL_get_cipher_bits(wr_ssl, NULL));

	/* send initial login */
	wr_send_command("HELLO%s", WR_MESSAGE_SEPARATOR);
	
	/* hash the password */
	memset(wr_password_sha, 0, sizeof(wr_password_sha));
	
	if(strlen(wr_password) > 0) {
		SHA1_Init(&c);
		SHA1_Update(&c, (unsigned char *) wr_password, strlen(wr_password));
		SHA1_Final(sha, &c);
	
		/* map into hexademical characters */
		for(i = 0; i < SHA_DIGEST_LENGTH; i++) {
			wr_password_sha[i+i]	= hex[sha[i] >> 4];
			wr_password_sha[i+i+1]	= hex[sha[i] & 0x0F];
		}
			
		wr_password_sha[i+i] = '\0';
	}
예제 #28
0
파일: viossl.c 프로젝트: AllenWeb/mariadb
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
                  int (*connect_accept_func)(SSL*), unsigned long *errptr)
{
  int r;
  SSL *ssl;
  my_bool unused;
  my_bool was_blocking;
  DBUG_ENTER("ssl_do");
  DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d  ctx: 0x%lx",
                       (long) ptr, vio->sd, (long) ptr->ssl_context));

  /* Set socket to blocking if not already set */
  vio_blocking(vio, 1, &was_blocking);

  if (!(ssl= SSL_new(ptr->ssl_context)))
  {
    DBUG_PRINT("error", ("SSL_new failure"));
    *errptr= ERR_get_error();
    vio_blocking(vio, was_blocking, &unused);
    DBUG_RETURN(1);
  }
  DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
  SSL_clear(ssl);
  SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
  SSL_set_fd(ssl, vio->sd);
#if  !defined(HAVE_YASSL) && defined(SSL_OP_NO_COMPRESSION)
  SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
#endif

  if ((r= connect_accept_func(ssl)) < 1)
  {
    DBUG_PRINT("error", ("SSL_connect/accept failure"));
    *errptr= SSL_get_error(ssl, r);
    SSL_free(ssl);
    vio_blocking(vio, was_blocking, &unused);
    DBUG_RETURN(1);
  }

  /*
    Connection succeeded. Install new function handlers,
    change type, set sd to the fd used when connecting
    and set pointer to the SSL structure
  */
  vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), 0, 0);
  vio->ssl_arg= (void*)ssl;

#ifndef DBUG_OFF
  {
    /* Print some info about the peer */
    X509 *cert;
    char buf[512];

    DBUG_PRINT("info",("SSL connection succeeded"));
    DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));

    if ((cert= SSL_get_peer_certificate (ssl)))
    {
      DBUG_PRINT("info",("Peer certificate:"));
      X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t subject: '%s'", buf));
      X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t issuer: '%s'", buf));
      X509_free(cert);
    }
    else
      DBUG_PRINT("info",("Peer does not have certificate."));

    if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
    {
      DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
    }
    else
      DBUG_PRINT("info",("no shared ciphers!"));
  }
#endif

  DBUG_RETURN(0);
}
예제 #29
0
/**
 * @brief Accept a TLS connection and authenticate and identify.
 * @note Various fields in #conn are set, like username and keyhash.
 */
int ServerTLSSessionEstablish(ServerConnectionState *conn)
{
    int ret;

    if (ConnectionInfoConnectionStatus(conn->conn_info) != CF_CONNECTION_ESTABLISHED)
    {
        assert(ConnectionInfoSSL(conn->conn_info) == NULL);
        SSL *ssl = SSL_new(SSLSERVERCONTEXT);
        if (ssl == NULL)
        {
            Log(LOG_LEVEL_ERR, "SSL_new: %s",
                TLSErrorString(ERR_get_error()));
            return -1;
        }
        ConnectionInfoSetSSL(conn->conn_info, ssl);

        /* Pass conn_info inside the ssl struct for TLSVerifyCallback(). */
        SSL_set_ex_data(ssl, CONNECTIONINFO_SSL_IDX, conn->conn_info);

        /* Now we are letting OpenSSL take over the open socket. */
        SSL_set_fd(ssl, ConnectionInfoSocket(conn->conn_info));

        ret = SSL_accept(ssl);
        if (ret <= 0)
        {
            TLSLogError(ssl, LOG_LEVEL_ERR,
                        "Failed to accept TLS connection", ret);
            return -1;
        }

        Log(LOG_LEVEL_VERBOSE, "TLS cipher negotiated: %s, %s",
            SSL_get_cipher_name(ssl),
            SSL_get_cipher_version(ssl));
        Log(LOG_LEVEL_VERBOSE, "TLS session established, checking trust...");

        /* Send/Receive "CFE_v%d" version string, agree on version, receive
           identity (username) of peer. */
        char username[sizeof(conn->username)] = "";
        bool b = ServerIdentificationDialog(conn->conn_info,
                                            username, sizeof(username));
        if (b != true)
        {
            return -1;
        }

        /* We *now* (maybe a bit late) verify the key that the client sent us in
         * the TLS handshake, since we need the username to do so. TODO in the
         * future store keys irrelevant of username, so that we can match them
         * before IDENTIFY. */
        ret = TLSVerifyPeer(conn->conn_info, conn->ipaddr, username);
        if (ret == -1)                                      /* error */
        {
            return -1;
        }

        if (ret == 1)                                    /* trusted key */
        {
            Log(LOG_LEVEL_VERBOSE,
                "%s: Client is TRUSTED, public key MATCHES stored one.",
                KeyPrintableHash(ConnectionInfoKey(conn->conn_info)));
        }

        if (ret == 0)                                  /* untrusted key */
        {
            if ((SV.trustkeylist != NULL) &&
                (IsMatchItemIn(SV.trustkeylist, conn->ipaddr)))
            {
                Log(LOG_LEVEL_VERBOSE,
                    "Peer was found in \"trustkeysfrom\" list");
                Log(LOG_LEVEL_NOTICE, "Trusting new key: %s",
                    KeyPrintableHash(ConnectionInfoKey(conn->conn_info)));

                SavePublicKey(username, KeyPrintableHash(conn->conn_info->remote_key),
                              KeyRSA(ConnectionInfoKey(conn->conn_info)));
            }
            else
            {
                Log(LOG_LEVEL_NOTICE,
                    "TRUST FAILED, peer presented an untrusted key, dropping connection!");
                Log(LOG_LEVEL_VERBOSE,
                    "Add peer to \"trustkeysfrom\" if you really want to start trusting this new key.");
                return -1;
            }
        }

        /* All checks succeeded, set conn->uid (conn->sid for Windows)
         * according to the received USERNAME identity. */
        SetConnIdentity(conn, username);

        /* No CAUTH, SAUTH in non-classic protocol. */
        conn->user_data_set = 1;
        conn->rsa_auth = 1;

        LastSaw1(conn->ipaddr, KeyPrintableHash(ConnectionInfoKey(conn->conn_info)),
                 LAST_SEEN_ROLE_ACCEPT);

        ServerSendWelcome(conn);
    }
    return 1;
}
예제 #30
0
/******************************************************************************
 ******************************************************************************
 ** Higher Level SSL_CTX Wrappers                                            **
 ******************************************************************************
 ******************************************************************************/
static void
log_callback(const SSL *ssl, int where, int ret)
{
    const char *retstr = "";
    int should_log = 0;
    lcbio_SOCKET *sock = SSL_get_app_data(ssl);
    /* Ignore low-level SSL stuff */

    if (where & SSL_CB_ALERT) {
        should_log = 1;
    }
    if (where == SSL_CB_HANDSHAKE_START || where == SSL_CB_HANDSHAKE_DONE) {
        should_log = 1;
    }
    if ((where & SSL_CB_EXIT) && ret == 0) {
        should_log = 1;
    }

    if (!should_log) {
        return;
    }

    retstr = SSL_alert_type_string(ret);
    lcb_log(LOGARGS(ssl, LCB_LOG_TRACE), "sock=%p: ST(0x%x). %s. R(0x%x)%s",
        (void*)sock, where, SSL_state_string_long(ssl), ret, retstr);

    if (where == SSL_CB_HANDSHAKE_DONE) {
        lcb_log(LOGARGS(ssl, LCB_LOG_DEBUG), "sock=%p. Using SSL version %s. Cipher=%s", (void*)sock, SSL_get_version(ssl), SSL_get_cipher_name(ssl));
    }
}