]> jfr.im git - irc/quakenet/newserv.git/blame - glines/glines_formats.c
Move the hostmask length check to isglinesane().
[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
64 gl = newgline();
65
66 if (!gl) {
67 Error("gline", ERR_ERROR, "Failed to allocate new gline");
68 return NULL;
69 }
923bc30c 70
a86fc0c4 71 if (mask[0] == '#' || mask[0] == '&') {
c60d02ed
GB
72 gl->flags |= GLINE_BADCHAN;
73 gl->user = getsstring(mask, CHANNELLEN);
74 return gl;
75 }
76
a86fc0c4 77 if (mask[0] == '$') {
c60d02ed
GB
78 if (mask[1] != 'R') {
79 freegline(gl);
80 return NULL;
81 }
82
83 gl->flags |= GLINE_REALNAME;
84 gl->user = getsstring(mask + 2, REALLEN);
85 return gl;
86 }
87
923bc30c
GB
88 strncpy(dupmask, mask, sizeof(dupmask));
89 canon_userhost(dupmask, &nick, &user, &host, "*");
c60d02ed 90
923bc30c 91 if (ipmask_parse(host, &gl->ip, &gl->bits))
c60d02ed
GB
92 gl->flags |= GLINE_IPMASK;
93 else
94 gl->flags |= GLINE_HOSTMASK;
95
923bc30c
GB
96 /* Don't allow invalid IPv6 bans as those might match * on snircd 1.3.4 */
97 count = 0;
27a53417 98
923bc30c
GB
99 for (pos = host; *pos; pos++)
100 if (*pos == ':')
101 count++;
27a53417 102
923bc30c
GB
103 if (count >= 8) {
104 controlwall(NO_OPER, NL_GLINES, "Warning: Parsed invalid IPv6 G-Line: %s", mask);
105 freegline(gl);
106 return NULL;
27a53417
GB
107 }
108
923bc30c
GB
109 if (strcmp(nick, "*") != 0)
110 gl->nick = getsstring(nick, 512);
c60d02ed 111
923bc30c
GB
112 if (strcmp(user, "*") != 0)
113 gl->user = getsstring(user, 512);
c60d02ed 114
923bc30c
GB
115 if (strcmp(host, "*") != 0)
116 gl->host = getsstring(host, 512);
c60d02ed
GB
117
118 return gl;
119}
120
121char *glinetostring(gline *gl) {
122 static char mask[512]; /* check */
123
124 if (gl->flags & GLINE_REALNAME) {
125 if (gl->user)
126 snprintf(mask, sizeof(mask), "$R%s", gl->user->content);
127 else
128 strncpy(mask, "$R*", sizeof(mask));
129
130 return mask;
131 }
132
133 if (gl->flags & GLINE_BADCHAN) {
134 assert(gl->user);
135
136 strncpy(mask, gl->user->content, sizeof(mask));
137 return mask;
138 }
139
140 snprintf(mask, sizeof(mask), "%s!%s@%s",
141 gl->nick ? gl->nick->content : "*",
142 gl->user ? gl->user->content : "*",
143 gl->host ? gl->host->content : "*");
144
145 return mask;
146}
147