]>
Commit | Line | Data |
---|---|---|
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 | ||
12 | gline *makegline(const char *mask) { | |
13 | /* populate gl-> user,host,node,nick and set appropriate flags */ | |
14 | gline *gl; | |
15 | char nick[512], user[512], host[512]; | |
16 | const char *pnick = NULL, *puser = NULL, *phost = NULL; | |
27a53417 GB |
17 | const char *pos; |
18 | int count; | |
c60d02ed GB |
19 | |
20 | /* Make sure there are no spaces in the mask, glstore_* depends on this */ | |
21 | if (strchr(mask, ' ') != NULL) | |
22 | return NULL; | |
23 | ||
24 | gl = newgline(); | |
25 | ||
26 | if (!gl) { | |
27 | Error("gline", ERR_ERROR, "Failed to allocate new gline"); | |
28 | return NULL; | |
29 | } | |
30 | ||
a86fc0c4 | 31 | if (mask[0] == '#' || mask[0] == '&') { |
c60d02ed GB |
32 | gl->flags |= GLINE_BADCHAN; |
33 | gl->user = getsstring(mask, CHANNELLEN); | |
34 | return gl; | |
35 | } | |
36 | ||
a86fc0c4 | 37 | if (mask[0] == '$') { |
c60d02ed GB |
38 | if (mask[1] != 'R') { |
39 | freegline(gl); | |
40 | return NULL; | |
41 | } | |
42 | ||
43 | gl->flags |= GLINE_REALNAME; | |
44 | gl->user = getsstring(mask + 2, REALLEN); | |
45 | return gl; | |
46 | } | |
47 | ||
48 | if (sscanf(mask, "%[^!]!%[^@]@%s", nick, user, host) == 3) { | |
49 | pnick = nick; | |
50 | puser = user; | |
51 | phost = host; | |
52 | } else if (sscanf(mask, "%[^@]@%s", user, host) == 2) { | |
53 | puser = user; | |
54 | phost = host; | |
55 | } else { | |
56 | phost = mask; | |
57 | } | |
58 | ||
59 | /* validate length of the mask components */ | |
60 | if ((pnick && (pnick[0] == '\0' || strlen(pnick) > NICKLEN)) || | |
61 | (puser && (puser[0] == '\0' || strlen(puser) > USERLEN)) || | |
62 | (phost && (phost[0] == '\0' || strlen(phost) > HOSTLEN))) { | |
63 | freegline(gl); | |
64 | return NULL; | |
65 | } | |
66 | ||
67 | /* ! and @ are not allowed in the mask components */ | |
68 | if ((pnick && (strchr(pnick, '!') || strchr(pnick, '@'))) || | |
69 | (puser && (strchr(puser, '!') || strchr(puser, '@'))) || | |
70 | (phost && (strchr(phost, '!') || strchr(phost, '@')))) { | |
71 | freegline(gl); | |
72 | return NULL; | |
73 | } | |
74 | ||
75 | if (phost && ipmask_parse(phost, &gl->ip, &gl->bits)) | |
76 | gl->flags |= GLINE_IPMASK; | |
77 | else | |
78 | gl->flags |= GLINE_HOSTMASK; | |
79 | ||
27a53417 GB |
80 | /* Don't allow invalid IPv6 bans as those match * on snircd 1.3.4 */ |
81 | if (phost) { | |
82 | count = 0; | |
83 | ||
84 | for (pos = phost; *pos; pos++) | |
85 | if (*pos == ':') | |
86 | count++; | |
87 | ||
88 | if (count >= 8) { | |
89 | controlwall(NO_OPER, NL_GLINES, "Warning: Parsed invalid IPv6 G-Line: %s", mask); | |
90 | freegline(gl); | |
91 | return NULL; | |
92 | } | |
93 | } | |
94 | ||
c60d02ed GB |
95 | if (pnick && strcmp(pnick, "*") != 0) |
96 | gl->nick = getsstring(pnick, NICKLEN); | |
97 | ||
98 | if (puser && strcmp(puser, "*") != 0) | |
99 | gl->user = getsstring(puser, USERLEN); | |
100 | ||
101 | if (phost && strcmp(phost, "*") != 0) | |
102 | gl->host = getsstring(phost, HOSTLEN); | |
103 | ||
104 | return gl; | |
105 | } | |
106 | ||
107 | char *glinetostring(gline *gl) { | |
108 | static char mask[512]; /* check */ | |
109 | ||
110 | if (gl->flags & GLINE_REALNAME) { | |
111 | if (gl->user) | |
112 | snprintf(mask, sizeof(mask), "$R%s", gl->user->content); | |
113 | else | |
114 | strncpy(mask, "$R*", sizeof(mask)); | |
115 | ||
116 | return mask; | |
117 | } | |
118 | ||
119 | if (gl->flags & GLINE_BADCHAN) { | |
120 | assert(gl->user); | |
121 | ||
122 | strncpy(mask, gl->user->content, sizeof(mask)); | |
123 | return mask; | |
124 | } | |
125 | ||
126 | snprintf(mask, sizeof(mask), "%s!%s@%s", | |
127 | gl->nick ? gl->nick->content : "*", | |
128 | gl->user ? gl->user->content : "*", | |
129 | gl->host ? gl->host->content : "*"); | |
130 | ||
131 | return mask; | |
132 | } | |
133 |