ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/branches/ircd-hybrid-newconf/modules/m_knock.c
(Generate patch)

Comparing ircd-hybrid/modules/m_knock.c (file contents):
Revision 227 by db, Thu Nov 3 18:29:22 2005 UTC vs.
Revision 398 by michael, Tue Feb 7 12:00:21 2006 UTC

# Line 39 | Line 39
39   #include "s_user.h"
40   #include "common.h"
41  
42 < static void m_knock(struct Client*, struct Client*, int, char**);
43 < static void ms_knock(struct Client *, struct Client *, int, char**);
44 < static void me_knock(struct Client *, struct Client *, int, char**);
45 <
46 < static void parse_knock_local(struct Client *, struct Client *,
47 <                              int, char **, char *);
48 < static void parse_knock_remote(struct Client *, struct Client *,
49 <                                      int, char **, int);
50 <
51 < static void send_knock(struct Client *, struct Client *,
52 <                       struct Channel *, char *, char *, int, int);
42 > static void m_knock(struct Client *, struct Client *, int, char *[]);
43  
44   struct Message knock_msgtab = {
45    "KNOCK", 0, 0, 2, 0, MFLG_SLOW, 0,
46 <  {m_unregistered, m_knock, ms_knock, me_knock, m_knock, m_ignore}
57 < };
58 <
59 < struct Message knockll_msgtab = {
60 <  "KNOCKLL", 0, 0, 2, 0, MFLG_SLOW, 0,
61 <  {m_unregistered, m_ignore, m_knock, m_ignore, m_ignore, m_ignore}
46 >  {m_unregistered, m_knock, m_knock, m_ignore, m_knock, m_ignore}
47   };
48  
49   #ifndef STATIC_MODULES
65
50   void
51   _modinit(void)
52   {
53    mod_add_cmd(&knock_msgtab);
70  mod_add_cmd(&knockll_msgtab);
54    add_capability("KNOCK", CAP_KNOCK, 1);
55    add_isupport("KNOCK", NULL, -1);
56   }
# Line 76 | Line 59 | void
59   _moddeinit(void)
60   {
61    mod_del_cmd(&knock_msgtab);
79  mod_del_cmd(&knockll_msgtab);
62    delete_capability("KNOCK");
63    delete_isupport("KNOCK");
64   }
# Line 97 | Line 79 | const char *_version = "$Revision$";
79   *  key is forgotten, or the channel is full (INVITE can bypass each one
80   *  of these conditions.  Concept by Dianora <db@db.net> and written by
81   *  <anonymous>
100 *
101 *  This function is also used for LL servers forwarding knock requests they
102 *  dont know about, for us to answer.
82   */
83   static void
84   m_knock(struct Client *client_p, struct Client *source_p,
85          int parc, char *parv[])
86   {
87 <  char *sockhost = NULL;
88 <
110 <  if ((ConfigChannel.use_knock == 0) && MyClient(source_p))
111 <  {
112 <    sendto_one(source_p, form_str(ERR_KNOCKDISABLED),
113 <               me.name, source_p->name);
114 <    return;
115 <  }
116 <
117 <  /* a remote KNOCKLL request, check we're capable of handling it.. */
118 <  if (!MyConnect(source_p))
119 <  {
120 <    if (!ServerInfo.hub || !IsCapable(client_p, CAP_LL) || parc < 3)
121 <      return;
122 <    else
123 <    {
124 <      /* set sockhost to parv[2] here to save messing in parse_knock_local() */
125 <      sockhost = parv[2];
126 <
127 <      if(parc > 3)
128 <      {
129 <        parv[2] = parv[3];
130 <        parv[3] = NULL;
131 <      }
132 <      else
133 <        parv[2] = NULL;
134 <
135 <      parc--;
136 <    }
137 <  }
138 <    
139 <  if (IsClient(source_p))
140 <    parse_knock_local(client_p, source_p, parc, parv, sockhost);
141 < }
142 <
143 < /*
144 < * ms_knock()
145 < *      parv[0] = sender prefix
146 < *      parv[1] = channel
147 < */
148 <
149 < static void
150 < ms_knock(struct Client *client_p, struct Client *source_p,
151 <         int parc, char *parv[])
152 < {
153 <  if (IsClient(source_p))
154 <    parse_knock_remote(client_p, source_p, parc, parv, 1);
155 < }
156 <
157 < /*
158 < * me_knock()
159 < *      parv[0] = sender prefix
160 < *      parv[1] = channel
161 < */
162 <
163 < static void
164 < me_knock(struct Client *client_p, struct Client *source_p,
165 <         int parc, char *parv[])
166 < {
167 <  if (IsClient(source_p))
168 <    parse_knock_remote(client_p, source_p, parc, parv, 0);
169 < }
170 <
171 < /* parse_knock_local()
172 < *
173 < * input        - pointer to physical struct client_p
174 < *              - pointer to source struct source_p
175 < *              - number of args
176 < *              - pointer to array of args
177 < *              - clients sockhost
178 < * output       -
179 < * side effects - sets name to name of base channel
180 < *                or sends failure message to source_p
181 < */
182 < static void
183 < parse_knock_local(struct Client *client_p, struct Client *source_p,
184 <                              int parc, char *parv[], char *sockhost)
185 < {
186 <  /* We will cut at the first comma reached, however we will not *
187 <   * process anything afterwards.                                */
188 <
189 <  struct Channel *chptr;
190 <  char *p, *name, *key;
191 <
192 <  name = parv[1];
193 <  key = (parc > 2) ? parv[2] : NULL;
194 <
195 <  if ((p = strchr(name, ',')) != NULL)
196 <    *p = '\0';
87 >  const char *name = parv[1];
88 >  struct Channel *chptr = NULL;
89  
90    if (*name == '\0')
91    {
# Line 202 | Line 94 | parse_knock_local(struct Client *client_
94      return;
95    }
96  
97 <  if (!IsChanPrefix(*name))
97 >  if (!ConfigChannel.use_knock && MyClient(source_p))
98    {
99 <    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
100 <               me.name, source_p->name, name);
99 >    sendto_one(source_p, form_str(ERR_KNOCKDISABLED),
100 >               me.name, source_p->name);
101      return;
102    }
103  
104    if ((chptr = hash_find_channel(name)) == NULL)
105    {
106 <    if (!ServerInfo.hub && uplink && IsCapable(uplink, CAP_LL))
107 <    {
216 <      sendto_one(uplink, ":%s KNOCKLL %s %s %s",
217 <                 ID_or_name(source_p, uplink), parv[1],
218 <                 IsIPSpoof(source_p) ? "255.255.255.255" :
219 <                 source_p->sockhost,
220 <                 (parc > 2) ? parv[2] : "");
221 <    }
222 <    else
223 <    {
224 <      sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
225 <                 me.name, source_p->name, name);
226 <    }
227 <
106 >    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
107 >               me.name, source_p->name, name);
108      return;
109    }
110  
# Line 245 | Line 125 | parse_knock_local(struct Client *client_
125      return;
126    }
127  
128 <  /* don't allow a knock if the user is banned, or the channel is secret */
249 <  if ((chptr->mode.mode & MODE_PARANOID) || is_banned(chptr, source_p))
250 <  {
251 <    sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN),
252 <               me.name, source_p->name, name);
253 <    return;
254 <  }
255 <
256 <  /* flood protection:
257 <   * allow one knock per user per knock_delay
258 <   * allow one knock per channel per knock_delay_channel
259 <   *
260 <   * we only limit local requests..
261 <   */
262 <  if (MyClient(source_p) &&
263 <     (source_p->localClient->last_knock + ConfigChannel.knock_delay) >
264 <      CurrentTime)
265 <  {
266 <    sendto_one(source_p, form_str(ERR_TOOMANYKNOCK),
267 <               me.name, source_p->name, parv[1], "user");
268 <    return;
269 <  }
270 <  else if (chptr->last_knock +
271 <           ConfigChannel.knock_delay_channel > CurrentTime)
128 >  if (MyClient(source_p))
129    {
130 <    sendto_one(source_p, form_str(ERR_TOOMANYKNOCK),
131 <               me.name, source_p->name, parv[1], "channel");
132 <    return;
133 <  }
134 <
135 <  /* pass on the knock */
136 <  send_knock(client_p, source_p, chptr, name, key,
280 <             MyClient(source_p) ? 0 : 1, 1);
281 < }
282 <
283 < /* parse_knock_remote()
284 < *
285 < * input        - pointer to client
286 < *              - pointer to source
287 < *              - number of args
288 < *              - pointer to array of args
289 < * output       - none
290 < * side effects - knock is checked for validity, if valid send_knock() is
291 < *                called
292 < */
293 < static void
294 < parse_knock_remote(struct Client *client_p, struct Client *source_p,
295 <                   int parc, char *parv[], int prop)
296 < {
297 <  struct Channel *chptr;
298 <  char *p, *name, *key;
299 <
300 <  name = parv[1];
301 <  key = parv[2];
302 <
303 <  if ((p = strchr(name, ',')) != NULL)
304 <    *p = '\0';
305 <
306 <  if (!IsChanPrefix(*name) || (chptr = hash_find_channel(name)) == NULL)
307 <    return;
308 <
309 <  if (IsMember(source_p, chptr))
310 <    return;
311 <  
312 <  if (!((chptr->mode.mode & MODE_INVITEONLY) || (*chptr->mode.key) ||
313 <        (chptr->mode.limit && dlink_list_length(&chptr->members) >=
314 <         chptr->mode.limit)))
315 <    return;
130 >    /* don't allow a knock if the user is banned, or the channel is secret */
131 >    if ((chptr->mode.mode & MODE_PARANOID) || is_banned(chptr, source_p))
132 >    {
133 >      sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN),
134 >                 me.name, source_p->name, name);
135 >      return;
136 >    }
137  
138 <  if (chptr)
139 <    send_knock(client_p, source_p, chptr, name, key, 0, prop);
140 < }
138 >    /* flood protection:
139 >     * allow one knock per user per knock_delay
140 >     * allow one knock per channel per knock_delay_channel
141 >     *
142 >     * we only limit local requests..
143 >     */
144 >    if ((source_p->localClient->last_knock + ConfigChannel.knock_delay) >
145 >        CurrentTime)
146 >    {
147 >      sendto_one(source_p, form_str(ERR_TOOMANYKNOCK),
148 >                 me.name, source_p->name, parv[1], "user");
149 >      return;
150 >    }
151  
152 < /* send_knock()
153 < *
154 < * input        - pointer to physical struct client_p
155 < *              - pointer to source struct source_p
156 < *              - pointer to channel struct chptr
157 < *              - pointer to base channel name
327 < * output       -
328 < * side effects - knock is sent locally (if enabled) and propagated
329 < */
330 < static void
331 < send_knock(struct Client *client_p, struct Client *source_p,
332 <           struct Channel *chptr, char *name, char *key, int llclient,
333 <           int prop)
334 < {
335 <  chptr->last_knock = CurrentTime;
152 >    if (chptr->last_knock + ConfigChannel.knock_delay_channel > CurrentTime)
153 >    {
154 >      sendto_one(source_p, form_str(ERR_TOOMANYKNOCK),
155 >                 me.name, source_p->name, parv[1], "channel");
156 >      return;
157 >    }
158  
337  if (MyClient(source_p))
338  {
159      source_p->localClient->last_knock = CurrentTime;
160  
161      sendto_one(source_p, form_str(RPL_KNOCKDLVR),
162                 me.name, source_p->name, name);
163    }
344  else if (llclient == 1)
345    sendto_one(source_p, form_str(RPL_KNOCKDLVR),
346               me.name, source_p->name, name);
164  
165 <  if (IsClient(source_p))
349 <  {
350 <    if (ConfigChannel.use_knock)
351 <      sendto_channel_local(CHFL_CHANOP, NO,
352 <                     chptr, form_str(RPL_KNOCK),
353 <                             me.name, name, name,
354 <                             source_p->name, source_p->username,
355 <                             source_p->host);
165 >  chptr->last_knock = CurrentTime;
166  
167 <    if (prop)
168 <    {
169 <      sendto_server(client_p, source_p, chptr, CAP_KNOCK|CAP_TS6, NOCAPS, LL_ICLIENT,
170 <                    ":%s KNOCK %s %s",
171 <                    ID(source_p), name, key != NULL ? key : "");
172 <      sendto_server(client_p, source_p, chptr, CAP_KNOCK, CAP_TS6, LL_ICLIENT,
173 <                    ":%s KNOCK %s %s",
174 <                    source_p->name, name, key != NULL ? key : "");
175 <    }
176 <  }
167 >  if (ConfigChannel.use_knock)
168 >    sendto_channel_local(CHFL_CHANOP, NO, chptr, form_str(RPL_KNOCK),
169 >                         me.name, name, name,
170 >                         source_p->name, source_p->username,
171 >                         source_p->host);
172 >
173 >  sendto_server(client_p, source_p, chptr, CAP_KNOCK|CAP_TS6, NOCAPS, LL_ICLIENT,
174 >                ":%s KNOCK %s %s", ID(source_p), name);
175 >  sendto_server(client_p, source_p, chptr, CAP_KNOCK, CAP_TS6, LL_ICLIENT,
176 >                ":%s KNOCK %s %s", source_p->name, name);
177   }
368

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)