mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-13 19:22:22 -05:00
Experimental OTP (token) based authentication
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@848 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
db0be1fe86
commit
a01b996220
@ -24,6 +24,7 @@ import davmail.util.StringUtil;
|
|||||||
import davmail.exception.DavMailAuthenticationException;
|
import davmail.exception.DavMailAuthenticationException;
|
||||||
import davmail.exception.DavMailException;
|
import davmail.exception.DavMailException;
|
||||||
import davmail.http.DavGatewayHttpClientFacade;
|
import davmail.http.DavGatewayHttpClientFacade;
|
||||||
|
import davmail.http.DavGatewayOTPPrompt;
|
||||||
import org.apache.commons.codec.DecoderException;
|
import org.apache.commons.codec.DecoderException;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.codec.binary.Hex;
|
import org.apache.commons.codec.binary.Hex;
|
||||||
@ -70,6 +71,25 @@ public class ExchangeSession {
|
|||||||
*/
|
*/
|
||||||
public static final SimpleTimeZone GMT_TIMEZONE = new SimpleTimeZone(0, "GMT");
|
public static final SimpleTimeZone GMT_TIMEZONE = new SimpleTimeZone(0, "GMT");
|
||||||
|
|
||||||
|
protected static final Set<String> USER_NAME_FIELDS = new HashSet<String>();
|
||||||
|
static {
|
||||||
|
USER_NAME_FIELDS.add("username");
|
||||||
|
USER_NAME_FIELDS.add("txtUserName");
|
||||||
|
USER_NAME_FIELDS.add("userid");
|
||||||
|
USER_NAME_FIELDS.add("SafeWordUser");
|
||||||
|
}
|
||||||
|
protected static final Set<String> PASSWORD_FIELDS = new HashSet<String>();
|
||||||
|
static {
|
||||||
|
PASSWORD_FIELDS.add("password");
|
||||||
|
PASSWORD_FIELDS.add("txtUserPass");
|
||||||
|
PASSWORD_FIELDS.add("pw");
|
||||||
|
PASSWORD_FIELDS.add("basicPassword");
|
||||||
|
}
|
||||||
|
protected static final Set<String> TOKEN_FIELDS = new HashSet<String>();
|
||||||
|
static {
|
||||||
|
TOKEN_FIELDS.add("SafeWordPassword");
|
||||||
|
}
|
||||||
|
|
||||||
protected static final int FREE_BUSY_INTERVAL = 15;
|
protected static final int FREE_BUSY_INTERVAL = 15;
|
||||||
|
|
||||||
protected static final Namespace URN_SCHEMAS_HTTPMAIL = Namespace.getNamespace("urn:schemas:httpmail:");
|
protected static final Namespace URN_SCHEMAS_HTTPMAIL = Namespace.getNamespace("urn:schemas:httpmail:");
|
||||||
@ -367,14 +387,17 @@ public class ExchangeSession {
|
|||||||
logonMethod.addParameter(name, value);
|
logonMethod.addParameter(name, value);
|
||||||
}
|
}
|
||||||
// custom login form
|
// custom login form
|
||||||
if ("txtUserName".equals(name) || "userid".equals(name)) {
|
if (USER_NAME_FIELDS.contains(name)) {
|
||||||
userNameInput = name;
|
userNameInput = name;
|
||||||
} else if ("txtUserPass".equals(name) || "pw".equals(name)) {
|
} else if (PASSWORD_FIELDS.contains(name)) {
|
||||||
passwordInput = name;
|
passwordInput = name;
|
||||||
} else if ("addr".equals(name)) {
|
} else if ("addr".equals(name)) {
|
||||||
// this is not a logon form but a redirect form
|
// this is not a logon form but a redirect form
|
||||||
HttpMethod newInitMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, logonMethod);
|
HttpMethod newInitMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, logonMethod);
|
||||||
logonMethod = buildLogonMethod(httpClient, newInitMethod);
|
logonMethod = buildLogonMethod(httpClient, newInitMethod);
|
||||||
|
} else if (TOKEN_FIELDS.contains(name)) {
|
||||||
|
// one time password, ask user
|
||||||
|
logonMethod.addParameter(name, DavGatewayOTPPrompt.getOneTimePassword());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -448,6 +471,10 @@ public class ExchangeSession {
|
|||||||
// if logonMethod is not null, try to follow redirection
|
// if logonMethod is not null, try to follow redirection
|
||||||
logonMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, logonMethod);
|
logonMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, logonMethod);
|
||||||
checkFormLoginQueryString(logonMethod);
|
checkFormLoginQueryString(logonMethod);
|
||||||
|
// also check cookies
|
||||||
|
if (!isAuthenticated()) {
|
||||||
|
throwAuthenticationFailed();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// authentication failed
|
// authentication failed
|
||||||
throwAuthenticationFailed();
|
throwAuthenticationFailed();
|
||||||
|
39
src/java/davmail/http/DavGatewayOTPPrompt.java
Normal file
39
src/java/davmail/http/DavGatewayOTPPrompt.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
|
||||||
|
* Copyright (C) 2009 Mickael Guessant
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
package davmail.http;
|
||||||
|
|
||||||
|
import davmail.BundleMessage;
|
||||||
|
import davmail.ui.PasswordPromptDialog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask user one time password.
|
||||||
|
*/
|
||||||
|
public class DavGatewayOTPPrompt {
|
||||||
|
private DavGatewayOTPPrompt() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask user token password
|
||||||
|
* @return user provided one time password
|
||||||
|
*/
|
||||||
|
public static String getOneTimePassword() {
|
||||||
|
PasswordPromptDialog passwordPromptDialog = new PasswordPromptDialog(BundleMessage.format("UI_OTP_PASSWORD_PROMPT"));
|
||||||
|
return String.valueOf(passwordPromptDialog.getPassword());
|
||||||
|
}
|
||||||
|
}
|
@ -39,7 +39,11 @@ public class PasswordPromptDialog extends JDialog {
|
|||||||
* @return user password as char array
|
* @return user password as char array
|
||||||
*/
|
*/
|
||||||
public char[] getPassword() {
|
public char[] getPassword() {
|
||||||
|
if (password != null) {
|
||||||
return password.clone();
|
return password.clone();
|
||||||
|
} else {
|
||||||
|
return "".toCharArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -231,3 +231,4 @@ LOG_SUBFOLDER_ACCESS_FORBIDDEN=Subfolder access forbidden to {0}
|
|||||||
LOG_FOLDER_NOT_FOUND=Folder {0} not found
|
LOG_FOLDER_NOT_FOUND=Folder {0} not found
|
||||||
LOG_FOLDER_ACCESS_FORBIDDEN=Folder access to {0} forbidden
|
LOG_FOLDER_ACCESS_FORBIDDEN=Folder access to {0} forbidden
|
||||||
LOG_FOLDER_ACCESS_ERROR=Folder access to {0} error: {1}
|
LOG_FOLDER_ACCESS_ERROR=Folder access to {0} error: {1}
|
||||||
|
UI_OTP_PASSWORD_PROMPT=One Time (token) Password:
|
||||||
|
@ -231,3 +231,4 @@ LOG_SUBFOLDER_ACCESS_FORBIDDEN=Acc
|
|||||||
LOG_FOLDER_ACCESS_FORBIDDEN=Accès interdit au dossier {0}
|
LOG_FOLDER_ACCESS_FORBIDDEN=Accès interdit au dossier {0}
|
||||||
LOG_FOLDER_NOT_FOUND=Dossier {0} introuvable
|
LOG_FOLDER_NOT_FOUND=Dossier {0} introuvable
|
||||||
LOG_FOLDER_ACCESS_ERROR=Erreur lors de l''accès au dossier {0} : {1}
|
LOG_FOLDER_ACCESS_ERROR=Erreur lors de l''accès au dossier {0} : {1}
|
||||||
|
UI_OTP_PASSWORD_PROMPT=Mot de passe du jeton :
|
Loading…
Reference in New Issue
Block a user