KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freecs > auth > AuthManager


1 package freecs.auth;
2
3 import java.io.File JavaDoc;
4 import java.io.FileInputStream JavaDoc;
5 import java.net.InetAddress JavaDoc;
6 import java.nio.channels.SelectionKey JavaDoc;
7 import java.nio.channels.SocketChannel JavaDoc;
8 import java.util.Properties JavaDoc;
9 import java.util.StringTokenizer JavaDoc;
10 import java.util.Vector JavaDoc;
11 import java.util.regex.Matcher JavaDoc;
12 import java.util.regex.Pattern JavaDoc;
13
14 import freecs.Server;
15 import freecs.commands.AbstractCommand;
16 import freecs.content.Connection;
17 import freecs.content.ContentContainer;
18 import freecs.core.Group;
19 import freecs.core.GroupManager;
20 import freecs.core.Membership;
21 import freecs.core.MembershipManager;
22 import freecs.core.RequestReader;
23 import freecs.core.User;
24 import freecs.core.UserManager;
25 import freecs.interfaces.IReloadable;
26 import freecs.interfaces.IRequest;
27 import freecs.layout.TemplateSet;
28 import freecs.util.FileMonitor;
29
30 public class AuthManager implements IReloadable {
31
32     public static AuthManager instance = new AuthManager();
33     // fields used for tracking config
34
private File JavaDoc configFile;
35     private long configLastModified;
36     
37     private boolean ALLOW_UNREGISTERED_USERS=false;
38     public String JavaDoc USERNAME_REGEX = "^[a-z[A-Z[0-9[]]]]+$";
39
40     // field used for checking usernames
41
public Pattern JavaDoc userNamePattern;
42
43     private IAuthenticator[] list;
44
45     /**
46      * constructs a new AuthManagers
47      */

48     private AuthManager() {
49         list = new IAuthenticator[0];
50     }
51
52     /**
53      * returns a reference to the authentication config. by default called auth.properties
54      * in server config directory
55      * @see freecs.Server#getConfigDir()
56      */

57     public static File JavaDoc getDefaultConfigFile() {
58         return new File JavaDoc(Server.srv.getConfigDir(), "auth.properties");
59     }
60
61     /**
62      * parses a config file into a Properties object
63      */

64     public static Properties JavaDoc parseConfigFile(File JavaDoc configFile) {
65         try {
66             FileInputStream JavaDoc in = new FileInputStream JavaDoc (configFile);
67             Properties JavaDoc props = new Properties JavaDoc ();
68             props.load (in);
69             in.close ();
70             return props;
71         } catch (Exception JavaDoc e) {
72             Server.log (null, "can't read authentication config from " + configFile + " (" + e.toString() + ")", Server.MSG_STATE, Server.LVL_MAJOR);
73             return null;
74         }
75     }
76
77     /**
78      * inits the class with the default configfile
79      */

80     public void init() {
81         init(getDefaultConfigFile());
82     }
83     
84     /**
85      * inits the class with a given config file.
86      * @param configFile represents the Fileobject pointing to the config-file
87      */

88     public void init(File JavaDoc configFile) {
89         this.configFile = configFile;
90         configLastModified = configFile.lastModified();
91         FileMonitor.getFileMonitor().addReloadable(this);
92         createAuthenticators();
93     }
94
95     /**
96      * creates authenticator objects according to <pre>authenticators</pre> property of config,
97      * then calls init() on each authenticator.
98      * if no Authenticator is configured property, NoAuthentication is used by default
99      */

100     public void createAuthenticators() {
101         Properties JavaDoc props = parseConfigFile(configFile);
102         String JavaDoc allowUnregistered = props.getProperty("allowUnregisteredUsers", "false").toLowerCase();
103         ALLOW_UNREGISTERED_USERS = ("true".equals(allowUnregistered)
104                                     || "1".equals(allowUnregistered)
105                                     || "yes".equals(allowUnregistered));
106         USERNAME_REGEX = props.getProperty("usernameRegex", "^[a-z[A-Z[0-9[]]]]+$");
107         userNamePattern = Pattern.compile(AuthManager.instance.USERNAME_REGEX);
108         String JavaDoc classNames = props.getProperty("authenticators", "NoAuthentication");
109         Server.log(this, "creating new authenticators: " + classNames, Server.MSG_CONFIG, Server.LVL_MINOR);
110         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc (classNames, ",");
111         Vector JavaDoc tmpList = new Vector JavaDoc();
112         while (tok.hasMoreTokens()) {
113             String JavaDoc element = tok.nextToken().trim();
114             String JavaDoc additionalConfigPrefix = null;
115             if (element.indexOf(" ")!=-1) {
116                 additionalConfigPrefix = element.substring(element.indexOf(" ")+1).trim();
117                 element = element.substring(0, element.indexOf(" "));
118             }
119             String JavaDoc className = getClass().getPackage().getName() + "." + element;
120             IAuthenticator authObj = null;
121             try {
122                 authObj = (IAuthenticator) Class.forName(className).newInstance();
123             } catch (Exception JavaDoc ex) {
124                 Server.log(this, "Can't load authentication class " + className + ": " + ex.toString(), Server.MSG_ERROR, Server.LVL_MAJOR);
125                 continue;
126             }
127             try {
128                 authObj.init(props, additionalConfigPrefix);
129             } catch (Exception JavaDoc ex1) {
130                 Server.log(this, "Error initializing authentication class " + className + ": " + ex1.toString(), Server.MSG_ERROR, Server.LVL_MAJOR);
131                 continue;
132             }
133             tmpList.add(authObj);
134         }
135         if (tmpList.size() == 0) {
136             tmpList.add(new NoAuthentication());
137             Server.log(this, "No authentication class, starting without authentication", Server.MSG_ERROR, Server.LVL_MAJOR);
138         }
139         list = (IAuthenticator[]) tmpList.toArray(new IAuthenticator[0]);
140     }
141     
142     /**
143      * calls shutdown() on all registered Authenticators
144      * @see freecs.auth.IAuthenticator#shutdown()
145      */

146     public void shutdown() throws Exception JavaDoc {
147         for (int i = 0; i < list.length; i++) {
148             list[i].shutdown();
149         }
150     }
151     
152     /**
153      * checks the credentials of a user against all registered Authenticators
154      * if an Authenticator returns null, the credentials are considered invalid
155      */

156     public User loginUser(String JavaDoc username, String JavaDoc password, String JavaDoc cookie, IRequest req) throws Exception JavaDoc {
157         if (username == null || username.trim().length() < 1)
158             return null;
159         User u = null;
160         for (int i = 0; i < list.length; i++) {
161             if (u == null) {
162                 u = list[i].loginUser(username, password, cookie, req);
163             } else {
164                 u = list[i].loginUser(u, username, password, req);
165             }
166             if (u == null) {
167                 return null;
168             } else if (u.getName() == null || "".equals(u.getName().trim())) {
169                 Server.log (this, list[i].toString() + " returned an invalid userobject having no name!", Server.MSG_AUTH, Server.LVL_MAJOR);
170                 return null;
171             }
172         }
173         if (u.isUnregistered
174                 && !ALLOW_UNREGISTERED_USERS)
175             return null;
176
177         if (u.getColCode() == null
178                 || AbstractCommand._isColorCodeValid(u.getColCode().trim().toLowerCase()) != 0) {
179             TemplateSet ts = Server.srv.templatemanager.getTemplateSet ("default");
180             String JavaDoc templateset = req.getValue ("templateset");
181             if (templateset != null) {
182                ts = Server.srv.templatemanager.getTemplateSet (templateset);
183             }
184             String JavaDoc col = ts.getMessageTemplate("constant.defaultColor");
185             if (col == null)
186                 col = AuthManager.instance.generateColCode();
187             u.setColCode(col);
188             Server.log(Thread.currentThread(), this.toString() + "LOGIN set a newly generated colorcode for " + u.getName() + " to " + u.getColCode(), Server.MSG_AUTH, Server.LVL_VERBOSE);
189         }
190         // aply Memberships to this User
191
String JavaDoc msList = (String JavaDoc) u.getProperty("memberships");
192         if (msList == null)
193             return u;
194         String JavaDoc[] msArr = msList.split(",");
195         for (int i = 0; i < msArr.length; i++) {
196             Membership cms = MembershipManager.instance.getMembership (msArr[i]);
197             if (cms==null) {
198                 Server.log (this, "Membership for key " + msArr[i] + " hasn't been found", Server.MSG_STATE, Server.LVL_VERBOSE);
199                 continue;
200             }
201             cms.add(u);
202         }
203         return u;
204     }
205
206
207     /**
208      * updates the username-patterns for all registered Authenticators
209      * @param pattern represents the regular-expression, which will be used to check the validity of usernames
210      */

211     public void updateUsernamePattern(String JavaDoc pattern) {
212         userNamePattern = Pattern.compile(pattern);
213     }
214
215     /**
216      * checks the given name for validity by using the predeffined pattern.
217      * If this username doesn't match the pattern (or any other custom conditions
218      * cause this username to be invalid), the login will be rejected. This get's
219      * called by the tryLogin()-method of UserManager.java
220      * @see freecs.core.UserManager
221      * @param name username to check
222      * @return true if the given username is a valid username, false if not
223      */

224     public boolean isValidName(String JavaDoc name) {
225         Matcher JavaDoc m = userNamePattern.matcher(name);
226         return m.matches();
227     }
228
229     public void logoutUser(User u) throws Exception JavaDoc {
230         for (int i = 0; i < list.length; i++) {
231             list[i].logoutUser(u);
232         }
233     }
234
235     public void doLogin(IRequest cReq, SelectionKey JavaDoc key, String JavaDoc cookie, ContentContainer c, TemplateSet ts, User u, boolean isHTTP11, RequestReader req) {
236         // LOGIN *********
237
Connection conn = cReq.getConnectionObject();
238         SocketChannel JavaDoc sc = (SocketChannel JavaDoc) key.channel ();
239         InetAddress JavaDoc ia = sc.socket ().getInetAddress ();
240
241         // check user and username for the user's name
242
String JavaDoc user = cReq.getValue ("user");
243         if (user == null)
244             user = cReq.getValue ("username");
245         String JavaDoc pwd = cReq.getValue ("password");
246         String JavaDoc grp = cReq.getValue ("group");
247
248         // if no get params are present -> print login_missing template and return
249
if (user == null || grp == null) {
250             c.setTemplate("login_missing");
251             return;
252         }
253         
254         grp = grp.toLowerCase();
255         StringBuffer JavaDoc sb = new StringBuffer JavaDoc ("logIN - ");
256         if (Server.srv.USE_TOKENSTORE && !Server.srv.isTokenValid(cReq.getValue("token"), cookie)) {
257             sb.append ("invalid token: ");
258             sb.append (user);
259             sb.append ("@");
260             sb.append (conn.toString());
261             Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
262             c.setTemplate ("login_missing");
263         } else if (Server.srv.isBanned (cookie) || Server.srv.isBanned (user) || Server.srv.isBanned(conn)) {
264             // USER IS BANNED
265
sb.append ("user banned: ");
266             sb.append (user);
267             sb.append ("@");
268             sb.append (conn.toString());
269             Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
270             c.setTemplate ("user_banned");
271         } else {
272             short result = UserManager.mgr.tryLogin (user, pwd, grp, ts, req, u);
273             req.currPosition=RequestReader.EVAL_POST_LOGIN_RESULT;
274             if (result == UserManager.LOGIN_CANCELED) {
275                 sb.append ("login timed out ");
276                 sb.append (user);
277                 sb.append ("@");
278                 sb.append (conn.toString());
279                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
280                 c.setTemplate("techerror");
281             } else if (result == UserManager.USEREMAIL_BANED) {
282                 sb.append ("user banned: (email-ban)");
283                 sb.append (user);
284                 sb.append ("@");
285                 sb.append (conn.toString());
286                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
287                 c.setTemplate ("user_banned");
288             } else if (result == UserManager.USERNAME_INVALID) {
289                 sb.append ("username not valid (");
290                 sb.append (user);
291                 sb.append (")");
292                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
293                 c.setTemplate("username_invalid");
294             } else if (result == UserManager.TECHNICAL_ERROR) {
295                 sb.append ("technical errors! Consult error-log.");
296                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
297                 c.setTemplate ("techerror");
298             } else if (result == UserManager.USERNAME_TOO_LONG) {
299                 sb.append ("authentication failed: username longer than max-username-length (");
300                 sb.append (Server.srv.MAX_USERNAME_LENGTH);
301                 sb.append (")@");
302                 sb.append (conn.toString());
303                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MINOR);
304                 c.setTemplate("username_too_long");
305             } else if (result == UserManager.LOGIN_BLOCKED) {
306                 sb.append ("authentication failed: login-blocked Nick");
307                 sb.append (user);
308                 sb.append ("@");
309                 sb.append (conn.toString());
310                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MINOR);
311                 c.setTemplate ("user_banned");
312             } else if (result == UserManager.USERNAME_NOT_ACTIVATED) {
313                 sb.append ("authentication failed: username not activated");
314                 sb.append (user);
315                 sb.append ("@");
316                 sb.append (conn.toString());
317                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MINOR);
318                 c.setTemplate ("username_not_activated");
319             } else if (result == UserManager.LOGIN_GROUP_LOCK) {
320                 sb.append ("authentication failed: login-group locked");
321                 sb.append (user);
322                 sb.append ("@");
323                 sb.append (conn.toString());
324                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MINOR);
325                 c.setTemplate ("login_group_locked");
326             } else if (result == UserManager.LOGIN_GROUP_BAN) {
327                 sb.append ("authentication failed: user is banned from startgroup '");
328                 sb.append (grp);
329                 sb.append ("' ");
330                 sb.append (user);
331                 sb.append ("@");
332                 sb.append (conn.toString());
333                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MINOR);
334                 c.setTemplate ("login_group_banned");
335             } else if (result == UserManager.LOGIN_OK) {
336                 sb.append ("authentication succeeded: ");
337                 sb.append (user);
338                 sb.append ("@");
339                 sb.append (conn.toString());
340                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MINOR);
341                 c.setTemplate ("frameset");
342             } else if (result == UserManager.LOGIN_MISSING) {
343                 sb.append ("login missing ");
344                 sb.append (conn.toString());
345                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_VERBOSE);
346                 c.setTemplate ("login_missing");
347             } else if (result == UserManager.MAX_USERS) {
348                 sb.append ("max users reached: ");
349                 sb.append (user);
350                 sb.append ("@");
351                 sb.append (conn.toString());
352                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
353                 c.setTemplate ("too_many_users");
354             } else if (result == UserManager.LOGIN_COOKIE_MISSING) {
355                 sb.append ("no cookie: ");
356                 sb.append (user);
357                 sb.append ("@");
358                 sb.append (conn.toString ());
359                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MINOR);
360                 c.setTemplate ("no_cookie");
361             } else if (result == UserManager.LOGIN_GROUP_MISSING) {
362                 sb.append ("no group-name given for login: ");
363                 sb.append (user);
364                 sb.append ("@");
365                 sb.append (conn.toString());
366                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_VERBOSE);
367                 c.setTemplate ("login_failed");
368             } else if (result == UserManager.LOGIN_GROUP_NOSTART) {
369                 sb.append ("invalid group '");
370                 sb.append (grp);
371                 sb.append ("': ");
372                 sb.append (user);
373                 sb.append ("@");
374                 sb.append (conn.toString ());
375                 Server.log (this, sb.toString (), Server.MSG_AUTH, Server.LVL_MAJOR);
376                 c.setTemplate ("login_failed");
377             } else if (result == UserManager.LOGIN_COOKIE_DUPLICATE) {
378                 sb.append ("cookie is present for another user ");
379                 sb.append (user);
380                 sb.append ("@");
381                 sb.append (conn.toString());
382                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_VERBOSE);
383                 c.setTemplate ("login_failed");
384             } else if (result == UserManager.LOGIN_PRESENT) {
385                 sb.append ("user is already logged in ");
386                 sb.append (user);
387                 sb.append (conn.toString());
388                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
389                 c.setTemplate ("user_present");
390             } else if (result == UserManager.LOGIN_RELOAD && u != null) {
391                 sb.append ("user hit reload ");
392                 sb.append (user);
393                 sb.append ("@");
394                 sb.append (conn.toString());
395                 Group g = u.getGroup ();
396                 u.setHTTP11 (isHTTP11);
397                 if (g != null) {
398                     g.addUser (u);
399                     c.setTemplate ("frameset");
400                     Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_VERBOSE);
401                     if (ts != null)
402                         u.setTemplateSet (ts);
403                 } else {
404                     sb.append (" but group was null");
405                     g = GroupManager.mgr.getStartingGroup (grp);
406                     if (g == null) {
407                         sb.append (" and ");
408                         sb.append (grp);
409                         sb.append (" is not a starting-group");
410                         c.setTemplate ("login_failed");
411                     } else {
412                         sb.append (" - joins group ");
413                         sb.append (g.getRawName());
414                         g.addUser (u);
415                         c.setTemplate ("frameset");
416                         if (ts != null)
417                             u.setTemplateSet (ts);
418                     }
419                     Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MAJOR);
420                 }
421             } else {
422                 sb.append ("authentication failed: ");
423                 sb.append (user);
424                 sb.append ("@");
425                 sb.append (conn.toString ());
426                 Server.log (this, sb.toString(), Server.MSG_AUTH, Server.LVL_MINOR);
427                 c.setTemplate ("login_failed");
428             }
429         }
430     }
431
432     /**
433      * this can be used if a user doesn't have a color code and
434      * should be assigned a random one
435      */

436     private String JavaDoc generateColCode () {
437         int r = (int) Math.round(Math.random() * 255);
438         int g = (int) Math.round(Math.random() * 255);
439         int b = (int) Math.round(Math.random() * 255);
440         while ((r+g+b) > 432) {
441             if (r>0) r--;
442             if (g>0) g--;
443             if (b>0) b--;
444         }
445         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
446         if (r < 16)
447             sb.append("0");
448         sb.append (Integer.toHexString(r));
449         if (g < 16)
450             sb.append("0");
451         sb.append (Integer.toHexString(g));
452         if (b < 16)
453             sb.append("0");
454         sb.append (Integer.toHexString(b));
455         return sb.toString();
456     }
457
458     /***************************************************************************
459      * interface IReloadable
460      **************************************************************************/

461     
462     public File JavaDoc getFile() {
463         return configFile;
464     }
465
466     public boolean filePresent() {
467         return configFile.exists();
468     }
469
470     public long lastModified() {
471         return configLastModified;
472     }
473
474     public void changed() {
475         configLastModified = configFile.lastModified();
476         Server.log(this, "authconfig in " + configFile + " changed, reloading.", Server.MSG_CONFIG, Server.LVL_MINOR);
477         synchronized(this) {
478             try {
479                 // kill all existing authenticators
480
shutdown();
481             } catch (Exception JavaDoc ex) {
482             }
483             // create the new ones from scratch
484
createAuthenticators();
485         }
486     }
487
488     public void removed() {
489     }
490
491     public void created() {
492         changed();
493     }
494
495     
496 }
497
Popular Tags