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_NICKSERV:
|
||||||
case LOGIN_NS:
|
case LOGIN_NS:
|
||||||
case LOGIN_MSG_NS:
|
case LOGIN_MSG_NS:
|
||||||
|
case LOGIN_CHALLENGEAUTH:
|
||||||
|
#if 0
|
||||||
case LOGIN_AUTH:
|
case LOGIN_AUTH:
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -67,43 +67,49 @@ irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3)
|
||||||
/* are all ircd authors idiots? */
|
/* are all ircd authors idiots? */
|
||||||
switch (serv->loginmethod)
|
switch (serv->loginmethod)
|
||||||
{
|
{
|
||||||
case LOGIN_MSG_NICKSERV:
|
case LOGIN_MSG_NICKSERV:
|
||||||
tcp_sendf (serv, "PRIVMSG NICKSERV :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
tcp_sendf (serv, "PRIVMSG NICKSERV :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||||
break;
|
break;
|
||||||
case LOGIN_NICKSERV:
|
case LOGIN_NICKSERV:
|
||||||
tcp_sendf (serv, "NICKSERV %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
tcp_sendf (serv, "NICKSERV %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||||
break;
|
break;
|
||||||
|
case LOGIN_MSG_NS:
|
||||||
|
tcp_sendf (serv, "PRIVMSG NS :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||||
|
break;
|
||||||
#if 0
|
#if 0
|
||||||
case LOGIN_NS:
|
case LOGIN_NS:
|
||||||
tcp_sendf (serv, "NS %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
tcp_sendf (serv, "NS %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
|
||||||
break;
|
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
|
#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
|
static void
|
||||||
irc_ns_identify (server *serv, char *pass)
|
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, "");
|
case LOGIN_CHALLENGEAUTH:
|
||||||
}
|
tcp_sendf (serv, "PRIVMSG %s :CHALLENGE\r\n", CHALLENGEAUTH_NICK); /* request a challenge from Q */
|
||||||
else
|
break;
|
||||||
{
|
#if 0
|
||||||
irc_nickserv (serv, "IDENTIFY", pass, "", "");
|
case LOGIN_AUTH:
|
||||||
|
irc_nickserv (serv, "", serv->nick, pass, "");
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
irc_nickserv (serv, "IDENTIFY", pass, "", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_ns_ghost (server *serv, char *usname, char *pass)
|
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);
|
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'):
|
case WORDL('N','O','T','I'):
|
||||||
{
|
{
|
||||||
int id = FALSE; /* identified */
|
int id = FALSE; /* identified */
|
||||||
|
char *response;
|
||||||
|
|
||||||
text = word_eol[4];
|
text = word_eol[4];
|
||||||
if (*text == ':')
|
if (*text == ':')
|
||||||
|
{
|
||||||
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)
|
if (serv->have_idmsg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -426,7 +426,7 @@ static const struct defaultserver def[] =
|
||||||
{0, "nfsi.ptnet.org"},
|
{0, "nfsi.ptnet.org"},
|
||||||
{0, "fctunl.ptnet.org"},
|
{0, "fctunl.ptnet.org"},
|
||||||
|
|
||||||
{"QuakeNet", 0, 0, 0, LOGIN_AUTH},
|
{"QuakeNet", 0, 0, 0, LOGIN_CHALLENGEAUTH},
|
||||||
{0, "irc.quakenet.org"},
|
{0, "irc.quakenet.org"},
|
||||||
{0, "irc.se.quakenet.org"},
|
{0, "irc.se.quakenet.org"},
|
||||||
{0, "irc.dk.quakenet.org"},
|
{0, "irc.dk.quakenet.org"},
|
||||||
|
|
|
@ -75,6 +75,10 @@ extern GSList *network_list;
|
||||||
#define LOGIN_AUTH 5
|
#define LOGIN_AUTH 5
|
||||||
#define LOGIN_SASL 6
|
#define LOGIN_SASL 6
|
||||||
#define LOGIN_PASS 7
|
#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 */
|
/* DEFAULT_CHARSET is already defined in wingdi.h */
|
||||||
#define IRC_DEFAULT_CHARSET "UTF-8 (Unicode)"
|
#define IRC_DEFAULT_CHARSET "UTF-8 (Unicode)"
|
||||||
|
|
|
@ -1978,3 +1978,64 @@ find_font (const char *fontname)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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 ();
|
int unity_mode ();
|
||||||
GSList *get_subdirs (const char *path);
|
GSList *get_subdirs (const char *path);
|
||||||
char *encode_sasl_pass (char *user, char *pass);
|
char *encode_sasl_pass (char *user, char *pass);
|
||||||
|
char *challengeauth_response (char *username, char *password, char *challenge);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -121,11 +121,12 @@ static int login_types_conf[] =
|
||||||
LOGIN_PASS,
|
LOGIN_PASS,
|
||||||
LOGIN_MSG_NICKSERV,
|
LOGIN_MSG_NICKSERV,
|
||||||
LOGIN_NICKSERV,
|
LOGIN_NICKSERV,
|
||||||
|
LOGIN_MSG_NS,
|
||||||
|
LOGIN_CHALLENGEAUTH
|
||||||
#if 0
|
#if 0
|
||||||
LOGIN_NS,
|
LOGIN_NS,
|
||||||
#endif
|
|
||||||
LOGIN_MSG_NS,
|
|
||||||
LOGIN_AUTH,
|
LOGIN_AUTH,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *login_types[]=
|
static const char *login_types[]=
|
||||||
|
@ -135,11 +136,12 @@ static const char *login_types[]=
|
||||||
"Server Password (/PASS password)",
|
"Server Password (/PASS password)",
|
||||||
"NickServ (/MSG NickServ + password)",
|
"NickServ (/MSG NickServ + password)",
|
||||||
"NickServ (/NICKSERV + password)",
|
"NickServ (/NICKSERV + password)",
|
||||||
|
"NickServ (/MSG NS + password)",
|
||||||
|
"Challenge Auth (username + password)",
|
||||||
#if 0
|
#if 0
|
||||||
"NickServ (/NS + password)",
|
"NickServ (/NS + password)",
|
||||||
#endif
|
|
||||||
"NickServ (/MSG NS + password)",
|
|
||||||
"AUTH (/AUTH nickname password)",
|
"AUTH (/AUTH nickname password)",
|
||||||
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue