diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 9e2cad3c..c69ef86a 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -24,6 +24,7 @@ import davmail.util.StringUtil; import davmail.exception.DavMailAuthenticationException; import davmail.exception.DavMailException; import davmail.http.DavGatewayHttpClientFacade; +import davmail.http.DavGatewayOTPPrompt; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; @@ -70,6 +71,25 @@ public class ExchangeSession { */ public static final SimpleTimeZone GMT_TIMEZONE = new SimpleTimeZone(0, "GMT"); + protected static final Set USER_NAME_FIELDS = new HashSet(); + 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 PASSWORD_FIELDS = new HashSet(); + static { + PASSWORD_FIELDS.add("password"); + PASSWORD_FIELDS.add("txtUserPass"); + PASSWORD_FIELDS.add("pw"); + PASSWORD_FIELDS.add("basicPassword"); + } + protected static final Set TOKEN_FIELDS = new HashSet(); + static { + TOKEN_FIELDS.add("SafeWordPassword"); + } + protected static final int FREE_BUSY_INTERVAL = 15; protected static final Namespace URN_SCHEMAS_HTTPMAIL = Namespace.getNamespace("urn:schemas:httpmail:"); @@ -367,14 +387,17 @@ public class ExchangeSession { logonMethod.addParameter(name, value); } // custom login form - if ("txtUserName".equals(name) || "userid".equals(name)) { + if (USER_NAME_FIELDS.contains(name)) { userNameInput = name; - } else if ("txtUserPass".equals(name) || "pw".equals(name)) { + } else if (PASSWORD_FIELDS.contains(name)) { passwordInput = name; } else if ("addr".equals(name)) { // this is not a logon form but a redirect form HttpMethod newInitMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, logonMethod); logonMethod = buildLogonMethod(httpClient, newInitMethod); + } else if (TOKEN_FIELDS.contains(name)) { + // one time password, ask user + logonMethod.addParameter(name, DavGatewayOTPPrompt.getOneTimePassword()); } } } else { @@ -448,6 +471,10 @@ public class ExchangeSession { // if logonMethod is not null, try to follow redirection logonMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, logonMethod); checkFormLoginQueryString(logonMethod); + // also check cookies + if (!isAuthenticated()) { + throwAuthenticationFailed(); + } } else { // authentication failed throwAuthenticationFailed(); diff --git a/src/java/davmail/http/DavGatewayOTPPrompt.java b/src/java/davmail/http/DavGatewayOTPPrompt.java new file mode 100644 index 00000000..e09efafb --- /dev/null +++ b/src/java/davmail/http/DavGatewayOTPPrompt.java @@ -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()); + } +} diff --git a/src/java/davmail/ui/PasswordPromptDialog.java b/src/java/davmail/ui/PasswordPromptDialog.java index 33479f70..86f331d2 100644 --- a/src/java/davmail/ui/PasswordPromptDialog.java +++ b/src/java/davmail/ui/PasswordPromptDialog.java @@ -39,7 +39,11 @@ public class PasswordPromptDialog extends JDialog { * @return user password as char array */ public char[] getPassword() { - return password.clone(); + if (password != null) { + return password.clone(); + } else { + return "".toCharArray(); + } } /** diff --git a/src/java/davmailmessages.properties b/src/java/davmailmessages.properties index 853d025c..df369e32 100644 --- a/src/java/davmailmessages.properties +++ b/src/java/davmailmessages.properties @@ -230,4 +230,5 @@ LOG_EXCEPTION_CLOSING_KEYSTORE_INPUT_STREAM=Exception closing keystore input str LOG_SUBFOLDER_ACCESS_FORBIDDEN=Subfolder access forbidden to {0} LOG_FOLDER_NOT_FOUND=Folder {0} not found LOG_FOLDER_ACCESS_FORBIDDEN=Folder access to {0} forbidden -LOG_FOLDER_ACCESS_ERROR=Folder access to {0} error: {1} \ No newline at end of file +LOG_FOLDER_ACCESS_ERROR=Folder access to {0} error: {1} +UI_OTP_PASSWORD_PROMPT=One Time (token) Password: diff --git a/src/java/davmailmessages_fr.properties b/src/java/davmailmessages_fr.properties index 3945f1bf..d5695a7f 100644 --- a/src/java/davmailmessages_fr.properties +++ b/src/java/davmailmessages_fr.properties @@ -230,4 +230,5 @@ LOG_EXCEPTION_CLOSING_KEYSTORE_INPUT_STREAM=Erreur LOG_SUBFOLDER_ACCESS_FORBIDDEN=Accès interdit au sous dossiers de {0} LOG_FOLDER_ACCESS_FORBIDDEN=Accès interdit au dossier {0} LOG_FOLDER_NOT_FOUND=Dossier {0} introuvable -LOG_FOLDER_ACCESS_ERROR=Erreur lors de l''accès au dossier {0} : {1} \ No newline at end of file +LOG_FOLDER_ACCESS_ERROR=Erreur lors de l''accès au dossier {0} : {1} +UI_OTP_PASSWORD_PROMPT=Mot de passe du jeton : \ No newline at end of file