ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/extban.c
Revision: 9459
Committed: Tue Jun 30 19:55:32 2020 UTC (5 years, 1 month ago) by michael
Content type: text/x-csrc
File size: 5588 byte(s)
Log Message:
- Extban $t of type 'acting' has been implemented. This extban allows matching based on TLS protocol version and/or cipher suite

File Contents

# User Rev Content
1 michael 9234 /*
2     * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3     *
4     * Copyright (c) 2015-2016 plexus development team
5     * Copyright (c) 2019-2020 ircd-hybrid development team
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20     * USA
21     */
22    
23     /*! \file extban.c
24     * \brief Implements extended channel bans.
25 michael 9238 * \version $Id$
26 michael 9234 */
27    
28     #include "stdinc.h"
29     #include "ircd_defs.h"
30     #include "list.h"
31     #include "irc_string.h"
32     #include "user.h"
33     #include "isupport.h"
34     #include "extban.h"
35    
36    
37     static dlink_list extban_list;
38     static unsigned int matching_mask, acting_mask;
39    
40    
41     static unsigned int
42     extban_find_mask(void)
43     {
44     dlink_node *node;
45     unsigned int used = 0;
46     unsigned int i;
47    
48     DLINK_FOREACH(node, extban_list.head)
49     {
50     const struct Extban *extban = node->data;
51     used |= extban->flag;
52     }
53    
54     for (i = 1; (i < EXTBAN_MASK) && (used & i); i <<= 1)
55     ;
56    
57     return i;
58     }
59    
60     void
61     extban_init(void)
62     {
63     extban_add(&extban_account);
64     extban_add(&extban_channel);
65     extban_add(&extban_fingerprint);
66     extban_add(&extban_gecos);
67     extban_add(&extban_join);
68     extban_add(&extban_mute);
69 michael 9292 extban_add(&extban_nick);
70 michael 9234 extban_add(&extban_operclass);
71     extban_add(&extban_server);
72 michael 9459 extban_add(&extban_tlsinfo);
73 michael 9234 extban_add(&extban_usermode);
74    
75     const char *ptr = extban_get_isupport();
76     if (ptr)
77     isupport_add("EXTBAN", ptr, -1);
78     }
79    
80     void
81     extban_add(struct Extban *extban)
82     {
83     unsigned int mask = extban_find_mask();
84    
85     if (mask == 0)
86     return;
87    
88     extban->flag = mask;
89     dlinkAdd(extban, &extban->node, &extban_list);
90    
91     if (extban->type & EXTBAN_MATCHING)
92     matching_mask |= mask;
93     if (extban->type & EXTBAN_ACTING)
94     acting_mask |= mask;
95     }
96    
97     void
98     extban_del(struct Extban *extban)
99     {
100     if (extban->flag == 0)
101     return;
102    
103     dlinkDelete(&extban->node, &extban_list);
104    
105     matching_mask &= ~extban->flag;
106     acting_mask &= ~extban->flag;
107     }
108    
109     struct Extban *
110     extban_find(unsigned char c)
111     {
112     dlink_node *node;
113    
114     DLINK_FOREACH(node, extban_list.head)
115     {
116     struct Extban *extban = node->data;
117    
118     if (extban->character == c)
119     return extban;
120     }
121    
122     return NULL;
123     }
124    
125     struct Extban *
126     extban_find_flag(unsigned int flag)
127     {
128     dlink_node *node;
129    
130     DLINK_FOREACH(node, extban_list.head)
131     {
132     struct Extban *extban = node->data;
133    
134     if (extban->flag == flag)
135     return extban;
136     }
137    
138     return NULL;
139     }
140    
141     enum extban_type
142     extban_parse(const char *mask, unsigned int *input_extbans, unsigned int *offset)
143     {
144     *input_extbans = 0;
145     *offset = 0;
146    
147     if (*mask == '$' && IsAlpha(*(mask + 1)) && *(mask + 2) == ':')
148     {
149     struct Extban *extban = extban_find(*(mask + 1));
150     if (extban == NULL)
151     return EXTBAN_INVALID;
152    
153     *input_extbans |= extban->flag;
154     *offset += 3;
155     mask += 3;
156    
157     /* Matching extbans take a special parameter, so stop reading */
158     if (extban->type == EXTBAN_MATCHING)
159     return EXTBAN_MATCHING;
160    
161     if (IsAlpha(*mask) && *(mask + 1) == ':')
162     {
163     extban = extban_find(*mask);
164     if (extban == NULL)
165     return EXTBAN_INVALID;
166    
167     /* Two acting extbans make no sense */
168     if (extban->type == EXTBAN_ACTING)
169     return EXTBAN_INVALID;
170    
171     /* Check parameter */
172     if (extban->is_valid && extban->is_valid(mask) == EXTBAN_INVALID)
173     return EXTBAN_INVALID;
174    
175     *input_extbans |= extban->flag;
176     *offset += 2;
177     mask += 2;
178    
179     return EXTBAN_MATCHING;
180     }
181    
182     return EXTBAN_ACTING;
183     }
184    
185     return EXTBAN_NONE;
186     }
187    
188     unsigned int
189     extban_format(unsigned int e, char *buf)
190     {
191     dlink_node *node;
192     unsigned int written = 0;
193    
194     DLINK_FOREACH(node, extban_list.head)
195     {
196     struct Extban *extban = node->data;
197    
198     if (extban->type != EXTBAN_ACTING)
199     continue;
200    
201     if (extban->flag & e)
202     {
203     if (written == 0)
204     {
205     written++;
206     *buf++ = '$';
207     }
208    
209     *buf++ = extban->character;
210     *buf++ = ':';
211 michael 9262 written += 2;
212 michael 9234
213 michael 9262 break;
214 michael 9234 }
215     }
216    
217     DLINK_FOREACH(node, extban_list.head)
218     {
219     struct Extban *extban = node->data;
220    
221     if (extban->type != EXTBAN_MATCHING)
222     continue;
223    
224     if (extban->flag & e)
225     {
226     if (written == 0)
227     {
228     written++;
229     *buf++ = '$';
230     }
231    
232     *buf++ = extban->character;
233     *buf++ = ':';
234     written += 2;
235 michael 9262
236     break;
237 michael 9234 }
238     }
239    
240     return written;
241     }
242    
243     unsigned int
244     extban_matching_mask(void)
245     {
246     return matching_mask;
247     }
248    
249     unsigned int
250     extban_acting_mask(void)
251     {
252     return acting_mask;
253     }
254    
255     const char *
256     extban_get_isupport(void)
257     {
258     dlink_node *node;
259     char extban_chars[256] = { 0 };
260     static char buf[sizeof(extban_chars) + 3 /* +3 = $,\0 */ ];
261    
262     if (dlink_list_length(&extban_list) == 0)
263     return NULL;
264    
265     DLINK_FOREACH(node, extban_list.head)
266     {
267     struct Extban *extban = node->data;
268 michael 9242 extban_chars[extban->character] = extban->character;
269 michael 9234 }
270    
271     char *p = buf + strlcpy(buf, "$,", sizeof(buf));
272    
273     for (unsigned int i = 0; i < 256; ++i)
274     if (extban_chars[i])
275     *p++ = extban_chars[i];
276     *p++ = '\0';
277    
278     return buf;
279     }
280    

Properties

Name Value
svn:eol-style native
svn:keywords Id