From 63419660b973188de959c5c59d6f787a41b0c8d4 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Wed, 7 Jan 2015 14:40:40 -0800 Subject: [PATCH] Removed AES and Blowfish support for SASL. --- src/common/hexchat.h | 6 +- src/common/inbound.c | 54 +++-------- src/common/util.c | 223 ------------------------------------------- src/common/util.h | 2 - 4 files changed, 15 insertions(+), 270 deletions(-) diff --git a/src/common/hexchat.h b/src/common/hexchat.h index a5b61a26..b4e8e3b9 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -422,11 +422,9 @@ typedef struct session void (*scrollback_replay_marklast) (struct session *sess); } session; -/* SASL Mechanisms */ +/* SASL mechanisms. Used as an index in sasl_mechanisms array in inbound.c. */ #define MECH_PLAIN 0 -#define MECH_BLOWFISH 1 -#define MECH_AES 2 -#define MECH_EXTERNAL 3 +#define MECH_EXTERNAL 1 typedef struct server { diff --git a/src/common/inbound.c b/src/common/inbound.c index db68c64c..e70a9433 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -48,6 +48,11 @@ #include "hexchatc.h" #include "chanopt.h" +static const char *sasl_mechanisms [] = +{ + "PLAIN", + "EXTERNAL" +}; void clear_channel (session *sess) @@ -1684,18 +1689,16 @@ inbound_cap_ack (server *serv, char *nick, char *extensions, if (serv->loginmethod == LOGIN_SASLEXTERNAL) { serv->sasl_mech = MECH_EXTERNAL; - tcp_send_len (serv, "AUTHENTICATE EXTERNAL\r\n", 23); } else { - /* default to most secure, it will fallback if not supported */ - serv->sasl_mech = MECH_AES; - tcp_send_len (serv, "AUTHENTICATE DH-AES\r\n", 21); + serv->sasl_mech = MECH_PLAIN; } #else serv->sasl_mech = MECH_PLAIN; - tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20); #endif + + tcp_sendf (serv, "AUTHENTICATE %s\r\n", sasl_mechanisms[serv->sasl_mech]); } } @@ -1817,32 +1820,15 @@ inbound_cap_list (server *serv, char *nick, char *extensions, NULL, NULL, 0, tags_data->timestamp); } -static const char *sasl_mechanisms[] = -{ - "PLAIN", - "DH-BLOWFISH", - "DH-AES", - "EXTERNAL" -}; - void inbound_sasl_supportedmechs (server *serv, char *list) { - int i; - - if (serv->sasl_mech != MECH_EXTERNAL) + if (serv->sasl_mech != MECH_EXTERNAL && strstr (list, sasl_mechanisms[MECH_PLAIN]) != NULL) { - /* Use most secure one supported */ - for (i = MECH_AES; i >= MECH_PLAIN; i--) - { - if (strstr (list, sasl_mechanisms[i]) != NULL) - { - serv->sasl_mech = i; - serv->retry_sasl = TRUE; - tcp_sendf (serv, "AUTHENTICATE %s\r\n", sasl_mechanisms[i]); - return; - } - } + serv->sasl_mech = MECH_PLAIN; + serv->retry_sasl = TRUE; + tcp_sendf (serv, "AUTHENTICATE %s\r\n", sasl_mechanisms[MECH_PLAIN]); + return; } /* Abort, none supported */ @@ -1876,12 +1862,6 @@ inbound_sasl_authenticate (server *serv, char *data) pass = encode_sasl_pass_plain (user, serv->password); break; #ifdef USE_OPENSSL - case MECH_BLOWFISH: - pass = encode_sasl_pass_blowfish (user, serv->password, data); - break; - case MECH_AES: - pass = encode_sasl_pass_aes (user, serv->password, data); - break; case MECH_EXTERNAL: pass = g_strdup ("+"); break; @@ -1911,13 +1891,5 @@ inbound_sasl_error (server *serv) if (serv->retry_sasl && !serv->sent_saslauth) return 1; - /* If server sent 904 before we sent password, - * mech not support so fallback to next mech */ - if (!serv->sent_saslauth && serv->sasl_mech != MECH_EXTERNAL && serv->sasl_mech != MECH_PLAIN) - { - serv->sasl_mech -= 1; - tcp_sendf (serv, "AUTHENTICATE %s\r\n", sasl_mechanisms[serv->sasl_mech]); - return 1; - } return 0; } diff --git a/src/common/util.c b/src/common/util.c index 37d214c0..c5692dcf 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -56,8 +56,6 @@ #ifdef USE_OPENSSL #include #include -#include -#include #ifndef WIN32 #include #endif @@ -1488,227 +1486,6 @@ encode_sasl_pass_plain (char *user, char *pass) return encoded; } -#ifdef USE_OPENSSL -/* Adapted from ZNC's SASL module */ - -static int -parse_dh (char *str, DH **dh_out, unsigned char **secret_out, int *keysize_out) -{ - DH *dh; - guchar *data, *decoded_data; - guchar *secret = NULL; - gsize data_len; - guint size; - guint16 size16; - BIGNUM *pubkey; - gint key_size; - - dh = DH_new(); - data = decoded_data = g_base64_decode (str, &data_len); - if (data_len < 2) - goto fail; - - /* prime number */ - memcpy (&size16, data, sizeof(size16)); - size = ntohs (size16); - data += 2; - data_len -= 2; - - if (size > data_len) - goto fail; - - dh->p = BN_bin2bn (data, size, NULL); - data += size; - - /* Generator */ - if (data_len < 2) - goto fail; - - memcpy (&size16, data, sizeof(size16)); - size = ntohs (size16); - data += 2; - data_len -= 2; - - if (size > data_len) - goto fail; - - dh->g = BN_bin2bn (data, size, NULL); - data += size; - - /* pub key */ - if (data_len < 2) - goto fail; - - memcpy (&size16, data, sizeof(size16)); - size = ntohs(size16); - data += 2; - data_len -= 2; - - pubkey = BN_bin2bn (data, size, NULL); - if (!(DH_generate_key (dh))) - goto fail; - - secret = g_malloc (DH_size (dh)); - key_size = DH_compute_key (secret, pubkey, dh); - if (key_size == -1) - goto fail; - - g_free (decoded_data); - - *dh_out = dh; - *secret_out = secret; - *keysize_out = key_size; - return 1; - -fail: - g_free (secret); - g_free (decoded_data); - - return 0; -} - -char * -encode_sasl_pass_blowfish (char *user, char *pass, char *data) -{ - DH *dh; - char *response, *ret = NULL; - unsigned char *secret; - unsigned char *encrypted_pass; - char *plain_pass; - BF_KEY key; - int key_size, length; - int pass_len = strlen (pass) + (8 - (strlen (pass) % 8)); - int user_len = strlen (user); - guint16 size16; - char *in_ptr, *out_ptr; - - if (!parse_dh (data, &dh, &secret, &key_size)) - return NULL; - BF_set_key (&key, key_size, secret); - - encrypted_pass = g_malloc0 (pass_len); - plain_pass = g_malloc0 (pass_len); - memcpy (plain_pass, pass, strlen(pass)); - out_ptr = (char*)encrypted_pass; - in_ptr = (char*)plain_pass; - - for (length = pass_len; length; length -= 8, in_ptr += 8, out_ptr += 8) - BF_ecb_encrypt ((unsigned char*)in_ptr, (unsigned char*)out_ptr, &key, BF_ENCRYPT); - - /* Create response */ - length = 2 + BN_num_bytes (dh->pub_key) + pass_len + user_len + 1; - response = g_malloc0 (length); - out_ptr = response; - - /* our key */ - size16 = htons ((guint16)BN_num_bytes (dh->pub_key)); - memcpy (out_ptr, &size16, sizeof(size16)); - out_ptr += 2; - BN_bn2bin (dh->pub_key, (guchar*)out_ptr); - out_ptr += BN_num_bytes (dh->pub_key); - - /* username */ - memcpy (out_ptr, user, user_len + 1); - out_ptr += user_len + 1; - - /* pass */ - memcpy (out_ptr, encrypted_pass, pass_len); - - ret = g_base64_encode ((const guchar*)response, length); - - g_free (response); - - DH_free(dh); - g_free (plain_pass); - g_free (encrypted_pass); - g_free (secret); - - return ret; -} - -char * -encode_sasl_pass_aes (char *user, char *pass, char *data) -{ - DH *dh; - AES_KEY key; - char *response = NULL; - char *out_ptr, *ret = NULL; - unsigned char *secret, *ptr; - unsigned char *encrypted_userpass, *plain_userpass; - int key_size, length; - guint16 size16; - unsigned char iv[16], iv_copy[16]; - int user_len = strlen (user) + 1; - int pass_len = strlen (pass) + 1; - int len = user_len + pass_len; - int padlen = 16 - (len % 16); - int userpass_len = len + padlen; - - if (!parse_dh (data, &dh, &secret, &key_size)) - return NULL; - - encrypted_userpass = g_malloc0 (userpass_len); - plain_userpass = g_malloc0 (userpass_len); - - /* create message */ - /* format of: \0\0 */ - ptr = plain_userpass; - memcpy (ptr, user, user_len); - ptr += user_len; - memcpy (ptr, pass, pass_len); - ptr += pass_len; - if (padlen) - { - /* Padding */ - unsigned char randbytes[16]; - if (!RAND_bytes (randbytes, padlen)) - goto end; - - memcpy (ptr, randbytes, padlen); - } - - if (!RAND_bytes (iv, sizeof (iv))) - goto end; - - memcpy (iv_copy, iv, sizeof(iv)); - - /* Encrypt */ - AES_set_encrypt_key (secret, key_size * 8, &key); - AES_cbc_encrypt(plain_userpass, encrypted_userpass, userpass_len, &key, iv_copy, AES_ENCRYPT); - - /* Create response */ - /* format of: */ - length = 2 + key_size + sizeof(iv) + userpass_len; - response = g_malloc (length); - out_ptr = response; - - /* our key */ - size16 = htons ((guint16)key_size); - memcpy (out_ptr, &size16, sizeof(size16)); - out_ptr += 2; - BN_bn2bin (dh->pub_key, (guchar*)out_ptr); - out_ptr += key_size; - - /* iv */ - memcpy (out_ptr, iv, sizeof(iv)); - out_ptr += sizeof(iv); - - /* userpass */ - memcpy (out_ptr, encrypted_userpass, userpass_len); - - ret = g_base64_encode ((const guchar*)response, length); - -end: - DH_free (dh); - g_free (plain_userpass); - g_free (encrypted_userpass); - g_free (secret); - g_free (response); - - return ret; -} -#endif - #ifdef USE_OPENSSL static char * str_sha256hash (char *string) diff --git a/src/common/util.h b/src/common/util.h index 8b2762fb..2220026b 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -76,8 +76,6 @@ void canonalize_key (char *key); int portable_mode (void); int unity_mode (void); char *encode_sasl_pass_plain (char *user, char *pass); -char *encode_sasl_pass_blowfish (char *user, char *pass, char *data); -char *encode_sasl_pass_aes (char *user, char *pass, char *data); char *challengeauth_response (char *username, char *password, char *challenge); size_t strftime_validated (char *dest, size_t destsize, const char *format, const struct tm *time); size_t strftime_utf8 (char *dest, size_t destsize, const char *format, time_t time);