ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_challenge.c
Revision: 348
Committed: Sat Dec 31 14:08:37 2005 UTC (20 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 6315 byte(s)
Error occurred while calculating annotation data.
Log Message:
- More documentation

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_challenge.c: Allows an IRC Operator to securely authenticate.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "handlers.h"
27 #include "client.h"
28 #include "ircd.h"
29 #include "modules.h"
30 #include "numeric.h"
31 #include "send.h"
32 #include "s_conf.h"
33 /* -lcrypto is implicit for building this module! */
34 #include "rsa.h"
35 #include "msg.h"
36 #include "parse.h"
37 #include "s_user.h"
38
39 static void failed_challenge_notice(struct Client *, const char *,
40 const char *);
41 static void m_challenge(struct Client *, struct Client *, int, char **);
42
43 /* We have openssl support, so include /CHALLENGE */
44 struct Message challenge_msgtab = {
45 "CHALLENGE", 0, 0, 2, 0, MFLG_SLOW, 0,
46 { m_unregistered, m_challenge, m_ignore, m_ignore, m_challenge, m_ignore }
47 };
48
49 #ifndef STATIC_MODULES
50 void
51 _modinit(void)
52 {
53 mod_add_cmd(&challenge_msgtab);
54 }
55
56 void
57 _moddeinit(void)
58 {
59 mod_del_cmd(&challenge_msgtab);
60 }
61
62 const char *_version = "$Revision$";
63 #endif
64
65 /*! \brief CHALLENGE command handler (called for local clients only)
66 *
67 * Generate RSA challenge for wouldbe oper
68 *
69 * \param client_p Pointer to allocated Client struct with physical connection
70 * to this server, i.e. with an open socket connected.
71 * \param source_p Pointer to allocated Client struct from which the message
72 * originally comes from. This can be a local or remote client.
73 * \param parc Integer holding the number of supplied arguments.
74 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
75 * pointers.
76 * \note Valid arguments for this command are:
77 * - parv[0] = sender prefix
78 * - parv[1] = operator to challenge for, or +response
79 */
80 static void
81 m_challenge(struct Client *client_p, struct Client *source_p,
82 int parc, char *parv[])
83 {
84 char *challenge = NULL;
85 struct ConfItem *conf = NULL;
86 struct AccessItem *aconf = NULL;
87
88 assert(source_p->localClient);
89
90 /* if theyre an oper, reprint oper motd and ignore */
91 if (IsOper(source_p))
92 {
93 sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, parv[0]);
94 send_message_file(source_p, &ConfigFileEntry.opermotd);
95 return;
96 }
97
98 if (*parv[1] == '+')
99 {
100 /* Ignore it if we aren't expecting this... -A1kmm */
101 if (source_p->localClient->response == NULL)
102 return;
103
104 if (irccmp(source_p->localClient->response, ++parv[1]))
105 {
106 sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name,
107 source_p->name);
108 failed_challenge_notice(source_p, source_p->localClient->auth_oper,
109 "challenge failed");
110 return;
111 }
112
113 if ((conf = find_exact_name_conf(OPER_TYPE,
114 source_p->localClient->auth_oper,
115 source_p->username, source_p->host
116 )) == NULL)
117 {
118 sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, parv[0]);
119 log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n",
120 source_p->localClient->auth_oper);
121 return;
122 }
123
124 oper_up(source_p, conf);
125
126 ilog(L_TRACE, "OPER %s by %s!%s@%s",
127 source_p->localClient->auth_oper, source_p->name, source_p->username,
128 source_p->host);
129 log_oper_action(LOG_OPER_TYPE, source_p,
130 "%s\n", source_p->localClient->auth_oper);
131
132 MyFree(source_p->localClient->response);
133 MyFree(source_p->localClient->auth_oper);
134 source_p->localClient->response = NULL;
135 source_p->localClient->auth_oper = NULL;
136 return;
137 }
138
139 MyFree(source_p->localClient->response);
140 MyFree(source_p->localClient->auth_oper);
141 source_p->localClient->response = NULL;
142 source_p->localClient->auth_oper = NULL;
143
144 if ((conf = find_exact_name_conf(OPER_TYPE,
145 parv[1], source_p->username, source_p->host
146 )) != NULL)
147 {
148 aconf = &conf->conf.AccessItem;
149 }
150 else if ((conf = find_exact_name_conf(OPER_TYPE,
151 parv[1], source_p->username,
152 source_p->sockhost)) != NULL)
153 {
154 aconf = &conf->conf.AccessItem;
155 }
156
157 if (aconf == NULL)
158 {
159 sendto_one (source_p, form_str(ERR_NOOPERHOST), me.name, parv[0]);
160 conf = find_exact_name_conf(OPER_TYPE, parv[1], NULL, NULL);
161 failed_challenge_notice(source_p, parv[1], (conf != NULL)
162 ? "host mismatch" : "no oper {} block");
163 log_oper_action(LOG_FAILED_OPER_TYPE, source_p, "%s\n", parv[1]);
164 return;
165 }
166
167 if (aconf->rsa_public_key == NULL)
168 {
169 sendto_one (source_p, ":%s NOTICE %s :I'm sorry, PK authentication "
170 "is not enabled for your oper{} block.", me.name,
171 parv[0]);
172 return;
173 }
174
175 if (!generate_challenge(&challenge, &(source_p->localClient->response),
176 aconf->rsa_public_key))
177 sendto_one(source_p, form_str(RPL_RSACHALLENGE),
178 me.name, source_p->name, challenge);
179
180 DupString(source_p->localClient->auth_oper, conf->name);
181 MyFree(challenge);
182 }
183
184 /* failed_challenge_notice()
185 *
186 * inputs - pointer to client doing /oper ...
187 * - pointer to nick they tried to oper as
188 * - pointer to reason they have failed
189 * output - nothing
190 * side effects - notices all opers of the failed oper attempt if enabled
191 */
192 static void
193 failed_challenge_notice(struct Client *source_p, const char *name,
194 const char *reason)
195 {
196 if (ConfigFileEntry.failed_oper_notice)
197 sendto_realops_flags(UMODE_ALL, L_ALL, "Failed CHALLENGE attempt as %s "
198 "by %s (%s@%s) - %s", name, source_p->name,
199 source_p->username, source_p->host, reason);
200 }

Properties

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