]> jfr.im git - irc/quakenet/newserv.git/blame - glines/glines_formats.c
Don't accept gline masks that are too long.
[irc/quakenet/newserv.git] / glines / glines_formats.c
CommitLineData
c60d02ed
GB
1#include <stdio.h>
2#include <string.h>
3#include <assert.h>
4#include "../lib/irc_string.h"
5#include "../lib/version.h"
6#include "../core/schedule.h"
7#include "../irc/irc.h"
8#include "../trusts/trusts.h"
9#include "../control/control.h"
10#include "glines.h"
11
923bc30c
GB
12/** Find canonical user and host for a string.
13 * If \a userhost starts with '$', assign \a userhost to *user_p and NULL to *host_p.
14 * Otherwise, if \a userhost contains '@', assign the earlier part of it to *user_p and the rest to *host_p.
15 * Otherwise, assign \a def_user to *user_p and \a userhost to *host_p.
16 *
17 * @param[in] userhost Input string from user.
18 * @param[out] nick_p Gets pointer to nick part of hostmask.
19 * @param[out] user_p Gets pointer to user (or channel/realname) part of hostmask.
20 * @param[out] host_p Gets point to host part of hostmask (may be assigned NULL).
21 * @param[in] def_user Default value for user part.
22 */
23static void
24canon_userhost(char *userhost, char **nick_p, char **user_p, char **host_p, char *def_user) {
25 char *tmp, *s;
26
27 if (*userhost == '$') {
28 *user_p = userhost;
29 *host_p = NULL;
30 *nick_p = NULL;
31 return;
32 }
33
34 if ((tmp = strchr(userhost, '!'))) {
35 *nick_p = userhost;
36 *(tmp++) = '\0';
37 } else {
38 *nick_p = def_user;
39 tmp = userhost;
40 }
41
42 if (!(s = strchr(tmp, '@'))) {
43 *user_p = def_user;
44 *host_p = tmp;
45 } else {
46 *user_p = tmp;
47 *(s++) = '\0';
48 *host_p = s;
49 }
50}
51
c60d02ed
GB
52gline *makegline(const char *mask) {
53 /* populate gl-> user,host,node,nick and set appropriate flags */
54 gline *gl;
923bc30c
GB
55 char dupmask[512];
56 char *nick, *user, *host;
27a53417
GB
57 const char *pos;
58 int count;
c60d02ed 59
923bc30c 60 /* Make sure there are no spaces in the mask */
c60d02ed
GB
61 if (strchr(mask, ' ') != NULL)
62 return NULL;
63
a24820ff
GB
64 /* Make sure it's not too long */
65 if (strlen(mask) > NICKLEN + USERLEN + HOSTLEN + 2)
66 return NULL;
67
c60d02ed
GB
68 gl = newgline();
69
70 if (!gl) {
71 Error("gline", ERR_ERROR, "Failed to allocate new gline");
72 return NULL;
73 }
923bc30c 74
a86fc0c4 75 if (mask[0] == '#' || mask[0] == '&') {
c60d02ed
GB
76 gl->flags |= GLINE_BADCHAN;
77 gl->user = getsstring(mask, CHANNELLEN);
78 return gl;
79 }
80
a86fc0c4 81 if (mask[0] == '$') {
c60d02ed
GB
82 if (mask[1] != 'R') {
83 freegline(gl);
84 return NULL;
85 }
86
87 gl->flags |= GLINE_REALNAME;
88 gl->user = getsstring(mask + 2, REALLEN);
89 return gl;
90 }
91
923bc30c
GB
92 strncpy(dupmask, mask, sizeof(dupmask));
93 canon_userhost(dupmask, &nick, &user, &host, "*");
c60d02ed 94
923bc30c 95 if (ipmask_parse(host, &gl->ip, &gl->bits))
c60d02ed
GB
96 gl->flags |= GLINE_IPMASK;
97 else
98 gl->flags |= GLINE_HOSTMASK;
99
923bc30c
GB
100 /* Don't allow invalid IPv6 bans as those might match * on snircd 1.3.4 */
101 count = 0;
27a53417 102
923bc30c
GB
103 for (pos = host; *pos; pos++)
104 if (*pos == ':')
105 count++;
27a53417 106
923bc30c
GB
107 if (count >= 8) {
108 controlwall(NO_OPER, NL_GLINES, "Warning: Parsed invalid IPv6 G-Line: %s", mask);
109 freegline(gl);
110 return NULL;
27a53417
GB
111 }
112
923bc30c
GB
113 if (strcmp(nick, "*") != 0)
114 gl->nick = getsstring(nick, 512);
c60d02ed 115
923bc30c
GB
116 if (strcmp(user, "*") != 0)
117 gl->user = getsstring(user, 512);
c60d02ed 118
923bc30c
GB
119 if (strcmp(host, "*") != 0)
120 gl->host = getsstring(host, 512);
c60d02ed
GB
121
122 return gl;
123}
124
125char *glinetostring(gline *gl) {
126 static char mask[512]; /* check */
127
128 if (gl->flags & GLINE_REALNAME) {
129 if (gl->user)
130 snprintf(mask, sizeof(mask), "$R%s", gl->user->content);
131 else
132 strncpy(mask, "$R*", sizeof(mask));
133
134 return mask;
135 }
136
137 if (gl->flags & GLINE_BADCHAN) {
138 assert(gl->user);
139
140 strncpy(mask, gl->user->content, sizeof(mask));
141 return mask;
142 }
143
144 snprintf(mask, sizeof(mask), "%s!%s@%s",
145 gl->nick ? gl->nick->content : "*",
146 gl->user ? gl->user->content : "*",
147 gl->host ? gl->host->content : "*");
148
149 return mask;
150}
151