mirror of
https://github.com/moparisthebest/hexchat
synced 2024-11-22 09:12:22 -05:00
Add support for QuakeNet /CHALLENGEAUTH, remove legacy /AUTH
This commit is contained in:
parent
096d0660e2
commit
a1a94ed319
@ -1380,7 +1380,10 @@ inbound_nickserv_login (server *serv)
|
||||
case LOGIN_NICKSERV:
|
||||
case LOGIN_NS:
|
||||
case LOGIN_MSG_NS:
|
||||
case LOGIN_CHALLENGEAUTH:
|
||||
#if 0
|
||||
case LOGIN_AUTH:
|
||||
#endif
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -67,43 +67,49 @@ irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3)
|
||||
/* are all ircd authors idiots? */
|
||||
switch (serv->loginmethod)
|
||||
{
|
||||
case LOGIN_MSG_NICKSERV:
|
||||
tcp_sendf (serv, "PRIVMSG NICKSERV :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case LOGIN_NICKSERV:
|
||||
tcp_sendf (serv, "NICKSERV %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case LOGIN_MSG_NICKSERV:
|
||||
tcp_sendf (serv, "PRIVMSG NICKSERV :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case LOGIN_NICKSERV:
|
||||
tcp_sendf (serv, "NICKSERV %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case LOGIN_MSG_NS:
|
||||
tcp_sendf (serv, "PRIVMSG NS :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
#if 0
|
||||
case LOGIN_NS:
|
||||
tcp_sendf (serv, "NS %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case LOGIN_NS:
|
||||
tcp_sendf (serv, "NS %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case LOGIN_AUTH:
|
||||
/* why couldn't QuakeNet implement one of the existing ones? */
|
||||
tcp_sendf (serv, "AUTH %s %s\r\n", arg1, arg2);
|
||||
break;
|
||||
#endif
|
||||
case LOGIN_MSG_NS:
|
||||
tcp_sendf (serv, "PRIVMSG NS :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||
break;
|
||||
case LOGIN_AUTH:
|
||||
/* why couldn't QuakeNet implement one of the existing ones? */
|
||||
tcp_sendf (serv, "AUTH %s %s\r\n", arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
irc_ns_identify (server *serv, char *pass)
|
||||
{
|
||||
if (serv->loginmethod == LOGIN_AUTH) /* QuakeNet needs to do everything in its own ways... */
|
||||
switch (serv->loginmethod)
|
||||
{
|
||||
irc_nickserv (serv, "", serv->nick, pass, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
irc_nickserv (serv, "IDENTIFY", pass, "", "");
|
||||
case LOGIN_CHALLENGEAUTH:
|
||||
tcp_sendf (serv, "PRIVMSG %s :CHALLENGE\r\n", CHALLENGEAUTH_NICK); /* request a challenge from Q */
|
||||
break;
|
||||
#if 0
|
||||
case LOGIN_AUTH:
|
||||
irc_nickserv (serv, "", serv->nick, pass, "");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
irc_nickserv (serv, "IDENTIFY", pass, "", "");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
irc_ns_ghost (server *serv, char *usname, char *pass)
|
||||
{
|
||||
if (serv->loginmethod != LOGIN_AUTH)
|
||||
if (serv->loginmethod != LOGIN_AUTH && serv->loginmethod != LOGIN_CHALLENGEAUTH)
|
||||
{
|
||||
irc_nickserv (serv, "GHOST", usname, " ", pass);
|
||||
}
|
||||
@ -1080,11 +1086,21 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[])
|
||||
|
||||
case WORDL('N','O','T','I'):
|
||||
{
|
||||
int id = FALSE; /* identified */
|
||||
int id = FALSE; /* identified */
|
||||
char *response;
|
||||
|
||||
text = word_eol[4];
|
||||
if (*text == ':')
|
||||
{
|
||||
text++;
|
||||
}
|
||||
|
||||
if (!strncmp (text, "CHALLENGE ", 10)) /* QuakeNet CHALLENGEAUTH upon our request */
|
||||
{
|
||||
response = challengeauth_response (((ircnet *)serv->network)->user, serv->password, word[5]);
|
||||
tcp_sendf (serv, "PRIVMSG %s :CHALLENGEAUTH %s %s %s\r\n", CHALLENGEAUTH_NICK, ((ircnet *)serv->network)->user, response, CHALLENGEAUTH_ALGO);
|
||||
g_free (response);
|
||||
}
|
||||
|
||||
if (serv->have_idmsg)
|
||||
{
|
||||
|
@ -426,7 +426,7 @@ static const struct defaultserver def[] =
|
||||
{0, "nfsi.ptnet.org"},
|
||||
{0, "fctunl.ptnet.org"},
|
||||
|
||||
{"QuakeNet", 0, 0, 0, LOGIN_AUTH},
|
||||
{"QuakeNet", 0, 0, 0, LOGIN_CHALLENGEAUTH},
|
||||
{0, "irc.quakenet.org"},
|
||||
{0, "irc.se.quakenet.org"},
|
||||
{0, "irc.dk.quakenet.org"},
|
||||
|
@ -75,6 +75,10 @@ extern GSList *network_list;
|
||||
#define LOGIN_AUTH 5
|
||||
#define LOGIN_SASL 6
|
||||
#define LOGIN_PASS 7
|
||||
#define LOGIN_CHALLENGEAUTH 8
|
||||
|
||||
#define CHALLENGEAUTH_ALGO "HMAC-SHA-256"
|
||||
#define CHALLENGEAUTH_NICK "Q@CServe.quakenet.org"
|
||||
|
||||
/* DEFAULT_CHARSET is already defined in wingdi.h */
|
||||
#define IRC_DEFAULT_CHARSET "UTF-8 (Unicode)"
|
||||
|
@ -1978,3 +1978,64 @@ find_font (const char *fontname)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *
|
||||
str_sha256hash (char *string)
|
||||
{
|
||||
int i;
|
||||
unsigned char hash[SHA256_DIGEST_LENGTH];
|
||||
char buf[SHA256_DIGEST_LENGTH * 2 + 1]; /* 64 digit hash + '\0' */
|
||||
SHA256_CTX sha256;
|
||||
|
||||
SHA256_Init (&sha256);
|
||||
SHA256_Update (&sha256, string, strlen (string));
|
||||
SHA256_Final (hash, &sha256);
|
||||
|
||||
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
|
||||
{
|
||||
sprintf (buf + (i * 2), "%02x", hash[i]);
|
||||
}
|
||||
|
||||
buf[SHA256_DIGEST_LENGTH * 2] = 0;
|
||||
|
||||
return g_strdup (buf);
|
||||
}
|
||||
|
||||
char *
|
||||
challengeauth_response (char *username, char *password, char *challenge)
|
||||
{
|
||||
int i;
|
||||
char *user;
|
||||
char *pass;
|
||||
char *passhash;
|
||||
char *key;
|
||||
char *keyhash;
|
||||
unsigned char *digest;
|
||||
GString *buf = g_string_new_len (NULL, SHA256_DIGEST_LENGTH * 2);
|
||||
|
||||
user = g_strdup (username);
|
||||
*user = rfc_tolower (*username); /* convert username to lowercase as per the RFC*/
|
||||
|
||||
pass = g_strndup (password, 10); /* truncate to 10 characters */
|
||||
passhash = str_sha256hash (pass);
|
||||
g_free (pass);
|
||||
|
||||
key = g_strdup_printf ("%s:%s", user, passhash);
|
||||
g_free (user);
|
||||
g_free (passhash);
|
||||
|
||||
keyhash = str_sha256hash (key);
|
||||
g_free (key);
|
||||
|
||||
digest = HMAC (EVP_sha256 (), keyhash, strlen (keyhash), (unsigned char *) challenge, strlen (challenge), NULL, NULL);
|
||||
g_free (keyhash);
|
||||
|
||||
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
|
||||
{
|
||||
g_string_append_printf (buf, "%02x", (unsigned int) digest[i]);
|
||||
}
|
||||
|
||||
digest = (unsigned char *) g_string_free (buf, FALSE);
|
||||
|
||||
return (char *) digest;
|
||||
}
|
||||
|
@ -80,5 +80,6 @@ int portable_mode ();
|
||||
int unity_mode ();
|
||||
GSList *get_subdirs (const char *path);
|
||||
char *encode_sasl_pass (char *user, char *pass);
|
||||
char *challengeauth_response (char *username, char *password, char *challenge);
|
||||
|
||||
#endif
|
||||
|
@ -121,11 +121,12 @@ static int login_types_conf[] =
|
||||
LOGIN_PASS,
|
||||
LOGIN_MSG_NICKSERV,
|
||||
LOGIN_NICKSERV,
|
||||
LOGIN_MSG_NS,
|
||||
LOGIN_CHALLENGEAUTH
|
||||
#if 0
|
||||
LOGIN_NS,
|
||||
#endif
|
||||
LOGIN_MSG_NS,
|
||||
LOGIN_AUTH,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const char *login_types[]=
|
||||
@ -135,11 +136,12 @@ static const char *login_types[]=
|
||||
"Server Password (/PASS password)",
|
||||
"NickServ (/MSG NickServ + password)",
|
||||
"NickServ (/NICKSERV + password)",
|
||||
"NickServ (/MSG NS + password)",
|
||||
"Challenge Auth (username + password)",
|
||||
#if 0
|
||||
"NickServ (/NS + password)",
|
||||
#endif
|
||||
"NickServ (/MSG NS + password)",
|
||||
"AUTH (/AUTH nickname password)",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user