001 package org.esupportail.cas.server.handlers.database;
002
003 import java.sql.Connection;
004 import java.sql.ResultSet;
005 import java.sql.SQLException;
006 import java.sql.Statement;
007
008 import org.dom4j.Element;
009 import org.esupportail.cas.server.util.RedundantHandler;
010 import org.esupportail.cas.server.util.crypt.Crypt;
011 import org.esupportail.cas.server.util.log.Log;
012
013 /**
014 * This class also implements a database server class, which can
015 * authenticate users by searching into a database. It is used by
016 * SearchDatabaseHandler.
017 *
018 * @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>
019 * @author Jean-Baptiste Daniel <danielj at users.sourceforge.net>
020 * @author Arunas Stockus <arunas.stockus at univ-lr.fr>
021 */
022 public final class QueryDatabaseServer extends DatabaseServer {
023
024 /**
025 * Constructor.
026 *
027 * @param handlerDebug debugging mode of the handler
028 * @param handler the handler the server will be used by
029 * @param serverElement the XML element that declares the server
030 * @throws Exception Exception
031 */
032 public QueryDatabaseServer(
033 final Boolean handlerDebug,
034 final RedundantHandler handler,
035 final Element serverElement) throws Exception {
036 super(handlerDebug, handler, serverElement);
037 traceBegin();
038 traceEnd();
039 }
040
041 /**
042 * Try to authenticate a user (by searching into the handler's database).
043 *
044 * @param username the user's name
045 * @param password the user's password
046 *
047 * @return Server.AUTHENTICATE_SUCCESS, Server.AUTHENTICATE_NOAUTH
048 * or Server.AUTHENTICATE_FAILURE.
049 */
050 public int authenticate(
051 final String username,
052 final String password) {
053 Connection connection = null;
054 traceBegin();
055
056 if (username.indexOf('\'') != -1) {
057 Log.info("Username \"" + username + "\" contains a single quote, this could be an attack.");
058 trace("Usernames containing single quotes are rejected.");
059 traceEnd("AUTHENTICATE_NOAUTH");
060 return AUTHENTICATE_NOAUTH;
061 }
062
063 QueryDatabaseHandler handler = (QueryDatabaseHandler) getHandler();
064
065 try {
066
067 connection = connect(handler.getBindUsername(), handler.getBindPassword());
068 switch (getConnectError()) {
069 case CONNECT_NOAUTH:
070 case CONNECT_FAILURE:
071 trace("Connection failed.");
072 traceEnd("AUTHENTICATE_FAILURE");
073 return AUTHENTICATE_FAILURE;
074 default: //CONNECT_SUCCESS
075 break;
076 }
077
078 trace("Create an SQL statement...");
079 Statement statement = connection.createStatement();
080
081 String sqlQuery = handler.getUserSqlQuery(username);
082
083 trace("Execute the query (" + sqlQuery + ")...");
084 ResultSet statementResult = statement.executeQuery(sqlQuery);
085
086 if (statementResult.next()) {
087
088 String encryption = handler.getEncryption();
089 trace("Username found, checking password (" + encryption + ")...");
090 // now for each result, encrypt the password (if needed) and compare
091 String encryptedPassword = statementResult.getString(1);
092 if (Crypt.match(encryption, password, encryptedPassword)) {
093 // username/password matches
094 trace("Password matches.");
095 trace("Closing the connection...");
096 connection.close();
097 traceEnd("AUTHENTICATE_SUCCESS");
098 return AUTHENTICATE_SUCCESS;
099 } else {
100 trace("Username found but password does not match.");
101 }
102 }
103 // no match found
104 trace("Search failed.");
105 trace("Closing the connection...");
106 connection.close();
107 traceEnd("AUTHENTICATE_NOAUTH");
108 return AUTHENTICATE_NOAUTH;
109
110 } catch (Exception e) {
111 // something went wrong
112 trace("Search failure: " + e.toString());
113 try {
114 trace("Closing the connection...");
115 connection.close();
116 } catch (SQLException e1) {
117 Log.warn("Connection could not be closed.");
118 }
119 traceEnd("AUTHENTICATE_FAILURE");
120 return AUTHENTICATE_FAILURE;
121 }
122
123 }
124
125 }