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

Last change on this file since 368 was 363, checked in by rjmcnab, 25 years ago

Initial revision.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 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 363 1999-07-10 22:19:29Z rjmcnab $
9 *
10 *********************************************************************/
11
12/*
13 $Log$
14 Revision 1.1 1999/07/10 22:19:29 rjmcnab
15 Initial revision.
16
17
18 */
19
20
21#include "authenaction.h"
22#include "fileutil.h"
23#include "cfgread.h"
24#include "cgiutils.h"
25
26
27/////////////////////////
28// a few useful functions
29/////////////////////////
30
31
32// reads in the password file. It returns true if successful
33// format is: username password status [groups]
34static bool read_passwd (const text_t &passwd_filename, userinfo_tmap &userinfo) {
35 text_tarray passwdline;
36 userinfo_t thisuserinfo;
37
38 userinfo.erase(userinfo.begin(), userinfo.end());
39
40 char *cstr = passwd_filename.getcstr();
41 ifstream passwdin (cstr);
42 delete cstr;
43
44 if (passwdin) {
45 while (read_cfg_line(passwdin, passwdline) >= 0) {
46 if (passwdline.size () >= 3) {
47 // get the information about the user
48 thisuserinfo.clear();
49 thisuserinfo.username = passwdline[0];
50 thisuserinfo.password = passwdline[1];
51 if (passwdline[2] == "enabled") thisuserinfo.status = userinfo_t::enabled;
52 else thisuserinfo.status = userinfo_t::disabled;
53 if (passwdline.size() >= 4) thisuserinfo.groups = passwdline[3];
54
55 // insert the user information into the map
56 if (!thisuserinfo.username.empty()) {
57 userinfo[thisuserinfo.username] = thisuserinfo;
58 }
59 }
60 }
61
62 passwdin.close ();
63 return true;
64 }
65
66 return false;
67}
68
69// returns true if the user was found, false otherwise
70static bool get_user_info (const userinfo_tmap &userinfo, const text_t &username,
71 userinfo_t &thisuser) {
72 thisuser.clear();
73
74 userinfo_tmap::const_iterator thisuser_here = userinfo.find (username);
75 if (thisuser_here != userinfo.end()) {
76 thisuser = (*thisuser_here).second;
77 return true;
78 }
79
80 return false;
81}
82
83// return true if the password matches, false if it doesn't
84static bool check_passwd (const userinfo_t &thisuser, const text_t &password) {
85 if (!thisuser.username.empty() && !thisuser.password.empty() &&
86 !password.empty() && thisuser.password == password) return true;
87
88 return false;
89}
90
91static text_t generate_key (const text_t &/*username*/) {
92 return "key";
93}
94
95
96/////////////
97// userinfo_t
98/////////////
99
100
101void userinfo_t::clear () {
102 username.clear();
103 password.clear();
104 status = invalid;
105 groups.clear();
106}
107
108
109
110///////////////
111// authenaction
112///////////////
113
114authenaction::authenaction () {
115 // this action uses cgi variable "a"
116 cgiarginfo arg_ainfo;
117 arg_ainfo.shortname = "a";
118 arg_ainfo.longname = "action";
119 arg_ainfo.multiplechar = true;
120 arg_ainfo.defaultstatus = cgiarginfo::weak;
121 arg_ainfo.argdefault = "a";
122 arg_ainfo.savedarginfo = cgiarginfo::must;
123 argsinfo.addarginfo (NULL, arg_ainfo);
124
125 // "us"
126 arg_ainfo.shortname = "us";
127 arg_ainfo.longname = "user account status";
128 arg_ainfo.multiplechar = true;
129 arg_ainfo.defaultstatus = cgiarginfo::weak;
130 arg_ainfo.argdefault = "invalid";
131 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
132 argsinfo.addarginfo (NULL, arg_ainfo);
133
134 // "ug"
135 arg_ainfo.shortname = "ug";
136 arg_ainfo.longname = "user groups"; // comma seperated list
137 arg_ainfo.multiplechar = true;
138 arg_ainfo.defaultstatus = cgiarginfo::weak;
139 arg_ainfo.argdefault = "";
140 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
141 argsinfo.addarginfo (NULL, arg_ainfo);
142
143 // "un"
144 arg_ainfo.shortname = "un";
145 arg_ainfo.longname = "user name";
146 arg_ainfo.multiplechar = true;
147 arg_ainfo.defaultstatus = cgiarginfo::weak;
148 arg_ainfo.argdefault = "";
149 arg_ainfo.savedarginfo = cgiarginfo::must;
150 argsinfo.addarginfo (NULL, arg_ainfo);
151
152 // "pw"
153 arg_ainfo.shortname = "pw";
154 arg_ainfo.longname = "password";
155 arg_ainfo.multiplechar = true;
156 arg_ainfo.defaultstatus = cgiarginfo::weak;
157 arg_ainfo.argdefault = "";
158 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
159 argsinfo.addarginfo (NULL, arg_ainfo);
160
161 // "ky" - gives a specific user authentication for a
162 // limited amount of time
163 arg_ainfo.shortname = "ky";
164 arg_ainfo.longname = "user time key";
165 arg_ainfo.multiplechar = true;
166 arg_ainfo.defaultstatus = cgiarginfo::weak;
167 arg_ainfo.argdefault = "";
168 arg_ainfo.savedarginfo = cgiarginfo::must;
169 argsinfo.addarginfo (NULL, arg_ainfo);
170
171 // "ua" - ""=no, "1"=yes
172 arg_ainfo.shortname = "ua";
173 arg_ainfo.longname = "whether a user has been authenticated";
174 arg_ainfo.multiplechar = true;
175 arg_ainfo.defaultstatus = cgiarginfo::weak;
176 arg_ainfo.argdefault = "";
177 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
178 argsinfo.addarginfo (NULL, arg_ainfo);
179
180 // "er" - compressed arguments for the referer page
181 arg_ainfo.shortname = "er";
182 arg_ainfo.longname = "the compressed args of the refer page";
183 arg_ainfo.multiplechar = true;
184 arg_ainfo.defaultstatus = cgiarginfo::weak;
185 arg_ainfo.argdefault = "";
186 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
187 argsinfo.addarginfo (NULL, arg_ainfo);
188
189 // "uan" - whether user authentication is needed
190 arg_ainfo.shortname = "uan";
191 arg_ainfo.longname = "whether user authentication is needed";
192 arg_ainfo.multiplechar = true;
193 arg_ainfo.defaultstatus = cgiarginfo::weak;
194 arg_ainfo.argdefault = "";
195 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
196 argsinfo.addarginfo (NULL, arg_ainfo);
197}
198
199void authenaction::configure (const text_t &key, const text_tarray &cfgline) {
200 // get the password filename
201 if (cfgline.size() == 1) {
202 if (key == "passwdfile") passwdfile = cfgline[0];
203 else if (key == "gsdlhome" && passwdfile.empty()) {
204 passwdfile = filename_cat (cfgline[0], "etc", "passwd");
205 }
206 }
207
208 action::configure (key, cfgline);
209}
210
211bool authenaction::init (ostream &logout) {
212 outconvertclass text_t2ascii;
213
214 // read in the password file
215 if (!read_passwd (passwdfile, userinfo)) {
216 logout << text_t2ascii << "Error: could not read in the password file "
217 << passwdfile << "\n";
218 return false;
219 }
220
221 return action::init (logout);
222}
223
224bool authenaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &/*args*/,
225 ostream &/*logout*/) {
226 return true;
227}
228
229// returns false if there is a major problem with the cgi arguments -- not
230// if authentication fails. If the authentication fails "un" will be empty
231bool authenaction::check_external_cgiargs (cgiargsinfoclass &argsinfo,
232 cgiargsclass &args,
233 outconvertclass &outconvert,
234 const text_t &saveconf,
235 ostream &logout) {
236 // success will be dealt with using a redirect in get_cgihead_info if neede
237 // failure means we have to redirect to this action to get authentication
238 // (if we are not already doing this)
239
240 userinfo_t thisuser;
241
242 text_t &args_uan = args["uan"];
243 text_t &args_un = args["un"];
244 text_t &args_pw = args["pw"];
245 text_t &args_us = args["us"];
246 text_t &args_ug = args["ug"];
247 text_t &args_ky = args["ky"];
248 text_t &args_ua = args["ua"];
249
250 args_ua.clear(); // default = false;
251 if (args_un.empty() || args_pw.empty()) args_us = "invalid";
252 else args_us = "failed";
253
254 // make sure we have a username
255 if (!args_un.empty() && get_user_info (userinfo, args_un, thisuser)) {
256 if (!args_pw.empty()) {
257 // we are authenticating using a password
258 if (check_passwd (thisuser, args_pw))
259 args_ua = "1"; // succeeded
260
261 } else if (!args_ky.empty()) {
262 // we are authenticating using a key
263 args_ua = "1"; // succeeded !!!!!!!!!!!!!!!!!!!
264 }
265 }
266
267 args_pw.clear(); // password goes no further
268
269 if (!args_ua.empty()) {
270 if (thisuser.status==userinfo_t::enabled) {
271 // succeeded, get info about this user
272 args_us = "enabled";
273 args_ug = thisuser.groups;
274 args_ky = generate_key (args_un); // new key
275 } else {
276 // succeeded, however, the account is disabled
277 args_ua.clear();
278 args_us = "disabled";
279 args_ug.clear();
280 args_ky.clear();
281 }
282
283 } else {
284 // failure, reset info about the user
285 args_ug.clear();
286 args_ky.clear();
287 }
288
289 // we will have to redirect the user if authentication is needed,
290 // it failed, and we weren't on our way to be authenticated anyway
291 if (!args_uan.empty() && args_ua.empty() && args["a"] != "a") {
292 // need to save the current arguments in "er"
293 text_t &arg_er = args["er"];
294 if (!compress_save_args(argsinfo, saveconf, args, arg_er, outconvert, logout))
295 arg_er.clear();
296
297 // redirect to this action
298 args["a"] = "a";
299 }
300
301 return true;
302}
303
304void authenaction::get_cgihead_info (cgiargsclass &/*args*/, response_t &response,
305 text_t &response_data, ostream &/*logout*/) {
306 response = content;
307 response_data = "text/html";
308}
309
310void authenaction::define_internal_macros (displayclass &disp, cgiargsclass &args,
311 recptproto */*collectproto*/, ostream &/*logout*/) {
312 // sets _authen:messageextra_ based on the value of args["us"]
313 disp.setmacro ("messagestatus", "authen", ("_authen:message" + args["us"]
314 + "_"));
315}
316
317void authenaction::define_external_macros (displayclass &/*disp*/, cgiargsclass &/*args*/,
318 recptproto */*collectproto*/, ostream &/*logout*/) {
319}
320
321bool authenaction::do_action (cgiargsclass &args, recptproto */*collectproto*/,
322 displayclass &disp, outconvertclass &outconvert,
323 ostream &textout, ostream &/*logout*/) {
324 if (args["us"] == "enabled") {
325 // have been authenticated
326 textout << outconvert << disp
327 << "_authenok:header_\n_authenok:content_\n_authenok:footer_\n";
328 return true;
329 }
330
331 // need to be authenticated
332 textout << outconvert << disp
333 << "_authen:header_\n_authen:content_\n_authen:footer_\n";
334
335 return true;
336}
Note: See TracBrowser for help on using the repository browser.