mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-11 08:20:17 +00:00
Added support for SCRAM-SHA-1, SCRAM-SHA-256 and SCRAM-SHA-512
This commit is contained in:
committed by
Patrick Griffis
parent
6420fd6117
commit
9b76b557ec
@@ -1648,7 +1648,10 @@ inbound_identified (server *serv) /* 'MODE +e MYSELF' on freenode */
|
||||
static const char *sasl_mechanisms[] =
|
||||
{
|
||||
"PLAIN",
|
||||
"EXTERNAL"
|
||||
"EXTERNAL",
|
||||
"SCRAM-SHA-1",
|
||||
"SCRAM-SHA-256",
|
||||
"SCRAM-SHA-512"
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -1689,6 +1692,12 @@ inbound_toggle_caps (server *serv, const char *extensions_str, gboolean enable)
|
||||
#ifdef USE_OPENSSL
|
||||
if (serv->loginmethod == LOGIN_SASLEXTERNAL)
|
||||
serv->sasl_mech = MECH_EXTERNAL;
|
||||
else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_1)
|
||||
serv->sasl_mech = MECH_SCRAM_SHA_1;
|
||||
else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_256)
|
||||
serv->sasl_mech = MECH_SCRAM_SHA_256;
|
||||
else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_512)
|
||||
serv->sasl_mech = MECH_SCRAM_SHA_512;
|
||||
#endif
|
||||
/* Mechanism either defaulted to PLAIN or server gave us list */
|
||||
tcp_sendf (serv, "AUTHENTICATE %s\r\n", sasl_mechanisms[serv->sasl_mech]);
|
||||
@@ -1766,6 +1775,30 @@ get_supported_mech (server *serv, const char *list)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_1)
|
||||
{
|
||||
if (!strcmp(mechs[i], "SCRAM-SHA-1"))
|
||||
{
|
||||
ret = MECH_SCRAM_SHA_1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_256)
|
||||
{
|
||||
if (!strcmp(mechs[i], "SCRAM-SHA-256"))
|
||||
{
|
||||
ret = MECH_SCRAM_SHA_256;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_512)
|
||||
{
|
||||
if (!strcmp(mechs[i], "SCRAM-SHA-512"))
|
||||
{
|
||||
ret = MECH_SCRAM_SHA_512;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!strcmp (mechs[i], "PLAIN"))
|
||||
@@ -1821,7 +1854,11 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str,
|
||||
|
||||
/* if the SASL password is set AND auth mode is set to SASL, request SASL auth */
|
||||
if (!g_strcmp0 (extension, "sasl") &&
|
||||
((serv->loginmethod == LOGIN_SASL && strlen (serv->password) != 0)
|
||||
(((serv->loginmethod == LOGIN_SASL
|
||||
|| serv->loginmethod == LOGIN_SASL_SCRAM_SHA_1
|
||||
|| serv->loginmethod == LOGIN_SASL_SCRAM_SHA_256
|
||||
|| serv->loginmethod == LOGIN_SASL_SCRAM_SHA_512)
|
||||
&& strlen (serv->password) != 0)
|
||||
|| serv->loginmethod == LOGIN_SASLEXTERNAL))
|
||||
{
|
||||
if (value)
|
||||
@@ -1902,7 +1939,7 @@ inbound_cap_list (server *serv, char *nick, char *extensions,
|
||||
}
|
||||
|
||||
static void
|
||||
plain_authenticate(server *serv, char *user, char *password)
|
||||
plain_authenticate (server *serv, char *user, char *password)
|
||||
{
|
||||
char *pass = encode_sasl_pass_plain (user, password);
|
||||
|
||||
@@ -1933,11 +1970,71 @@ plain_authenticate(server *serv, char *user, char *password)
|
||||
tcp_sendf (serv, "AUTHENTICATE +\r\n");
|
||||
}
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
/*
|
||||
* Sends AUTHENTICATE messages to log in via SCRAM.
|
||||
*/
|
||||
static void
|
||||
scram_authenticate (server *serv, const char *data, const char *digest,
|
||||
const char *user, const char *password)
|
||||
{
|
||||
char *encoded, *decoded, *output;
|
||||
scram_status status;
|
||||
size_t output_len;
|
||||
gsize decoded_len;
|
||||
|
||||
if (serv->scram_session == NULL)
|
||||
{
|
||||
serv->scram_session = scram_create_session (digest, user, password);
|
||||
|
||||
if (serv->scram_session == NULL)
|
||||
{
|
||||
PrintTextf (serv->server_session, _("Could not create SCRAM session with digest %s"), digest);
|
||||
g_warning ("Could not create SCRAM session with digest %s", digest);
|
||||
tcp_sendf (serv, "AUTHENTICATE *\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
decoded = g_base64_decode (data, &decoded_len);
|
||||
status = scram_process (serv->scram_session, decoded, &output, &output_len);
|
||||
g_free (decoded);
|
||||
|
||||
if (status == SCRAM_IN_PROGRESS)
|
||||
{
|
||||
// Authentication is still in progress
|
||||
encoded = g_base64_encode ((guchar *) output, output_len);
|
||||
tcp_sendf (serv, "AUTHENTICATE %s\r\n", encoded);
|
||||
g_free (encoded);
|
||||
g_free (output);
|
||||
}
|
||||
else if (status == SCRAM_SUCCESS)
|
||||
{
|
||||
// Authentication succeeded
|
||||
tcp_sendf (serv, "AUTHENTICATE +\r\n");
|
||||
g_clear_pointer (&serv->scram_session, scram_free_session);
|
||||
}
|
||||
else if (status == SCRAM_ERROR)
|
||||
{
|
||||
// Authentication failed
|
||||
tcp_sendf (serv, "AUTHENTICATE *\r\n");
|
||||
|
||||
if (serv->scram_session->error != NULL)
|
||||
{
|
||||
PrintTextf (serv->server_session, _("SASL SCRAM authentication failed: %s"), serv->scram_session->error);
|
||||
g_info ("SASL SCRAM authentication failed: %s", serv->scram_session->error);
|
||||
}
|
||||
|
||||
g_clear_pointer (&serv->scram_session, scram_free_session);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
inbound_sasl_authenticate (server *serv, char *data)
|
||||
{
|
||||
ircnet *net = (ircnet*)serv->network;
|
||||
char *user, *pass = NULL;
|
||||
char *user;
|
||||
const char *mech = sasl_mechanisms[serv->sasl_mech];
|
||||
|
||||
/* Got a list of supported mechanisms from outdated inspircd
|
||||
@@ -1959,6 +2056,15 @@ inbound_sasl_authenticate (server *serv, char *data)
|
||||
case MECH_EXTERNAL:
|
||||
tcp_sendf (serv, "AUTHENTICATE +\r\n");
|
||||
break;
|
||||
case MECH_SCRAM_SHA_1:
|
||||
scram_authenticate(serv, data, "SHA1", user, serv->password);
|
||||
return;
|
||||
case MECH_SCRAM_SHA_256:
|
||||
scram_authenticate(serv, data, "SHA256", user, serv->password);
|
||||
return;
|
||||
case MECH_SCRAM_SHA_512:
|
||||
scram_authenticate(serv, data, "SHA512", user, serv->password);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1969,6 +2075,9 @@ inbound_sasl_authenticate (server *serv, char *data)
|
||||
void
|
||||
inbound_sasl_error (server *serv)
|
||||
{
|
||||
#ifdef USE_OPENSSL
|
||||
g_clear_pointer (&serv->scram_session, scram_free_session);
|
||||
#endif
|
||||
/* Just abort, not much we can do */
|
||||
tcp_sendf (serv, "AUTHENTICATE *\r\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user