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