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

Comparing ircd-hybrid-7.2/modules/m_knock.c (file contents):
Revision 884 by lusky, Sun Oct 2 21:05:51 2005 UTC vs.
Revision 885 by michael, Wed Oct 31 18:09:24 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines