]> jfr.im git - irc/quakenet/newserv.git/blame - ticketauth/ticketauth.c
Fix timing attacks in HMAC functions.
[irc/quakenet/newserv.git] / ticketauth / ticketauth.c
CommitLineData
c2234094
CP
1/* ticketauth.c */
2
3#include <stdio.h>
4#include <string.h>
5#include <strings.h>
6
7#include "../control/control.h"
8#include "../core/config.h"
9#include "../nick/nick.h"
10#include "../core/error.h"
893267ed 11#include "../lib/hmac.h"
c2234094 12#include "../lib/version.h"
893267ed 13#include "../localuser/localuser.h"
c2234094
CP
14#include "../core/hooks.h"
15#include "../irc/irc.h"
dbbee796
CP
16
17#define CS_NODB
3294b10b 18#include "../chanserv/chanserv.h"
c2234094 19
f20f0b80 20#define WARN_CHANNEL "#twilightzone"
c2234094 21
70b0a4e5 22MODULE_VERSION("");
c2234094
CP
23
24sstring *sharedsecret = NULL;
25
c2234094
CP
26int ta_ticketauth(void *source, int cargc, char **cargv) {
27 nick *np = (nick *)source;
3294b10b 28 char buffer[1024], *uhmac, *acc, *junk, *flags;
893267ed
CP
29 unsigned char digest[32];
30 int expiry, acclen, id;
31 hmacsha256 hmac;
32 channel *wcp;
c2234094
CP
33
34 if(IsAccount(np)) {
35 controlreply(np, "You're already authed.");
36 return CMD_ERROR;
37 }
38
e1bca874
CP
39 if(cargc != 6) {
40 controlreply(np, "%d\n", cargc);
c2234094 41 return CMD_USAGE;
e1bca874 42 }
c2234094 43
893267ed 44 acc = cargv[0];
f20f0b80 45 expiry = atoi(cargv[1]);
893267ed 46 id = atoi(cargv[2]);
c2234094 47 acclen = strlen(acc);
3294b10b
CP
48 flags = cargv[3];
49 junk = cargv[4];
50 uhmac = cargv[5];
f5ec1838 51
c2234094
CP
52 if((acclen <= 1) || (acclen > ACCOUNTLEN)) {
53 controlreply(np, "Bad account.");
54 return CMD_ERROR;
55 }
56
f20f0b80 57 if(time(NULL) > expiry + 30) {
c2234094
CP
58 controlwall(NO_OPER, NL_MISC, "%s!%s@%s attempted to TICKETAUTH as %s (expired)", np->nick, np->ident, np->host->name->content, acc);
59 controlreply(np, "Ticket time is bad or has expired.");
60 return CMD_ERROR;
61 }
c2234094 62
893267ed 63 hmacsha256_init(&hmac, (unsigned char *)sharedsecret->content, sharedsecret->length);
e1bca874 64 snprintf(buffer, sizeof(buffer), "%s %d %d %s %s", acc, expiry, id, flags, junk);
893267ed
CP
65 hmacsha256_update(&hmac, (unsigned char *)buffer, strlen(buffer));
66 hmacsha256_final(&hmac, digest);
c2234094 67
893267ed
CP
68 /* hahahaha */
69 snprintf(buffer, sizeof(buffer), "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15], digest[16], digest[17], digest[18], digest[19], digest[20], digest[21], digest[22], digest[23], digest[24], digest[25], digest[26], digest[27], digest[28], digest[29], digest[30], digest[31]);
c2234094 70
0bd91417 71 if(hmac_strcmp(buffer, uhmac)) {
c2234094
CP
72 controlwall(NO_OPER, NL_MISC, "%s!%s@%s attempted to TICKETAUTH as %s (bad HMAC)", np->nick, np->ident, np->host->name->content, acc);
73 controlreply(np, "Bad HMAC.");
74 return CMD_ERROR;
75 }
76
77 controlwall(NO_OPER, NL_MISC, "%s!%s@%s TICKETAUTH'ed as %s", np->nick, np->ident, np->host->name->content, acc);
893267ed
CP
78
79 wcp = findchannel(WARN_CHANNEL);
80 if(wcp)
81 controlchanmsg(wcp, "WARNING: %s!%s@%s TICKETAUTH'ed as %s", np->nick, np->ident, np->host->name->content, acc);
82
c2234094
CP
83 controlreply(np, "Ticket valid, authing. . .");
84
e1bca874 85 localusersetaccount(np, acc, id, cs_accountflagmap_str(flags), 0);
c2234094 86
893267ed 87 controlreply(np, "Done.");
c2234094
CP
88 return CMD_OK;
89}
90
893267ed 91void _init() {
c2234094
CP
92 sharedsecret = getcopyconfigitem("ticketauth", "sharedsecret", "", 512);
93 if(!sharedsecret || !sharedsecret->content || !sharedsecret->content[0]) {
94 Error("ticketauth", ERR_ERROR, "Shared secret not defined in config file.");
95 if(sharedsecret) {
96 freesstring(sharedsecret);
97 sharedsecret = NULL;
98 }
99
100 return;
101 }
102
e1bca874 103 registercontrolhelpcmd("ticketauth", NO_OPERED, 6, ta_ticketauth, "Usage: ticketauth <ticket>");
c2234094
CP
104}
105
106void _fini() {
107 if(!sharedsecret)
108 return;
109
110 deregistercontrolcmd("ticketauth", ta_ticketauth);
111
112 freesstring(sharedsecret);
113}