diff --git a/Changes b/Changes index 93a7d44fb..7124918b1 100644 --- a/Changes +++ b/Changes @@ -1587,3 +1587,5 @@ seen. gmtime warning still there you send commands like JOIN from a server directly - Made channel keys be case sensitive - Fixed a bug with /who -h in some cases, found by Zer0, fixed by butter (#0000361) +- Changed auth method sslpubkey into sslclientcert, which means it will check the X509 certificate of the + user using X509_cmp. Also needing is some policy/conf setting to adjust if to reject invalid client certificates or whatever.. diff --git a/include/auth.h b/include/auth.h index d8f9eb2dd..522590bb5 100644 --- a/include/auth.h +++ b/include/auth.h @@ -28,13 +28,13 @@ typedef struct { #define AUTHTYPE_UNIXCRYPT 1 #define AUTHTYPE_MD5 2 #define AUTHTYPE_SHA1 3 -#define AUTHTYPE_SSL_PUBKEY 4 +#define AUTHTYPE_SSL_CLIENTCERT 4 #define AUTHTYPE_RIPEMD160 5 #ifdef USE_SSL #define AUTHENABLE_MD5 #define AUTHENABLE_SHA1 -#define AUTHENABLE_SSL_PUBKEY +#define AUTHENABLE_SSL_CLIENTCERT #define AUTHENABLE_RIPEMD160 /* OpenSSL provides a crypt() */ #ifndef AUTHENABLE_UNIXCRYPT diff --git a/src/auth.c b/src/auth.c index 3d1e45431..eccd67d6b 100644 --- a/src/auth.c +++ b/src/auth.c @@ -52,8 +52,8 @@ anAuthStruct AuthTypes[] = { #ifdef AUTHENABLE_SHA1 {"sha1", AUTHTYPE_SHA1}, #endif -#ifdef AUTHENABLE_SSL_PUBKEY - {"sslpubkey", AUTHTYPE_SSL_PUBKEY}, +#ifdef AUTHENABLE_SSL_CLIENTCERT + {"sslclientcert", AUTHTYPE_SSL_CLIENTCERT}, #endif #ifdef AUTHENABLE_RIPEMD160 {"ripemd160", AUTHTYPE_RIPEMD160}, @@ -145,11 +145,10 @@ int Auth_Check(aClient *cptr, anAuthStruct *as, char *para) int i; #endif -#ifdef AUTHENABLE_SSL_PUBKEY - EVP_PKEY *evp_pkey = NULL; - EVP_PKEY *evp_pkeyfile = NULL; - X509 *x509_client = NULL; - FILE *key_file = NULL; +#ifdef AUTHENABLE_SSL_CLIENTCERT + X509 *x509_clientcert = NULL; + X509 *x509_filecert = NULL; + FILE *x509_f = NULL; #endif if (!as) return 1; @@ -281,43 +280,35 @@ int Auth_Check(aClient *cptr, anAuthStruct *as, char *para) return -1; break; #endif -#ifdef AUTHENABLE_SSL_PUBKEY - case AUTHTYPE_SSL_PUBKEY: +#ifdef AUTHENABLE_SSL_CLIENTCERT + case AUTHTYPE_SSL_CLIENTCERT: if (!para) return -1; if (!cptr->ssl) return -1; - x509_client = SSL_get_peer_certificate((SSL *)cptr->ssl); - if (!x509_client) + x509_clientcert = SSL_get_peer_certificate((SSL *)cptr->ssl); + if (!x509_clientcert) return -1; - evp_pkey = X509_get_pubkey(x509_client); - if (!(key_file = fopen(para, "r"))) + if (!(x509_f = fopen(as->data, "r"))) { - EVP_PKEY_free(evp_pkey); - X509_free(x509_client); + X509_free(x509_clientcert); return -1; } - evp_pkeyfile = PEM_read_PUBKEY(key_file, NULL, - NULL, NULL); - if (!evp_pkeyfile) + x509_filecert = PEM_read_X509(x509_f, NULL, NULL, NULL); + fclose(x509_f); + if (!x509_filecert) { - fclose(key_file); - EVP_PKEY_free(evp_pkey); - X509_free(x509_client); + X509_free(x509_clientcert); return -1; } - if (!(EVP_PKEY_cmp_parameters(evp_pkeyfile, evp_pkey))) + if (X509_cmp(x509_filecert, x509_clientcert) != 0) { - fclose(key_file); - EVP_PKEY_free(evp_pkey); - EVP_PKEY_free(evp_pkeyfile); - X509_free(x509_client); - return -1; + X509_free(x509_clientcert); + X509_free(x509_filecert); + break; } - fclose(key_file); - EVP_PKEY_free(evp_pkey); - EVP_PKEY_free(evp_pkeyfile); - X509_free(x509_client); + X509_free(x509_clientcert); + X509_free(x509_filecert); return 2; #endif } diff --git a/src/ssl.c b/src/ssl.c index 75bf0acdd..0e30ea3ad 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -147,6 +147,12 @@ int ssl_pem_passwd_cb(char *buf, int size, int rwflag, void *password) return 0; } +static int ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) +{ + return 1; +} + + void init_ctx_server(void) { ctx_server = SSL_CTX_new(SSLv23_server_method()); @@ -157,6 +163,8 @@ void init_ctx_server(void) } SSL_CTX_set_default_passwd_cb(ctx_server, ssl_pem_passwd_cb); SSL_CTX_set_options(ctx_server, SSL_OP_NO_SSLv2); + SSL_CTX_set_verify(ctx_server, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, ssl_verify_callback); + if (SSL_CTX_use_certificate_file(ctx_server, SSL_SERVER_CERT_PEM, SSL_FILETYPE_PEM) <= 0) { ircd_log(LOG_ERROR, "Failed to load SSL certificate %s", SSL_SERVER_CERT_PEM); @@ -175,6 +183,7 @@ void init_ctx_server(void) } } + void init_ctx_client(void) { ctx_client = SSL_CTX_new(SSLv3_client_method());