X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconn-ssl.c;h=5d44b30f07708e46d0221c4ba227f20f1bc7d853;hp=cd7abd4bd38dcf79d688e448a9acecb98234dad5;hb=c0d059cd0ed4403e50820437d9a4cce1648c6b5a;hpb=125c05fba0315da143c3431a41bd930fcb992501 diff --git a/src/ngircd/conn-ssl.c b/src/ngircd/conn-ssl.c index cd7abd4b..5d44b30f 100644 --- a/src/ngircd/conn-ssl.c +++ b/src/ngircd/conn-ssl.c @@ -1,11 +1,15 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * - * SSL wrapper functions. * Copyright (c) 2005-2008 Florian Westphal */ #include "portab.h" + +/** + * @file + * SSL wrapper functions + */ + #include "imp.h" #include "conf-ssl.h" @@ -47,10 +51,11 @@ static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c )); #include #include -#define DH_BITS 1024 +#define DH_BITS 2048 +#define DH_BITS_MIN 1024 + static gnutls_certificate_credentials_t x509_cred; static gnutls_dh_params_t dh_params; - static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void )); #endif @@ -123,7 +128,10 @@ pem_passwd_cb(char *buf, int size, int rwflag, void *password) { array *pass = password; int passlen; - assert(rwflag == 0); /* 0 -> callback used for decryption. See SSL_CTX_set_default_passwd_cb(3) */ + + (void)rwflag; /* rwflag is unused if DEBUG is not set. */ + assert(rwflag == 0); /* 0 -> callback used for decryption. + * See SSL_CTX_set_default_passwd_cb(3) */ passlen = (int) array_bytes(pass); @@ -148,7 +156,7 @@ Load_DH_params(void) bool ret = true; if (!Conf_SSLOptions.DHFile) { - Log(LOG_NOTICE, "Configuration option \"SSLDHFile\" not set"); + Log(LOG_NOTICE, "Configuration option \"SSLDHFile\" not set!"); return false; } fp = fopen(Conf_SSLOptions.DHFile, "r"); @@ -158,7 +166,8 @@ Load_DH_params(void) } dh_params = PEM_read_DHparams(fp, NULL, NULL, NULL); if (!dh_params) { - Log(LOG_ERR, "%s: PEM_read_DHparams failed", Conf_SSLOptions.DHFile); + Log(LOG_ERR, "%s: PEM_read_DHparams failed!", + Conf_SSLOptions.DHFile); ret = false; } fclose(fp); @@ -191,7 +200,9 @@ Load_DH_params(void) } } if (need_dhgenerate) { - Log(LOG_WARNING, "SSLDHFile not set, generating %u bit DH parameters. This may take a while...", DH_BITS); + Log(LOG_WARNING, + "SSLDHFile not set, generating %u bit DH parameters. This may take a while ...", + DH_BITS); err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS); if (err < 0) { Log(LOG_ERR, "gnutls_dh_params_generate2: %s", gnutls_strerror(err)); @@ -222,7 +233,8 @@ void ConnSSL_Free(CONNECTION *c) } #endif assert(Conn_OPTION_ISSET(c, CONN_SSL)); - Conn_OPTION_DEL(c, (CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE)); + /* can't just set bitmask to 0 -- there are other, non-ssl related flags, e.g. CONN_ZIP. */ + Conn_OPTION_DEL(c, CONN_SSL_FLAGS_ALL); } @@ -260,7 +272,7 @@ ConnSSL_InitLibrary( void ) SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE); SSL_CTX_free(ssl_ctx); ssl_ctx = newctx; - Log(LOG_INFO, "%s initialized", SSLeay_version(SSLEAY_VERSION)); + Log(LOG_INFO, "%s initialized.", SSLeay_version(SSLEAY_VERSION)); return true; out: SSL_CTX_free(newctx); @@ -279,7 +291,7 @@ out: } if (!ConnSSL_LoadServerKey_gnutls()) return false; - Log(LOG_INFO, "gnutls %s initialized", gnutls_check_version(NULL)); + Log(LOG_INFO, "gnutls %s initialized.", gnutls_check_version(NULL)); initialized = true; return true; #endif @@ -301,12 +313,13 @@ ConnSSL_LoadServerKey_gnutls(void) cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile; if (!cert_file) { - Log(LOG_ERR, "Neither Key nor certificate File set"); + Log(LOG_NOTICE, "No SSL server key configured, SSL disabled."); return false; } if (array_bytes(&Conf_SSLOptions.KeyFilePassword)) - Log(LOG_WARNING, "Ignoring KeyFilePassword: Not supported by GNUTLS"); + Log(LOG_WARNING, + "Ignoring KeyFilePassword: Not supported by GNUTLS."); if (!Load_DH_params()) return false; @@ -331,7 +344,7 @@ ConnSSL_LoadServerKey_openssl(SSL_CTX *ctx) assert(ctx); if (!Conf_SSLOptions.KeyFile) { - Log(LOG_NOTICE, "No SSL Server Key configured, ssl disabled"); + Log(LOG_NOTICE, "No SSL server key configured, SSL disabled."); return false; } @@ -375,10 +388,10 @@ ConnSSL_Init_SSL(CONNECTION *c) int ret; assert(c != NULL); #ifdef HAVE_LIBSSL - assert(ssl_ctx); - if (!ssl_ctx) /* NULL when library initialization failed */ + if (!ssl_ctx) { + Log(LOG_ERR, "Cannot init ssl_ctx: OpenSSL initialization failed at startup"); return false; - + } assert(c->ssl_state.ssl == NULL); c->ssl_state.ssl = SSL_new(ssl_ctx); @@ -399,6 +412,7 @@ ConnSSL_Init_SSL(CONNECTION *c) if (ret < 0) { Log(LOG_ERR, "gnutls_set_default_priority: %s", gnutls_strerror(ret)); ConnSSL_Free(c); + return false; } /* * The intermediate (long) cast is here to avoid a warning like: @@ -411,8 +425,9 @@ ConnSSL_Init_SSL(CONNECTION *c) if (ret < 0) { Log(LOG_ERR, "gnutls_credentials_set: %s", gnutls_strerror(ret)); ConnSSL_Free(c); + return false; } - gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS); + gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS_MIN); #endif Conn_OPTION_ADD(c, CONN_SSL); return true; @@ -425,10 +440,7 @@ ConnSSL_PrepareConnect(CONNECTION *c, UNUSED CONF_SERVER *s) bool ret; #ifdef HAVE_LIBGNUTLS int err; -#endif - assert(c != NULL); - assert(s != NULL); -#ifdef HAVE_LIBGNUTLS + err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_CLIENT); if (err) { Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err)); @@ -463,8 +475,6 @@ ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname ) unsigned long sslerr; int real_errno = errno; - assert( fname ); - ret = SSL_get_error(c->ssl_state.ssl, code); switch (ret) { case SSL_ERROR_WANT_READ: @@ -476,8 +486,8 @@ ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname ) Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE); /* fall through */ case SSL_ERROR_NONE: return 0; /* try again later */ - case SSL_ERROR_ZERO_RETURN: /* TLS/SSL Connection was shut down */ - LogOpenSSLError("TLS/SSL Connection shutdown", fname); + case SSL_ERROR_ZERO_RETURN: + LogDebug("TLS/SSL connection shut down normally"); break; /* SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_X509_LOOKUP @@ -510,15 +520,14 @@ ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname ) switch (code) { case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: - if (gnutls_record_get_direction(c->ssl_state.gnutls_session)) { /* need write */ - io_event_del(c->sock, IO_WANTREAD); - Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE); /* fall through */ - break; - } else { /* need read */ - io_event_del(c->sock, IO_WANTWRITE); - Conn_OPTION_ADD(c, CONN_SSL_WANT_READ); + if (gnutls_record_get_direction(c->ssl_state.gnutls_session)) { + Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE); + io_event_del(c->sock, IO_WANTREAD); + } else { + Conn_OPTION_ADD(c, CONN_SSL_WANT_READ); + io_event_del(c->sock, IO_WANTWRITE); + } break; - } default: assert(code < 0); if (gnutls_error_is_fatal(code)) { @@ -538,19 +547,20 @@ ConnSSL_LogCertInfo( CONNECTION *c ) #ifdef HAVE_LIBSSL SSL *ssl = c->ssl_state.ssl; - assert( c ); - assert( ssl ); + assert(ssl); - Log( LOG_INFO, "New %s connection using cipher %s on socket %d", - SSL_get_version(ssl), SSL_get_cipher(ssl), c->sock); + Log(LOG_INFO, "Connection %d: initialized %s using cipher %s.", + c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl)); #endif #ifdef HAVE_LIBGNUTLS gnutls_session_t sess = c->ssl_state.gnutls_session; gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess); - Log( LOG_INFO, "New %s connection using cipher %s-%s on socket %d", - gnutls_protocol_get_name(gnutls_protocol_get_version(sess)), - gnutls_cipher_get_name(cipher), gnutls_mac_get_name(gnutls_mac_get(sess)), c->sock); + Log(LOG_INFO, "Connection %d: initialized %s using cipher %s-%s.", + c->sock, + gnutls_protocol_get_name(gnutls_protocol_get_version(sess)), + gnutls_cipher_get_name(cipher), + gnutls_mac_get_name(gnutls_mac_get(sess))); #endif } @@ -566,11 +576,8 @@ int ConnSSL_Accept( CONNECTION *c ) { assert(c != NULL); -#ifdef HAVE_LIBSSL - if (!c->ssl_state.ssl) { -#endif -#ifdef HAVE_LIBGNUTLS if (!Conn_OPTION_ISSET(c, CONN_SSL)) { +#ifdef HAVE_LIBGNUTLS int err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_SERVER); if (err) { Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err)); @@ -592,9 +599,7 @@ ConnSSL_Connect( CONNECTION *c ) #ifdef HAVE_LIBSSL assert(c->ssl_state.ssl); #endif -#ifdef HAVE_LIBGNUTLS assert(Conn_OPTION_ISSET(c, CONN_SSL)); -#endif return ConnectAccept(c, true); } @@ -614,7 +619,6 @@ ConnectAccept( CONNECTION *c, bool connect) #endif #ifdef HAVE_LIBGNUTLS (void) connect; - assert(Conn_OPTION_ISSET(c, CONN_SSL)); ret = gnutls_handshake(c->ssl_state.gnutls_session); if (ret) return ConnSSL_HandleError(c, ret, "gnutls_handshake"); @@ -639,7 +643,8 @@ ConnSSL_Write(CONNECTION *c, const void *buf, size_t count) #ifdef HAVE_LIBGNUTLS bw = gnutls_write(c->ssl_state.gnutls_session, buf, count); #endif - if ( bw > 0 ) return bw; + if (bw > 0) + return bw; if (ConnSSL_HandleError( c, bw, "ConnSSL_Write") == 0) errno = EAGAIN; /* try again */ return -1; @@ -676,11 +681,8 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len) { #ifdef HAVE_LIBSSL char *nl; + SSL *ssl = c->ssl_state.ssl; - SSL *ssl; - assert(c != NULL); - assert(len >= 128); - ssl = c->ssl_state.ssl; if (!ssl) return false; *buf = 0; @@ -691,8 +693,6 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len) return true; #endif #ifdef HAVE_LIBGNUTLS - assert(c != NULL); - assert(len >= 128); if (Conn_OPTION_ISSET(c, CONN_SSL)) { const char *name_cipher, *name_mac, *name_proto, *name_keyexchange; unsigned keysize;