ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_challenge.c
Revision: 3300
Committed: Sat Apr 12 18:26:22 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 7102 byte(s)
Log Message:
- doxygen

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
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
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
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
22 /*! \file m_challenge.c
23 * \brief Includes required functions for processing the CHALLENGE command.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "client.h"
29 #include "ircd.h"
30 #include "modules.h"
31 #include "numeric.h"
32 #include "send.h"
33 #include "conf.h"
34 #include "rsa.h"
35 #include "parse.h"
36 #include "irc_string.h"
37 #include "log.h"
38 #include "s_user.h"
39 #include "memory.h"
40
41
42 #ifdef HAVE_LIBCRYPTO
43 /* failed_challenge_notice()
44 *
45 * inputs - pointer to client doing /oper ...
46 * - pointer to nick they tried to oper as
47 * - pointer to reason they have failed
48 * output - nothing
49 * side effects - notices all opers of the failed oper attempt if enabled
50 */
51 static void
52 failed_challenge_notice(struct Client *source_p, const char *name,
53 const char *reason)
54 {
55 if (ConfigFileEntry.failed_oper_notice)
56 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
57 "Failed CHALLENGE attempt as %s "
58 "by %s (%s@%s) - %s", name, source_p->name,
59 source_p->username, source_p->host, reason);
60
61 ilog(LOG_TYPE_OPER, "Failed CHALLENGE attempt as %s "
62 "by %s (%s@%s) - %s", name, source_p->name,
63 source_p->username, source_p->host, reason);
64 }
65
66 /*! \brief CHALLENGE command handler
67 *
68 * \param source_p Pointer to allocated Client struct from which the message
69 * originally comes from. This can be a local or remote client.
70 * \param parc Integer holding the number of supplied arguments.
71 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
72 * pointers.
73 * \note Valid arguments for this command are:
74 * - parv[0] = command
75 * - parv[1] = operator to challenge for, or +response
76 */
77 static int
78 m_challenge(struct Client *source_p, int parc, char *parv[])
79 {
80 char *challenge = NULL;
81 struct MaskItem *conf = NULL;
82
83 if (*parv[1] == '+')
84 {
85 /* Ignore it if we aren't expecting this... -A1kmm */
86 if (source_p->localClient->response == NULL)
87 return 0;
88
89 if (irccmp(source_p->localClient->response, ++parv[1]))
90 {
91 sendto_one_numeric(source_p, &me, ERR_PASSWDMISMATCH);
92 failed_challenge_notice(source_p, source_p->localClient->auth_oper,
93 "challenge failed");
94 return 0;
95 }
96
97 conf = find_exact_name_conf(CONF_OPER, source_p,
98 source_p->localClient->auth_oper, NULL, NULL);
99 if (conf == NULL)
100 {
101 sendto_one_numeric(source_p, &me, ERR_NOOPERHOST);
102 conf = find_exact_name_conf(CONF_OPER, NULL, source_p->localClient->auth_oper, NULL, NULL);
103 failed_challenge_notice(source_p, source_p->localClient->auth_oper, (conf != NULL) ?
104 "host mismatch" : "no oper {} block");
105 return 0;
106 }
107
108 if (attach_conf(source_p, conf) != 0)
109 {
110 sendto_one_notice(source_p, &me, ":Can't attach conf!");
111 failed_challenge_notice(source_p, conf->name, "can't attach conf!");
112 return 0;
113 }
114
115 oper_up(source_p);
116
117 ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s",
118 source_p->localClient->auth_oper, source_p->name, source_p->username,
119 source_p->host);
120
121 MyFree(source_p->localClient->response);
122 MyFree(source_p->localClient->auth_oper);
123 source_p->localClient->response = NULL;
124 source_p->localClient->auth_oper = NULL;
125 return 0;
126 }
127
128 MyFree(source_p->localClient->response);
129 MyFree(source_p->localClient->auth_oper);
130 source_p->localClient->response = NULL;
131 source_p->localClient->auth_oper = NULL;
132
133 conf = find_exact_name_conf(CONF_OPER, source_p, parv[1], NULL, NULL);
134
135 if (!conf)
136 {
137 sendto_one_numeric(source_p, &me, ERR_NOOPERHOST);
138 conf = find_exact_name_conf(CONF_OPER, NULL, parv[1], NULL, NULL);
139 failed_challenge_notice(source_p, parv[1], (conf != NULL)
140 ? "host mismatch" : "no oper {} block");
141 return 0;
142 }
143
144 if (conf->rsa_public_key == NULL)
145 {
146 sendto_one_notice(source_p, &me, ":I'm sorry, PK authentication "
147 "is not enabled for your oper{} block.");
148 return 0;
149 }
150
151 if (IsConfSSL(conf) && !HasUMode(source_p, UMODE_SSL))
152 {
153 sendto_one_numeric(source_p, &me, ERR_NOOPERHOST);
154 failed_challenge_notice(source_p, conf->name, "requires SSL/TLS");
155 return 0;
156 }
157
158 if (!EmptyString(conf->certfp))
159 {
160 if (EmptyString(source_p->certfp) || strcasecmp(source_p->certfp, conf->certfp))
161 {
162 sendto_one_numeric(source_p, &me, ERR_NOOPERHOST);
163 failed_challenge_notice(source_p, conf->name, "client certificate fingerprint mismatch");
164 return 0;
165 }
166 }
167
168 if (!generate_challenge(&challenge, &(source_p->localClient->response),
169 conf->rsa_public_key))
170 sendto_one_numeric(source_p, &me, RPL_RSACHALLENGE, challenge);
171
172 source_p->localClient->auth_oper = xstrdup(conf->name);
173 MyFree(challenge);
174 return 0;
175 }
176
177 /*! \brief CHALLENGE command handler
178 *
179 * \param source_p Pointer to allocated Client struct from which the message
180 * originally comes from. This can be a local or remote client.
181 * \param parc Integer holding the number of supplied arguments.
182 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
183 * pointers.
184 * \note Valid arguments for this command are:
185 * - parv[0] = command
186 * - parv[1] = operator to challenge for, or +response
187 */
188 static int
189 mo_challenge(struct Client *source_p, int parc, char *parv[])
190 {
191 sendto_one_numeric(source_p, &me, RPL_YOUREOPER);
192 return 0;
193 }
194
195 static struct Message challenge_msgtab =
196 {
197 "CHALLENGE", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
198 { m_unregistered, m_challenge, m_ignore, m_ignore, mo_challenge, m_ignore }
199 };
200
201 static void
202 module_init(void)
203 {
204 mod_add_cmd(&challenge_msgtab);
205 }
206
207 static void
208 module_exit(void)
209 {
210 mod_del_cmd(&challenge_msgtab);
211 }
212
213 #else
214
215 static void
216 module_init(void)
217 {
218 }
219
220 static void
221 module_exit(void)
222 {
223 }
224 #endif
225
226 struct module module_entry =
227 {
228 .node = { NULL, NULL, NULL },
229 .name = NULL,
230 .version = "$Revision$",
231 .handle = NULL,
232 .modinit = module_init,
233 .modexit = module_exit,
234 .flags = 0
235 };

Properties

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