001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 package org.apache.geronimo.javamail.authentication; 021 022 import java.io.UnsupportedEncodingException; 023 024 import javax.mail.MessagingException; 025 026 public class PlainAuthenticator implements ClientAuthenticator { 027 028 // the user we're authenticating 029 protected String username; 030 031 // the user's password (the "shared secret") 032 protected String password; 033 034 // indicates whether we've gone through the entire challenge process. 035 protected boolean complete = false; 036 037 /** 038 * Main constructor. 039 * 040 * @param username 041 * The login user name. 042 * @param password 043 * The login password. 044 */ 045 public PlainAuthenticator(String username, String password) { 046 this.username = username; 047 this.password = password; 048 } 049 050 /** 051 * Respond to the hasInitialResponse query. This mechanism does have an 052 * initial response, which is the entire challenge sequence. 053 * 054 * @return Always returns true. 055 */ 056 public boolean hasInitialResponse() { 057 return true; 058 } 059 060 /** 061 * Indicate whether the challenge/response process is complete. 062 * 063 * @return True if the last challenge has been processed, false otherwise. 064 */ 065 public boolean isComplete() { 066 return complete; 067 } 068 069 /** 070 * Retrieve the authenticator mechanism name. 071 * 072 * @return Always returns the string "PLAIN" 073 */ 074 public String getMechanismName() { 075 return "PLAIN"; 076 } 077 078 /** 079 * Evaluate a PLAIN login challenge, returning the a result string that 080 * should satisfy the clallenge. 081 * 082 * @param challenge 083 * The decoded challenge data, as byte array. 084 * 085 * @return A formatted challege response, as an array of bytes. 086 * @exception MessagingException 087 */ 088 public byte[] evaluateChallenge(byte[] challenge) throws MessagingException { 089 try { 090 // get the username and password in an UTF-8 encoding to create the 091 // token 092 byte[] userBytes = username.getBytes("UTF-8"); 093 byte[] passBytes = password.getBytes("UTF-8"); 094 095 // our token has two copies of the username, one copy of the 096 // password, and nulls 097 // between 098 byte[] tokenBytes = new byte[(userBytes.length * 2) + passBytes.length + 2]; 099 100 System.arraycopy(userBytes, 0, tokenBytes, 0, userBytes.length); 101 System.arraycopy(userBytes, 0, tokenBytes, userBytes.length + 1, userBytes.length); 102 System.arraycopy(passBytes, 0, tokenBytes, (userBytes.length * 2) + 2, passBytes.length); 103 104 complete = true; 105 return tokenBytes; 106 107 } catch (UnsupportedEncodingException e) { 108 // got an error, fail this 109 throw new MessagingException("Invalid encoding"); 110 } 111 } 112 }