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

Comparing:
ircd-hybrid/modules/m_challenge.c (file contents), Revision 33 by knight, Sun Oct 2 20:50:00 2005 UTC vs.
ircd-hybrid/trunk/modules/m_challenge.c (file contents), Revision 3347 by michael, Sun Apr 20 14:03:06 2014 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  m_challenge.c: Allows an IRC Operator to securely authenticate.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 2000-2014 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 18 | Line 17
17   *  along with this program; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
19   *  USA
20 < *
21 < *  $Id$
20 > */
21 >
22 > /*! \file m_challenge.c
23 > * \brief Includes required functions for processing the CHALLENGE command.
24 > * \version $Id$
25   */
26  
27   #include "stdinc.h"
26 #include "handlers.h"
28   #include "client.h"
29   #include "ircd.h"
30   #include "modules.h"
31   #include "numeric.h"
32   #include "send.h"
33 < #include "s_conf.h"
33 < /* -lcrypto is implicit for building this module! */
33 > #include "conf.h"
34   #include "rsa.h"
35 #include "msg.h"
35   #include "parse.h"
36   #include "irc_string.h"
37 < #include "s_log.h"
38 < #include "s_user.h"
37 > #include "log.h"
38 > #include "user.h"
39 > #include "memory.h"
40  
41 static void failed_challenge_notice(struct Client *, const char *,
42                                    const char *);
43 static void m_challenge(struct Client *, struct Client *, int, char **);
44
45 /* We have openssl support, so include /CHALLENGE */
46 struct Message challenge_msgtab = {
47  "CHALLENGE", 0, 0, 2, 0, MFLG_SLOW, 0,
48  { m_unregistered, m_challenge, m_ignore, m_ignore, m_challenge, m_ignore }
49 };
41  
42 < #ifndef STATIC_MODULES
43 < void
44 < _modinit(void)
42 > #ifdef HAVE_LIBCRYPTO
43 > /*! \brief Notices all opers of the failed challenge attempt if enabled
44 > *
45 > * \param source_p Client doing /challenge ...
46 > * \param name     The nick they tried to oper as
47 > * \param reason   The reason why they have failed
48 > */
49 > static void
50 > failed_challenge_notice(struct Client *source_p, const char *name,
51 >                        const char *reason)
52   {
53 <  mod_add_cmd(&challenge_msgtab);
54 < }
53 >  if (ConfigFileEntry.failed_oper_notice)
54 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
55 >                         "Failed CHALLENGE attempt as %s "
56 >                         "by %s (%s@%s) - %s", name, source_p->name,
57 >                         source_p->username, source_p->host, reason);
58  
59 < void
60 < _moddeinit(void)
61 < {
61 <  mod_del_cmd(&challenge_msgtab);
59 >  ilog(LOG_TYPE_OPER, "Failed CHALLENGE attempt as %s "
60 >       "by %s (%s@%s) - %s", name, source_p->name,
61 >       source_p->username, source_p->host, reason);
62   }
63  
64 < const char *_version = "$Revision$";
65 < #endif
66 <
67 < /*
68 < * m_challenge - generate RSA challenge for wouldbe oper
69 < * parv[0] = sender prefix
70 < * parv[1] = operator to challenge for, or +response
64 > /*! \brief CHALLENGE command handler
65   *
66 + * \param source_p Pointer to allocated Client struct from which the message
67 + *                 originally comes from.  This can be a local or remote client.
68 + * \param parc     Integer holding the number of supplied arguments.
69 + * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
70 + *                 pointers.
71 + * \note Valid arguments for this command are:
72 + *      - parv[0] = command
73 + *      - parv[1] = operator to challenge for, or +response
74   */
75 < static void
76 < m_challenge(struct Client *client_p, struct Client *source_p,
75 <            int parc, char *parv[])
75 > static int
76 > m_challenge(struct Client *source_p, int parc, char *parv[])
77   {
78 <  char *challenge;
79 <  struct ConfItem *conf=NULL;
79 <  struct AccessItem *aconf=NULL;
80 <
81 <  assert(source_p->localClient);
82 <
83 <  /* if theyre an oper, reprint oper motd and ignore */
84 <  if (IsOper(source_p))
85 <  {
86 <    sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, parv[0]);
87 <    send_message_file(source_p, &ConfigFileEntry.opermotd);
88 <    return;
89 <  }
78 >  char *challenge = NULL;
79 >  struct MaskItem *conf = NULL;
80  
81    if (*parv[1] == '+')
82    {
83      /* Ignore it if we aren't expecting this... -A1kmm */
84 <    if (!source_p->localClient->response)
85 <      return;
84 >    if (source_p->localClient->response == NULL)
85 >      return 0;
86  
87      if (irccmp(source_p->localClient->response, ++parv[1]))
88      {
89 <      sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name,
100 <                 source_p->name);
89 >      sendto_one_numeric(source_p, &me, ERR_PASSWDMISMATCH);
90        failed_challenge_notice(source_p, source_p->localClient->auth_oper,
91 <                              "challenge failed");
92 <      return;
91 >                              "challenge failed");
92 >      return 0;
93      }
94 <    
95 <    if ((conf = find_exact_name_conf(OPER_TYPE,
96 <                                     source_p->localClient->auth_oper,
97 <                                     source_p->username, source_p->host
109 <                                   )) == NULL)
94 >    
95 >    conf = find_exact_name_conf(CONF_OPER, source_p,
96 >                                source_p->localClient->auth_oper, NULL, NULL);
97 >    if (conf == NULL)
98      {
99 <      sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, parv[0]);
100 <      log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n",
101 <                      source_p->localClient->auth_oper);
102 <      return;
99 >      sendto_one_numeric(source_p, &me, ERR_NOOPERHOST);
100 >      conf = find_exact_name_conf(CONF_OPER, NULL, source_p->localClient->auth_oper, NULL, NULL);
101 >      failed_challenge_notice(source_p, source_p->localClient->auth_oper, (conf != NULL) ?
102 >                              "host mismatch" : "no oper {} block");
103 >      return 0;
104      }
105  
106      if (attach_conf(source_p, conf) != 0)
107      {
108 <      sendto_one(source_p,":%s NOTICE %s :Can't attach conf!",
120 <                 me.name, source_p->name);  
108 >      sendto_one_notice(source_p, &me, ":Can't attach conf!");  
109        failed_challenge_notice(source_p, conf->name, "can't attach conf!");
110 <      log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n",
123 <                      source_p->localClient->auth_oper);
124 <      return;
110 >      return 0;
111      }
112  
113      oper_up(source_p);
114  
115 <    ilog(L_TRACE, "OPER %s by %s!%s@%s",
116 <         source_p->localClient->auth_oper, source_p->name, source_p->username,
117 <         source_p->host);
132 <    log_oper_action(LOG_OPER_TYPE, source_p,
133 <                    "%s\n", source_p->localClient->auth_oper);
115 >    ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s",
116 >         source_p->localClient->auth_oper, source_p->name, source_p->username,
117 >         source_p->host);
118  
119      MyFree(source_p->localClient->response);
120      MyFree(source_p->localClient->auth_oper);
121      source_p->localClient->response  = NULL;
122      source_p->localClient->auth_oper = NULL;
123 <    return;
123 >    return 0;
124    }
125  
126    MyFree(source_p->localClient->response);
# Line 144 | Line 128 | m_challenge(struct Client *client_p, str
128    source_p->localClient->response  = NULL;
129    source_p->localClient->auth_oper = NULL;
130  
131 <  if ((conf = find_conf_exact(OPER_TYPE,
132 <                              parv[1], source_p->username, source_p->host
133 <                              )) != NULL)
131 >  conf = find_exact_name_conf(CONF_OPER, source_p, parv[1], NULL, NULL);
132 >
133 >  if (!conf)
134    {
135 <    aconf = (struct AccessItem *)map_to_conf(conf);
135 >    sendto_one_numeric(source_p, &me, ERR_NOOPERHOST);
136 >    conf = find_exact_name_conf(CONF_OPER, NULL, parv[1], NULL, NULL);
137 >    failed_challenge_notice(source_p, parv[1], (conf != NULL)
138 >                            ? "host mismatch" : "no oper {} block");
139 >    return 0;
140    }
141 <  else if ((conf = find_conf_exact(OPER_TYPE,
142 <                                   parv[1], source_p->username,
155 <                                   source_p->sockhost)) != NULL)
141 >
142 >  if (conf->rsa_public_key == NULL)
143    {
144 <    aconf = (struct AccessItem *)map_to_conf(conf);
144 >    sendto_one_notice(source_p, &me, ":I'm sorry, PK authentication "
145 >                      "is not enabled for your oper{} block.");
146 >    return 0;
147    }
148  
149 <  if(aconf == NULL)
149 >  if (IsConfSSL(conf) && !HasUMode(source_p, UMODE_SSL))
150    {
151 <    sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, parv[0]);
152 <    conf = find_exact_name_conf(OPER_TYPE, parv[1], NULL, NULL);
153 <    failed_challenge_notice(source_p, parv[1], (conf != NULL)
165 <                            ? "host mismatch" : "no oper {} block");
166 <    log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n", parv[1]);
167 <    return;
151 >    sendto_one_numeric(source_p, &me, ERR_NOOPERHOST);
152 >    failed_challenge_notice(source_p, conf->name, "requires SSL/TLS");
153 >    return 0;
154    }
155  
156 <  if (aconf->rsa_public_key == NULL)
156 >  if (!EmptyString(conf->certfp))
157    {
158 <    sendto_one (source_p, ":%s NOTICE %s :I'm sorry, PK authentication "
159 <                "is not enabled for your oper{} block.", me.name,
160 <                parv[0]);
161 <    return;
158 >    if (EmptyString(source_p->certfp) || strcasecmp(source_p->certfp, conf->certfp))
159 >    {
160 >      sendto_one_numeric(source_p, &me, ERR_NOOPERHOST);
161 >      failed_challenge_notice(source_p, conf->name, "client certificate fingerprint mismatch");
162 >      return 0;
163 >    }
164    }
165  
166    if (!generate_challenge(&challenge, &(source_p->localClient->response),
167 <                          aconf->rsa_public_key))
168 <    sendto_one(source_p, form_str(RPL_RSACHALLENGE),
181 <               me.name, parv[0], challenge);
167 >                          conf->rsa_public_key))
168 >    sendto_one_numeric(source_p, &me, RPL_RSACHALLENGE, challenge);
169  
170 <  DupString(source_p->localClient->auth_oper, conf->name);
170 >  source_p->localClient->auth_oper = xstrdup(conf->name);
171    MyFree(challenge);
172 +  return 0;
173   }
174  
175 < /* failed_challenge_notice()
175 > /*! \brief CHALLENGE command handler
176   *
177 < * inputs       - pointer to client doing /oper ...
178 < *              - pointer to nick they tried to oper as
179 < *              - pointer to reason they have failed
180 < * output       - nothing
181 < * side effects - notices all opers of the failed oper attempt if enabled
177 > * \param source_p Pointer to allocated Client struct from which the message
178 > *                 originally comes from.  This can be a local or remote client.
179 > * \param parc     Integer holding the number of supplied arguments.
180 > * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
181 > *                 pointers.
182 > * \note Valid arguments for this command are:
183 > *      - parv[0] = command
184 > *      - parv[1] = operator to challenge for, or +response
185   */
186 + static int
187 + mo_challenge(struct Client *source_p, int parc, char *parv[])
188 + {
189 +  sendto_one_numeric(source_p, &me, RPL_YOUREOPER);
190 +  return 0;
191 + }
192 +
193 + static struct Message challenge_msgtab =
194 + {
195 +  "CHALLENGE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
196 +  { m_unregistered, m_challenge, m_ignore, m_ignore, mo_challenge, m_ignore }
197 + };
198 +
199   static void
200 < failed_challenge_notice(struct Client *source_p, const char *name,
201 <                        const char *reason)
200 > module_init(void)
201 > {
202 >  mod_add_cmd(&challenge_msgtab);
203 > }
204 >
205 > static void
206 > module_exit(void)
207 > {
208 >  mod_del_cmd(&challenge_msgtab);
209 > }
210 >
211 > #else
212 >
213 > static void
214 > module_init(void)
215   {
199  if (ConfigFileEntry.failed_oper_notice)
200    sendto_realops_flags(UMODE_ALL, L_ALL, "Failed CHALLENGE attempt as %s "
201                         "by %s (%s@%s) - %s", name, source_p->name,
202                         source_p->username, source_p->host, reason);
216   }
217 +
218 + static void
219 + module_exit(void)
220 + {
221 + }
222 + #endif
223 +
224 + struct module module_entry =
225 + {
226 +  .node    = { NULL, NULL, NULL },
227 +  .name    = NULL,
228 +  .version = "$Revision$",
229 +  .handle  = NULL,
230 +  .modinit = module_init,
231 +  .modexit = module_exit,
232 +  .flags   = 0
233 + };

Diff Legend

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