5480c380df187f9fca3c0e14d785e0f80d56feef
[iauth.git] / iauth_cmd.c
1 /*
2  * Written by David Herrmann.
3  * Dedicated to the Public Domain.
4  */
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <errno.h>
10
11 #include "iauth.h"
12
13 char iauth_servname[IAUTH_DATALEN + 1];
14
15 static char *iauth_next_data(char **arg) {
16     char *sep, *ret;
17     unsigned int len;
18
19     while(**arg == ' ') ++*arg;
20     if(!**arg) return NULL;
21     if(**arg == ':' || !(sep = strchr(*arg, ' '))) {
22         if(**arg == ':') ++*arg;
23         len = strlen(*arg);
24         ret = iauth_malloc(len + 1);
25         strcpy(ret, *arg);
26         *arg += len;
27         if(len > IAUTH_DATALEN) ret[IAUTH_DATALEN] = 0;
28         else ret[len] = 0;
29         return ret;
30     }
31     else {
32         *sep = 0;
33         len = strlen(*arg);
34         ret = iauth_malloc(len + 1);
35         strcpy(ret, *arg);
36         if(len > IAUTH_DATALEN) ret[IAUTH_DATALEN] = 0;
37         else ret[len] = 0;
38         *sep = ' ';
39         *arg = sep + 1;
40         return ret;
41     }
42 }
43
44 /* Client Introduction: <id> C <remoteip> <remoteport> <localip> <localport> */
45 void iauth_cmd_C(signed int id, char *arg) {
46     char *str;
47     struct iauth_client *cli;
48
49     iauth_delid(id);
50     iauth_addid(id);
51     cli = &iauth_clients[id];
52
53     str = iauth_next_data(&arg);
54     if(!str) goto parse_error;
55     iauth_set(cli->ip, str);
56
57     str = iauth_next_data(&arg);
58     if(!str) goto parse_error;
59     cli->port = atoi(str);
60     iauth_free(str);
61
62     str = iauth_next_data(&arg);
63     if(!str) goto parse_error;
64     iauth_set(cli->lo_ip, str);
65
66     str = iauth_next_data(&arg);
67     if(!str) goto parse_error;
68     cli->lo_port = atoi(str);
69     iauth_free(str);
70
71     iauth_flog(IAUTH_INFO, "New client (%d) from '%s':%hu to '%s':%hu.", id, cli->ip, cli->port, cli->lo_ip, cli->lo_port);
72
73     return;
74     parse_error:
75     iauth_flog(IAUTH_WARNING, "Parse error: Invalid C line.");
76     iauth_delid(id);
77     return;
78 }
79
80 /* Client Disconnect: <id> D */
81 void iauth_cmd_D(struct iauth_client *client) {
82     iauth_delid(client->id);
83 }
84
85 /* Login On Connect: <id> L <account>[:<accountstamp>][ <fakehost>] */
86 void iauth_cmd_L(struct iauth_client *client, char *arg) {
87     char *str;
88     const struct iauth_result *res;
89
90     str = iauth_next_data(&arg);
91     if(!str) goto parse_error;
92     iauth_set(client->account, str);
93
94     str = iauth_next_data(&arg);
95     if(str) iauth_set(client->fakehost, str);
96
97     /* Query database for account query. */
98     res = iauth_query(client);
99     if(!res) {
100         iauth_query_reject(client->id, "Access denied.");
101         iauth_stats_loc_deny();
102     }
103     else {
104         if(*res->ident) iauth_query_set_username(client->id, res->ident);
105         if(*res->host) iauth_query_sethost(client->id, res->host);
106         if(*res->ip) iauth_query_setip(client->id, res->ip);
107         if(*res->modes) iauth_query_setmodes(client->id, res->modes);
108         iauth_query_assign(client->id, (*res->cclass)?res->cclass:NULL);
109         iauth_stats_loc_allow();
110     }
111
112     iauth_delid(client->id);
113
114     return;
115     parse_error:
116     iauth_flog(IAUTH_WARNING, "Parse error: Invalid L line.");
117     return;
118 }
119
120 /* Hurry Up: <id> H <class> */
121 void iauth_cmd_H(struct iauth_client *client, char *arg) {
122     char *str;
123     const struct iauth_result *res;
124
125     str = iauth_next_data(&arg);
126     if(!str) goto parse_error;
127     iauth_set(client->cclass, str);
128     client->state_h = 1;
129
130     /* Query database for account query. */
131     res = iauth_query(client);
132     if(!res) {
133         iauth_query_reject(client->id, "Access denied.");
134         iauth_stats_def_deny();
135     }
136     else {
137         if(*res->ident) iauth_query_set_username(client->id, res->ident);
138         if(*res->host) iauth_query_sethost(client->id, res->host);
139         if(*res->ip) iauth_query_setip(client->id, res->ip);
140         if(*res->modes) iauth_query_setmodes(client->id, res->modes);
141         iauth_query_assign(client->id, (*res->cclass)?res->cclass:NULL);
142         iauth_stats_def_allow();
143     }
144     iauth_delid(client->id);
145
146     return;
147     parse_error:
148     iauth_flog(IAUTH_WARNING, "Parse error: Invalid H line.");
149     return;
150 }
151
152 /* Server Name and Capacity: <id> M <servername> <capacity> */
153 void iauth_cmd_M(char *arg) {
154     char *server = NULL, *str = NULL;
155     unsigned int cap;
156
157     server = iauth_next_data(&arg);
158     if(!server) goto parse_error;
159
160     str = iauth_next_data(&arg);
161     if(!str || !*str || (cap = atoi(str)) == 0) goto parse_error;
162     iauth_setcap(cap);
163     iauth_flog(IAUTH_INFO, "Setting server (%s) capacity to: %u.", server, cap);
164     strcpy(iauth_servname, server);
165     iauth_free(str);
166     iauth_free(server);
167
168     return;
169     parse_error:
170     iauth_flog(IAUTH_WARNING, "Parse error: Invalid M line.");
171     iauth_free(server);
172     iauth_free(str);
173     return;
174 }
175
176 /* Hostname Received: <id> N <hostname> */
177 void iauth_cmd_N(struct iauth_client *client, char *arg) {
178     char *str;
179
180     str = iauth_next_data(&arg);
181     if(!str) goto parse_error;
182     iauth_set(client->host, str);
183
184     return;
185     parse_error:
186     iauth_flog(IAUTH_WARNING, "Parse error: Invalid N line.");
187     return;
188 }
189
190 /* Hostname Timeout: <id> d */
191 void iauth_cmd_d(struct iauth_client *client) {
192     char *str;
193
194     str = iauth_malloc(1);
195     iauth_set(client->host, str);
196
197     return;
198 }
199
200 /* Client Password: <id> P :<password ...> */
201 void iauth_cmd_P(struct iauth_client *client, char *arg) {
202     char *str;
203
204     str = iauth_next_data(&arg);
205     if(!str) goto parse_error;
206     iauth_set(client->password, str);
207
208     return;
209     parse_error:
210     iauth_flog(IAUTH_WARNING, "Parse error: Invalid P line.");
211     return;
212 }
213
214 /* Client Username: <id> U <username> <hostname> <servername> :<userinfo ...> */
215 void iauth_cmd_U(struct iauth_client *client, char *arg) {
216     char *str;
217
218     str = iauth_next_data(&arg);
219     if(!str) goto parse_error;
220     iauth_set(client->username, str);
221
222     str = iauth_next_data(&arg);
223     if(!str) goto parse_error;
224     iauth_set(client->c_host, str);
225
226     str = iauth_next_data(&arg);
227     if(!str) goto parse_error;
228     iauth_set(client->c_serv, str);
229
230     str = iauth_next_data(&arg);
231     if(!str) goto parse_error;
232     iauth_set(client->realname, str);
233
234     return;
235     parse_error:
236     iauth_flog(IAUTH_WARNING, "Parse error: Invalid U line.");
237     return;
238 }
239
240 /* Client Username: <id> u <username> */
241 void iauth_cmd_u(struct iauth_client *client, char *arg) {
242     char *str;
243
244     str = iauth_next_data(&arg);
245     if(!str) goto parse_error;
246     iauth_set(client->ident, str);
247
248     return;
249     parse_error:
250     iauth_flog(IAUTH_WARNING, "Parse error: Invalid u line.");
251     return;
252 }
253
254 /* Client Nickname: <id> n <nickname> */
255 void iauth_cmd_n(struct iauth_client *client, char *arg) {
256     char *str;
257
258     str = iauth_next_data(&arg);
259     if(!str) goto parse_error;
260     iauth_set(client->nick, str);
261
262     return;
263     parse_error:
264     iauth_flog(IAUTH_WARNING, "Parse error: Invalid n line.");
265     return;
266 }
267
268 /* Client Registered: <id> T */
269 void iauth_cmd_T(struct iauth_client *client) {
270     iauth_flog(IAUTH_INFO, "Client %d was registered without IAuth answer.", client->id);
271     iauth_delid(client->id);
272 }
273
274 /* Error: <id> E <type> :<additional text> */
275 void iauth_cmd_E(signed int id, char *arg) {
276     iauth_flog(IAUTH_WARNING, "Received IRCd error: %s", arg);
277 }
278