source: trunk/gsdl/src/recpt/authenaction.cpp@ 421

Last change on this file since 421 was 421, checked in by sjboddie, 25 years ago

added collectinfo argument to some functions

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1/**********************************************************************
2 *
3 * authenaction.cpp -- authenticating users
4 * Copyright (C) 1999 DigiLib Systems Limited, New Zealand
5 *
6 * PUT COPYRIGHT NOTICE HERE
7 *
8 * $Id: authenaction.cpp 421 1999-07-30 02:24:45Z sjboddie $
9 *
10 *********************************************************************/
11
12/*
13 $Log$
14 Revision 1.4 1999/07/30 02:24:43 sjboddie
15 added collectinfo argument to some functions
16
17 Revision 1.3 1999/07/13 23:23:26 rjmcnab
18 Put users in their own gdbm database. Moved a lot of functionality to usersdb
19
20 Revision 1.2 1999/07/11 10:47:32 rjmcnab
21 Got something basic working.
22
23 Revision 1.1 1999/07/10 22:19:29 rjmcnab
24 Initial revision.
25
26
27 */
28
29
30#include "authenaction.h"
31#include "fileutil.h"
32#include "cfgread.h"
33#include "cgiutils.h"
34#include "infodbclass.h"
35#include "gsdltimes.h"
36#include "userdb.h"
37
38
39///////////////
40// authenaction
41///////////////
42
43authenaction::authenaction () {
44 keydecay = 600; // 10 minutes
45 recpt = NULL;
46
47 // this action uses cgi variable "a"
48 cgiarginfo arg_ainfo;
49 arg_ainfo.shortname = "a";
50 arg_ainfo.longname = "action";
51 arg_ainfo.multiplechar = true;
52 arg_ainfo.defaultstatus = cgiarginfo::weak;
53 arg_ainfo.argdefault = "a";
54 arg_ainfo.savedarginfo = cgiarginfo::must;
55 argsinfo.addarginfo (NULL, arg_ainfo);
56
57 // "us"
58 arg_ainfo.shortname = "us";
59 arg_ainfo.longname = "user account status";
60 arg_ainfo.multiplechar = true;
61 arg_ainfo.defaultstatus = cgiarginfo::weak;
62 arg_ainfo.argdefault = "invalid";
63 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
64 argsinfo.addarginfo (NULL, arg_ainfo);
65
66 // "ug"
67 arg_ainfo.shortname = "ug";
68 arg_ainfo.longname = "user groups"; // comma seperated list
69 arg_ainfo.multiplechar = true;
70 arg_ainfo.defaultstatus = cgiarginfo::weak;
71 arg_ainfo.argdefault = "";
72 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
73 argsinfo.addarginfo (NULL, arg_ainfo);
74
75 // "un"
76 arg_ainfo.shortname = "un";
77 arg_ainfo.longname = "user name";
78 arg_ainfo.multiplechar = true;
79 arg_ainfo.defaultstatus = cgiarginfo::weak;
80 arg_ainfo.argdefault = "";
81 arg_ainfo.savedarginfo = cgiarginfo::must;
82 argsinfo.addarginfo (NULL, arg_ainfo);
83
84 // "pw"
85 arg_ainfo.shortname = "pw";
86 arg_ainfo.longname = "password";
87 arg_ainfo.multiplechar = true;
88 arg_ainfo.defaultstatus = cgiarginfo::weak;
89 arg_ainfo.argdefault = "";
90 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
91 argsinfo.addarginfo (NULL, arg_ainfo);
92
93 // "ky" - gives a specific user authentication for a
94 // limited amount of time
95 arg_ainfo.shortname = "ky";
96 arg_ainfo.longname = "user time key";
97 arg_ainfo.multiplechar = true;
98 arg_ainfo.defaultstatus = cgiarginfo::weak;
99 arg_ainfo.argdefault = "";
100 arg_ainfo.savedarginfo = cgiarginfo::must;
101 argsinfo.addarginfo (NULL, arg_ainfo);
102
103 // "ua" - ""=no, "1"=yes
104 arg_ainfo.shortname = "ua";
105 arg_ainfo.longname = "whether a user has been authenticated";
106 arg_ainfo.multiplechar = true;
107 arg_ainfo.defaultstatus = cgiarginfo::weak;
108 arg_ainfo.argdefault = "";
109 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
110 argsinfo.addarginfo (NULL, arg_ainfo);
111
112 // "er" - compressed arguments for the referer page
113 arg_ainfo.shortname = "er";
114 arg_ainfo.longname = "the compressed args of the refer page";
115 arg_ainfo.multiplechar = true;
116 arg_ainfo.defaultstatus = cgiarginfo::weak;
117 arg_ainfo.argdefault = "";
118 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
119 argsinfo.addarginfo (NULL, arg_ainfo);
120
121 // "uan" - whether user authentication is needed
122 arg_ainfo.shortname = "uan";
123 arg_ainfo.longname = "whether user authentication is needed";
124 arg_ainfo.multiplechar = true;
125 arg_ainfo.defaultstatus = cgiarginfo::weak;
126 arg_ainfo.argdefault = "";
127 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
128 argsinfo.addarginfo (NULL, arg_ainfo);
129}
130
131void authenaction::configure (const text_t &key, const text_tarray &cfgline) {
132 // get the password filename
133 if (cfgline.size() == 1) {
134 if (key == "usersfile") usersfile = cfgline[0];
135 else if (key == "keyfile") keyfile = cfgline[0];
136 else if (key == "keydecay") keydecay = cfgline[0].getint();
137 else if (key == "gsdlhome") {
138 if (usersfile.empty())
139 usersfile = filename_cat (cfgline[0], "etc", "users.db");
140 if (keyfile.empty())
141 keyfile = filename_cat (cfgline[0], "etc", "key.db");
142 }
143 }
144
145 action::configure (key, cfgline);
146}
147
148bool authenaction::init (ostream &logout) {
149 return action::init (logout);
150}
151
152bool authenaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &/*args*/,
153 ostream &/*logout*/) {
154 return true;
155}
156
157// returns false if there is a major problem with the cgi arguments -- not
158// if authentication fails. If the authentication fails "un" will be empty
159bool authenaction::check_external_cgiargs (cgiargsinfoclass &argsinfo,
160 cgiargsclass &args,
161 outconvertclass &outconvert,
162 const text_t &saveconf,
163 ostream &logout) {
164 // failure means we have to redirect to this action to get authentication
165 // (if we are not already doing this)
166
167 userinfo_t thisuser;
168
169 text_t &args_uan = args["uan"]; text_t &args_un = args["un"];
170 text_t &args_pw = args["pw"]; text_t &args_us = args["us"];
171 text_t &args_ug = args["ug"]; text_t &args_ky = args["ky"];
172 text_t &args_ua = args["ua"];
173
174 // we must have a username and a password or a key to
175 // do any authentication
176 args_ua.clear(); // default = false;
177 if (args_un.empty() || args_pw.empty()) args_us = "invalid";
178 else args_us = "failed";
179
180 // make sure we have a username
181 if (!args_un.empty() && get_user_info (usersfile, args_un, thisuser)) {
182 if (!args_pw.empty()) {
183 // we are authenticating using a password
184 if (check_passwd (thisuser, args_pw)) args_ua = "1"; // succeeded
185
186 } else if (!args_ky.empty()) {
187 // we are authenticating using a key
188 if (check_key (keyfile, thisuser, args_ky, args_ug, keydecay)) args_ua = "1";
189 else args_us = "stalekey";
190 }
191 }
192
193 args_pw.clear(); // password goes no further
194 if (!args_ua.empty()) {
195 if (thisuser.enabled) {
196 bool haspermission = true;
197 // check to make sure the user is in the required group
198 if (!args_ug.empty()) {
199 haspermission = false;
200 text_t::const_iterator group_here = thisuser.groups.begin();
201 text_t::const_iterator group_end = thisuser.groups.end();
202 text_t thisgroup;
203 while (group_here != group_end) {
204 group_here = getdelimitstr (group_here, group_end, ',', thisgroup);
205 if (thisgroup == args_ug) {
206 haspermission = true;
207 break;
208 }
209 }
210 }
211
212 if (haspermission) {
213 // succeeded, get info about this user
214 // note: we don't need to set "ug" as it is already set to what it needs to be
215 args_us = "enabled";
216 args_ky = generate_key (keyfile, args_un); // new key
217
218 // delete old keys around every 50 accesses
219 if (rand()%50 == 1) remove_old_keys (keyfile, keydecay);
220
221 } else {
222 // succeeded, however, the user is not in the correct group
223 args_ua.clear();
224 args_us = "permissiondenied";
225 args_ug.clear();
226 args_ky.clear();
227 }
228
229 } else {
230 // succeeded, however, the account is disabled
231 args_ua.clear();
232 args_us = "disabled";
233 args_ug.clear();
234 args_ky.clear();
235 }
236
237 } else {
238 // failure, reset info about the user
239 args_ug.clear();
240 args_ky.clear();
241 }
242
243 // we will have to redirect the user if authentication is needed,
244 // it failed, and we weren't on our way to be authenticated anyway
245 if (!args_uan.empty() && args_ua.empty() && args["a"] != "a") {
246 // need to save the current arguments in "er"
247 text_t &arg_er = args["er"];
248 if (!compress_save_args(argsinfo, saveconf, args, arg_er, outconvert, logout))
249 arg_er.clear();
250
251 // redirect to this action
252 args["a"] = "a";
253 }
254
255 return true;
256}
257
258void authenaction::get_cgihead_info (cgiargsclass &/*args*/, response_t &response,
259 text_t &response_data, ostream &/*logout*/) {
260 response = content;
261 response_data = "text/html";
262}
263
264void authenaction::define_internal_macros (const ColInfoResponse_t &/*collectinfo*/, displayclass &disp,
265 cgiargsclass &args, recptproto */*collectproto*/,
266 ostream &/*logout*/) {
267 // sets _authen:messageextra_ based on the value of args["us"]
268 // _authen:hiddenargs_ to contain all the arguments that were
269 // explicitly set
270 disp.setmacro ("messagestatus", "authen", ("_authen:message" + args["us"]
271 + "_"));
272
273 // get a list of saved configuration arguments (if possible)
274 text_t saveconf;
275 text_tset saveconfset;
276 if (recpt != NULL) {
277 saveconf = recpt->get_configinfo().saveconf;
278 splitchar (saveconf.begin(), saveconf.end(), '-', saveconfset);
279 }
280
281 text_t hiddenargs;
282 cgiargsclass::const_iterator args_here = args.begin();
283 cgiargsclass::const_iterator args_end = args.end();
284 while (args_here != args_end) {
285 // set this as a hidden argument if it came from the cgi arguments,
286 // its not the compressed arguments, the query string, a user name or
287 // password, and if it is not in the compressed arguments
288 if ((*args_here).second.source == cgiarg_t::cgi_arg &&
289 (*args_here).first != "e" && (*args_here).first != "q" &&
290 (*args_here).first != "un" && (*args_here).first != "pw" &&
291 saveconfset.find((*args_here).first) == saveconfset.end()) {
292 hiddenargs += "<input type=hidden name=\"" + (*args_here).first +
293 "\" value=\"_cgiarg" + (*args_here).first + "_\">\n";
294 }
295
296 args_here++;
297 }
298
299 disp.setmacro ("hiddenargs", "authen", hiddenargs);
300}
301
302void authenaction::define_external_macros (const ColInfoResponse_t &/*collectinfo*/, displayclass &/*disp*/,
303 cgiargsclass &/*args*/, recptproto */*collectproto*/,
304 ostream &/*logout*/) {
305}
306
307bool authenaction::do_action (cgiargsclass &args, const ColInfoResponse_t &/*collectinfo*/,
308 recptproto */*collectproto*/, displayclass &disp,
309 outconvertclass &outconvert, ostream &textout,
310 ostream &/*logout*/) {
311 if (args["us"] == "enabled") {
312 // have been authenticated
313 textout << outconvert << disp
314 << "_authenok:header_\n_authenok:content_\n_authenok:footer_\n";
315 return true;
316 }
317
318 // need to be authenticated
319 textout << outconvert << disp
320 << "_authen:header_\n_authen:content_\n_authen:footer_\n";
321
322 return true;
323}
Note: See TracBrowser for help on using the repository browser.