KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > knowgate > acl > ACL


1 /*
2   Copyright (C) 2003 Know Gate S.L. All rights reserved.
3                       C/Oņa, 107 1š2 28050 Madrid (Spain)
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions
7   are met:
8
9   1. Redistributions of source code must retain the above copyright
10      notice, this list of conditions and the following disclaimer.
11
12   2. The end-user documentation included with the redistribution,
13      if any, must include the following acknowledgment:
14      "This product includes software parts from hipergate
15      (http://www.hipergate.org/)."
16      Alternately, this acknowledgment may appear in the software itself,
17      if and wherever such third-party acknowledgments normally appear.
18
19   3. The name hipergate must not be used to endorse or promote products
20      derived from this software without prior written permission.
21      Products derived from this software may not be called hipergate,
22      nor may hipergate appear in their name, without prior written
23      permission.
24
25   This library is distributed in the hope that it will be useful,
26   but WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28
29   You should have received a copy of hipergate License with this code;
30   if not, visit http://www.hipergate.org or mail to info@hipergate.org
31 */

32
33 package com.knowgate.acl;
34
35 import java.sql.SQLException JavaDoc;
36 import java.sql.CallableStatement JavaDoc;
37 import java.sql.Statement JavaDoc;
38 import java.sql.PreparedStatement JavaDoc;
39 import java.sql.ResultSet JavaDoc;
40
41 import java.util.Date JavaDoc;
42
43 import com.knowgate.debug.DebugFile;
44 import com.knowgate.jdc.JDCConnection;
45 import com.knowgate.misc.MD5;
46
47 /**
48  *
49  * <p>Top Level User Authentication and Access Control List Functions.</p>
50  * @author Sergio Montoro Ten
51  * @version 3.0
52  */

53 public final class ACL {
54
55   /**
56    * Default Constructor
57    */

58   public ACL() {
59   }
60
61   /**
62    * <p>Checks whether or not password is valid for given user.</p>
63    * <p>This method calls k_sp_autenticate stored procedure witch looks up tx_pwd field at k_users table and see if it is the same as sAuthStr parameter.</p>
64    * @param oConn Opened Database Connection
65    * @param sUserId User nickname
66    * @param sAuthStr Authentication String (password)
67    * @param iFlags Authentication String Flags
68    * <ul>
69    * <li>ACL.PWD_CLEAR_TEXT Authentication String is passed as clear text (no encryption)
70    * <li>ACL.PWD_DTIP_RC4 Authentication String is given encrypted using RC4 algorithm
71    * </ul>
72    * @return
73    * <ul>
74    * <li>ACL.USER_NOT_FOUND sUserId not found at gu_user field from k_users table
75    * <li>ACL.INVALID_PASSWORD sAuthStr parameter does not match tx_pwd field from k_users for sUserId
76    * <li>ACL.PASSWORD_EXPIRED Password has expired (dt_pwd_expires field value is before current date)
77    * <li>ACL.ACCOUNT_DEACTIVATED User account as been deactivated (field bo_active from k_users table set to zero)
78    * <li>ACL.ACCOUNT_CANCELLED User account as been cancelled (field dt_cancel from k_users table set to date before now)
79    * <li>ACL.INTERNAL_ERROR Internal error while trying to autenticate user
80    * </ul>
81    * @throws SQLException
82    * @throws UnsupportedOperationException If k_sp_autenticate stored procedure is not found
83    */

84
85   public static short autenticate (JDCConnection oConn, String JavaDoc sUserId, String JavaDoc sAuthStr, int iFlags)
86       throws SQLException JavaDoc, UnsupportedOperationException JavaDoc {
87     short iStatus;
88     CallableStatement JavaDoc oCall;
89     Statement JavaDoc oStmt;
90     ResultSet JavaDoc oRSet;
91     String JavaDoc sPassword;
92
93     if (DebugFile.trace) {
94       DebugFile.writeln("Begin ACL.autenticate([Connection], " + sUserId + "," + sAuthStr + "," + iFlags + ")" );
95       DebugFile.incIdent();
96     }
97
98     sPassword = encript(sAuthStr, iFlags);
99
100     switch (oConn.getDataBaseProduct()) {
101
102       case JDCConnection.DBMS_ORACLE:
103
104         if (DebugFile.trace) DebugFile.writeln(" Connection.prepareCall({ call k_sp_autenticate (" + sUserId + "," + sPassword + ",?)})");
105
106         oCall = oConn.prepareCall("{ call k_sp_autenticate (?,?,?)}");
107
108         try {oCall.setQueryTimeout(20);} catch (SQLException JavaDoc sqle) {}
109
110         oCall.setString(1,sUserId);
111         oCall.setString(2,sPassword);
112         oCall.registerOutParameter(3, java.sql.Types.DECIMAL);
113
114         if (DebugFile.trace) DebugFile.writeln(" java.sql.Connection.execute()");
115
116         oCall.execute();
117         iStatus = Short.parseShort(oCall.getBigDecimal(3).toString());
118         oCall.close();
119         break;
120
121       case JDCConnection.DBMS_MSSQL:
122       case JDCConnection.DBMS_MYSQL:
123
124         if (DebugFile.trace) DebugFile.writeln(" Connection.prepareCall({ call k_sp_autenticate (" + sUserId + "," + sPassword + ",?)})");
125
126         oCall = oConn.prepareCall("{ call k_sp_autenticate (?,?,?)}");
127
128         try {oCall.setQueryTimeout(20);} catch (SQLException JavaDoc sqle) {}
129
130         oCall.setString(1,sUserId);
131         oCall.setString(2,sPassword);
132         oCall.registerOutParameter(3, java.sql.Types.SMALLINT);
133
134         if (DebugFile.trace) DebugFile.writeln(" java.sql.Connection.execute()");
135
136         oCall.execute();
137         iStatus = oCall.getShort(3);
138         oCall.close();
139         break;
140
141         case JDCConnection.DBMS_POSTGRESQL:
142           oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
143
144           if (DebugFile.trace) DebugFile.writeln(" Statement.executeQuery(SELECT k_sp_autenticate('" + sUserId + "', '" + sPassword + "', ...))");
145
146           oRSet = oStmt.executeQuery("SELECT k_sp_autenticate('" + sUserId + "','" + sPassword + "')");
147           oRSet.next();
148           iStatus = oRSet.getShort(1);
149           oRSet.close();
150           oStmt.close();
151           break;
152
153         default:
154           throw new UnsupportedOperationException JavaDoc("k_sp_autenticate procedure not found");
155     }
156
157     if (DebugFile.trace) {
158       DebugFile.decIdent();
159       DebugFile.writeln("End ACL.autenticate() : " + iStatus);
160     }
161
162     return iStatus;
163   } // autenticate
164

165   /**
166    * <p>Checks password and captcha for a given user </p>
167    * <p>This method </p>
168    * @param oConn Opened Database Connection
169    * @param sUserId User nickname
170    * @param sAuthStr Authentication String (password)
171    * @param iFlags Authentication String Flags
172    * @param lTimestamp Timestamp (in miliseconds) when sPlainCaptcha was generated
173    * @param lTimemout Number of miliseconds after which sPlainCaptcha expires
174    * @param sPlainCaptcha Captcha plain text
175    * @param sTimeCaptchaMD5 Precomputed MD5 hash for String sPlainCaptcha+lTimestamp
176    * @return This method returns the same values as autenticate(JDCConnection,String,String,int) and also
177    * <ul>
178    * <li>ACL.CAPTCHA_MISMATCH The computed MD5 hash for sPlainCaptcha+lTimestamp does not match sTimeCaptchaMD5
179    * <li>ACL.CAPTCHA_TIMEOUT lTimestamp+lTimeout is before current datetime
180    * </ul>
181    * @throws SQLException
182    * @throws UnsupportedOperationException If k_sp_autenticate stored procedure is not found
183    * @since 2.2
184    */

185
186   public static short autenticate (JDCConnection oConn, String JavaDoc sUserId,
187                                    String JavaDoc sAuthStr, int iFlags,
188                                    long lTimestamp, long lTimeout,
189                                    String JavaDoc sPlainCaptcha,
190                                    String JavaDoc sTimeCaptchaMD5)
191     throws SQLException JavaDoc, UnsupportedOperationException JavaDoc {
192     short iRetVal = autenticate(oConn, sUserId, sAuthStr, iFlags);
193     if (iRetVal>=(short)0) {
194       long lNow = new Date JavaDoc().getTime();
195       if (lTimestamp+lTimeout<lNow) {
196         iRetVal = CAPTCHA_TIMEOUT;
197       } else {
198         MD5 oCaptchaMd5 = new MD5(sPlainCaptcha+String.valueOf(lTimestamp));
199         if (!sTimeCaptchaMD5.equalsIgnoreCase(oCaptchaMd5.asHex()))
200           iRetVal = CAPTCHA_MISMATCH;
201       } // fi (lTimestamp+lCaptchaTimeout<lNow)
202
}
203     return iRetVal;
204   } // autenticate
205

206   /**
207    * <p>Encrypt String</p>
208    * @param sStr String to be encrypted
209    * @param iFlags Encryption flags
210    * <ul>
211    * <li>ACL.PWD_CLEAR_TEXT Do not encrypt sStr (return as it is given)
212    * <li>ACL.PWD_DTIP_RC4 Encrypt using RC4 algorithm
213    * </ul>
214    * @return Encrypted string
215    * @throws NullPointerException if sStr is <b>null</b>
216    * @throws IllegalArgumentException if iFlags!=PWD_CLEAR_TEXT AND iFlags!=PWD_DTIP_RC4
217    */

218
219   public static String JavaDoc encript (String JavaDoc sStr, int iFlags)
220     throws IllegalArgumentException JavaDoc, NullPointerException JavaDoc {
221
222     String JavaDoc sEncrypted;
223
224     if (iFlags!=PWD_CLEAR_TEXT && iFlags!=PWD_DTIP_RC4)
225       throw new IllegalArgumentException JavaDoc("ACL.encript() encryption algorithm must be either PWD_CLEAR_TEXT or PWD_DTIP_RC4");
226
227     if (DebugFile.trace) {
228       DebugFile.writeln("Begin ACL.encript(" + sStr + "," + String.valueOf(iFlags) + ")" );
229       DebugFile.incIdent();
230     }
231
232     if ((iFlags & ACL.PWD_DTIP_RC4)!=0)
233       sEncrypted = RC4EnDeCrypt(sStr, RC4PWD);
234     else
235       sEncrypted = sStr;
236
237     if (DebugFile.trace) {
238       DebugFile.decIdent();
239       DebugFile.writeln("End ACL.encript() : " + sEncrypted);
240     }
241
242     return sEncrypted;
243   } // encript
244

245   /**
246    * <p>Get user unique id given its nickname.</p>
247    * <p>Calls k_get_user_from_nick stored procedure and gets gu_user field from tx_nickname field</p>
248    * @param oConn Database Connection
249    * @param sNickName User nickname (tx_nickname from k_users table)
250    * @param iDomain Domain Identifier (id_domain from k_users table)
251    * @return User Unique Identifier (gu_user from k_users table)
252    * @throws SQLException
253    */

254   public static String JavaDoc getUserIdFromNick (JDCConnection oConn, String JavaDoc sNickName, int iDomain) throws SQLException JavaDoc {
255     String JavaDoc sUserId;
256
257     if (oConn.getDataBaseProduct()==JDCConnection.DBMS_POSTGRESQL) {
258       PreparedStatement JavaDoc oStmt = oConn.prepareStatement(
259           "SELECT gu_user FROM k_users WHERE id_domain=? AND tx_nickname=?",
260           ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
261       oStmt.setInt(1, iDomain);
262       oStmt.setString(2, sNickName);
263       ResultSet JavaDoc oRSet = oStmt.executeQuery();
264       if (oRSet.next())
265         sUserId = oRSet.getString(1);
266       else
267         sUserId = null;
268       oRSet.close();
269       oStmt.close();
270     }
271     else {
272       CallableStatement JavaDoc oCall = oConn.prepareCall("{ call k_get_user_from_nick (?,?,?)}");
273
274       oCall.setInt(1, iDomain);
275       oCall.setString(2, sNickName);
276       oCall.registerOutParameter(3, java.sql.Types.CHAR);
277
278       oCall.execute();
279
280       if (JDCConnection.DBMS_ORACLE==oConn.getDataBaseProduct()) {
281         sUserId = oCall.getString(3);
282         if (null!=sUserId) sUserId = sUserId.trim();
283       }
284       else
285         sUserId = oCall.getString(3);
286
287       oCall.close();
288     }
289
290     return sUserId;
291   } // getUserIdFromNick
292

293   // ---------------------------------------------------------------------------
294

295   private static void RC4Init(String JavaDoc sPwd, char cKey[], int byBox[])
296     throws NullPointerException JavaDoc {
297     int iPwdLen = sPwd.length();
298     int a, b, t;
299
300     for (a=0; a<256; a++) {
301       cKey[a] = sPwd.charAt((a % iPwdLen));
302       byBox[a] = a;
303     }
304
305     for (a=0, b=0; a<256; a++) {
306       b = (b + byBox[a] + cKey[a]) % 256;
307       t = byBox[a];
308       byBox[a] = byBox[b];
309       byBox[b] = t;
310     }
311   }
312
313   /**
314    * Get RC4 default key for encryption
315    */

316   public static String JavaDoc getRC4key () {
317     return RC4PWD;
318   }
319
320   /**
321    * Set RC4 default key for encryption
322    * @param sKey
323    */

324   public static void setRC4key (String JavaDoc sKey) {
325     RC4PWD = sKey;
326   }
327
328   /**
329    * <p>Encrypt text using RC4 algorithm and a default encryption key</p>
330    * @param sTxt Text to be encrypted
331    * @return String Encrypted text
332    * @throws NullPointerException if sTxt is null
333    * @see {@link http://www.4guysfromrolla.com/webtech/010100-1.shtml}
334    */

335
336   public static String JavaDoc RC4EnDeCrypt(String JavaDoc sTxt)
337     throws NullPointerException JavaDoc {
338     return RC4EnDeCrypt(sTxt, RC4PWD);
339   }
340
341   /**
342    * <p>Encrypt text using RC4 algorithm</p>
343    * @param sTxt Text to be encrypted
344    * @param sKey Encryption key
345    * @see {@link http://www.4guysfromrolla.com/webtech/010100-1.shtml}
346    */

347   public static String JavaDoc RC4EnDeCrypt(String JavaDoc sTxt, String JavaDoc sKey) {
348
349     int iTxtLen = sTxt.length();
350     int i=0, j=0;
351     char cKey[] = new char[256];
352     int byBox[] = new int[256];
353     char byCipher[] = new char[iTxtLen];
354     int t;
355     short k;
356
357     RC4Init(sKey, cKey, byBox);
358
359     for (int a=0; a<iTxtLen; a++) {
360       i = (i+1) % 256;
361       j = (j + byBox[i]) % 256;
362       t = byBox[i];
363       byBox[i] = byBox[j];
364       byBox[j] = t;
365       k = (short) byBox[(byBox[i] + byBox[j]) % 256];
366
367       byCipher[a] = (char) (((short)sTxt.charAt(a)) ^ k);
368     } // next
369

370     return new String JavaDoc(byCipher);
371   } // RC4EnDeCrypt
372

373   /**
374    * <p>Gets permissions mask descriptive name for given language</p>
375    * @param iACLMask Permissions Mask, any combination of ACL.PERMISSION_ constants
376    * @param sLanguage Language for localized string {"en", "es"}
377    * @return
378    */

379   public static String JavaDoc getLocalizedMaskName(int iACLMask, String JavaDoc sLanguage) throws IllegalArgumentException JavaDoc {
380     int iName;
381     String JavaDoc es[] = { "Desconocido", "Listar", "Leer", "Aņadir", "Aņadir y Leer", "Moderar", "Modificar", "Control Total"};
382     String JavaDoc en[] = { "Unknown", "List", "Read", "Add", "Add & Read", "Moderate", "Modify", "Full Control"};
383
384     if (PERMISSION_LIST==iACLMask)
385       iName = 1;
386     else if (PERMISSION_READ==iACLMask || (PERMISSION_LIST|PERMISSION_READ)==iACLMask)
387       iName = 2;
388     else if (PERMISSION_ADD==iACLMask || (PERMISSION_LIST|PERMISSION_ADD)==iACLMask)
389       iName = 3;
390     else if ((PERMISSION_ADD|PERMISSION_READ)==iACLMask || (PERMISSION_LIST|PERMISSION_ADD|PERMISSION_READ)==iACLMask)
391       iName = 4;
392     else if ((PERMISSION_MODERATE)==iACLMask ||
393              (PERMISSION_READ|PERMISSION_MODERATE)==iACLMask ||
394              (PERMISSION_LIST|PERMISSION_READ|PERMISSION_MODERATE)==iACLMask ||
395              (PERMISSION_LIST|PERMISSION_READ|PERMISSION_ADD|PERMISSION_MODERATE)==iACLMask)
396       iName = 5;
397     else if ((PERMISSION_MODIFY&iACLMask)!=0 && iACLMask!=2147483647)
398       iName = 6;
399     else if (iACLMask>=255)
400       iName = 7;
401     else
402       iName = 0;
403
404     if (sLanguage.compareToIgnoreCase("es")==0)
405       return es[iName];
406     else if (sLanguage.compareToIgnoreCase("en")==0)
407       return en[iName];
408     else
409       throw new IllegalArgumentException JavaDoc ("language must \"be\" en or \"es\"");
410   } // getLocalizedMaskName
411

412   // ---------------------------------------------------------------------------
413

414   public static String JavaDoc getErrorMessage(short iErrCode) {
415     if (iErrCode<0) {
416       switch (iErrCode) {
417         case USER_NOT_FOUND:
418           return "User not found";
419         case INVALID_PASSWORD:
420           return "Invalid password";
421         case ACCOUNT_DEACTIVATED:
422           return "User not found";
423         case SESSION_EXPIRED:
424           return "Session expired";
425         case DOMAIN_NOT_FOUND:
426           return "Domain not found";
427         case WORKAREA_NOT_FOUND:
428           return "WorkArea not found";
429         case WORKAREA_NOT_SET:
430           return "WorkArea not set";
431         case ACCOUNT_CANCELLED:
432           return "Account cancelled";
433         case PASSWORD_EXPIRED:
434           return "Password expired";
435         case CAPTCHA_MISMATCH:
436           return "Captcha mismatch";
437         case CAPTCHA_TIMEOUT:
438           return "Captcha mismatch";
439         case INTERNAL_ERROR:
440           return "Internal error";
441         default:
442           return "Undefined error";
443       }
444     }
445     else
446       return "";
447   } // getErrorMessage
448

449   // ---------------------------------------------------------------------------
450
// just a random string for RC4 algorithm, change for your own implementation
451
private static String JavaDoc RC4PWD = "LindtExcellence%70Degustation";
452
453   public static final int PERMISSION_LIST = 1;
454   public static final int PERMISSION_READ = 2;
455   public static final int PERMISSION_ADD = 4;
456   public static final int PERMISSION_DELETE = 8;
457   public static final int PERMISSION_MODIFY = 16;
458   public static final int PERMISSION_MODERATE = 32;
459   public static final int PERMISSION_SEND = 64;
460   public static final int PERMISSION_GRANT = 128;
461   public static final int PERMISSION_FULL_CONTROL = 2147483647;
462
463   public static final int ROLE_NONE = 0;
464   public static final int ROLE_ADMIN = 1;
465   public static final int ROLE_POWERUSER = 2;
466   public static final int ROLE_USER = 4;
467   public static final int ROLE_GUEST = 4;
468
469   public static final int PWD_CLEAR_TEXT = 0;
470   public static final int PWD_DTIP_RC4 = 1;
471
472   public static final short USER_NOT_FOUND = -1;
473   public static final short INVALID_PASSWORD = -2;
474   public static final short ACCOUNT_DEACTIVATED = -3;
475   public static final short SESSION_EXPIRED = -4;
476   public static final short DOMAIN_NOT_FOUND = -5;
477   public static final short WORKAREA_NOT_FOUND = -6;
478   public static final short WORKAREA_NOT_SET = -7;
479   public static final short ACCOUNT_CANCELLED = -8;
480   public static final short PASSWORD_EXPIRED = -9;
481   public static final short CAPTCHA_MISMATCH = -10;
482   public static final short CAPTCHA_TIMEOUT = -11;
483   public static final short INTERNAL_ERROR = -255;
484
485 } // ACL
486
Popular Tags