Removed AES and Blowfish support for SASL.

This commit is contained in:
Arnavion 2015-01-07 14:40:40 -08:00
parent 7739c99f3f
commit 63419660b9
4 changed files with 15 additions and 270 deletions

View File

@ -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
{

View File

@ -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;
}

View File

@ -56,8 +56,6 @@
#ifdef USE_OPENSSL
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/blowfish.h>
#include <openssl/aes.h>
#ifndef WIN32
#include <netinet/in.h>
#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: <username>\0<password>\0<padding> */
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: <size pubkey><pubkey><iv (always 16 bytes)><ciphertext> */
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)

View File

@ -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);