Save This Page
Home » j2ssh-0.2.9-src » com.sshtools.j2ssh.authentication » [javadoc | source]
    1   /*
    2    *  SSHTools - Java SSH2 API
    3    *
    4    *  Copyright (C) 2002-2003 Lee David Painter and Contributors.
    5    *
    6    *  Contributions made by:
    7    *
    8    *  Brett Smith
    9    *  Richard Pernavas
   10    *  Erwin Bolwidt
   11    *
   12    *  This program is free software; you can redistribute it and/or
   13    *  modify it under the terms of the GNU General Public License
   14    *  as published by the Free Software Foundation; either version 2
   15    *  of the License, or (at your option) any later version.
   16    *
   17    *  This program is distributed in the hope that it will be useful,
   18    *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   19    *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20    *  GNU General Public License for more details.
   21    *
   22    *  You should have received a copy of the GNU General Public License
   23    *  along with this program; if not, write to the Free Software
   24    *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   25    */
   26   package com.sshtools.j2ssh.authentication;
   27   
   28   import com.sshtools.j2ssh.SshException;
   29   import com.sshtools.j2ssh.transport.MessageNotAvailableException;
   30   import com.sshtools.j2ssh.transport.MessageStoreEOFException;
   31   import com.sshtools.j2ssh.transport.Service;
   32   import com.sshtools.j2ssh.transport.SshMessage;
   33   
   34   import org.apache.commons.logging.Log;
   35   import org.apache.commons.logging.LogFactory;
   36   
   37   import java.io.IOException;
   38   
   39   import java.util.Iterator;
   40   import java.util.List;
   41   import java.util.Vector;
   42   
   43   
   44   /**
   45    *
   46    *
   47    * @author $author$
   48    * @version $Revision: 1.27 $
   49    */
   50   public class AuthenticationProtocolClient extends Service {
   51       private static Log log = LogFactory.getLog(AuthenticationProtocolClient.class);
   52       private int[] resultFilter = new int[2];
   53       private int[] singleIdFilter = new int[3];
   54       private Vector listeners = new Vector();
   55   
   56       /**
   57        * Creates a new AuthenticationProtocolClient object.
   58        */
   59       public AuthenticationProtocolClient() {
   60           super("ssh-userauth");
   61           resultFilter[0] = SshMsgUserAuthSuccess.SSH_MSG_USERAUTH_SUCCESS;
   62           resultFilter[1] = SshMsgUserAuthFailure.SSH_MSG_USERAUTH_FAILURE;
   63           singleIdFilter[0] = SshMsgUserAuthSuccess.SSH_MSG_USERAUTH_SUCCESS;
   64           singleIdFilter[1] = SshMsgUserAuthFailure.SSH_MSG_USERAUTH_FAILURE;
   65       }
   66   
   67       /**
   68        *
   69        *
   70        * @throws java.io.IOException
   71        */
   72       protected void onServiceAccept() throws java.io.IOException {
   73       }
   74   
   75       /**
   76        *
   77        */
   78       protected void onStart() {
   79       }
   80   
   81       /**
   82        *
   83        *
   84        * @param startMode
   85        *
   86        * @throws java.io.IOException
   87        * @throws IOException
   88        */
   89       protected void onServiceInit(int startMode) throws java.io.IOException {
   90           if (startMode == Service.ACCEPTING_SERVICE) {
   91               throw new IOException(
   92                   "The Authentication Protocol client cannot be accepted");
   93           }
   94   
   95           messageStore.registerMessage(SshMsgUserAuthFailure.SSH_MSG_USERAUTH_FAILURE,
   96               SshMsgUserAuthFailure.class);
   97           messageStore.registerMessage(SshMsgUserAuthSuccess.SSH_MSG_USERAUTH_SUCCESS,
   98               SshMsgUserAuthSuccess.class);
   99           messageStore.registerMessage(SshMsgUserAuthBanner.SSH_MSG_USERAUTH_BANNER,
  100               SshMsgUserAuthBanner.class);
  101   
  102           //messageStore.registerMessage(SshMsgUserAuthPwdChangeReq.SSH_MSG_USERAUTH_PWD_CHANGEREQ,
  103           //    SshMsgUserAuthPwdChangeReq.class);
  104       }
  105   
  106       /**
  107        *
  108        *
  109        * @throws java.io.IOException
  110        * @throws IOException
  111        */
  112       protected void onServiceRequest() throws java.io.IOException {
  113           throw new IOException("This class implements the client protocol only!");
  114       }
  115   
  116       /**
  117        *
  118        *
  119        * @param listener
  120        */
  121       public void addEventListener(AuthenticationProtocolListener listener) {
  122           if (listener != null) {
  123               listeners.add(listener);
  124           }
  125       }
  126   
  127       /**
  128        *
  129        *
  130        * @param username
  131        * @param serviceName
  132        *
  133        * @return
  134        *
  135        * @throws IOException
  136        * @throws SshException
  137        */
  138       public List getAvailableAuths(String username, String serviceName)
  139           throws IOException {
  140           log.info("Requesting authentication methods");
  141   
  142           SshMessage msg = new SshMsgUserAuthRequest(username, serviceName,
  143                   "none", null);
  144           transport.sendMessage(msg, this);
  145   
  146           try {
  147               msg = messageStore.getMessage(resultFilter);
  148           } catch (InterruptedException ex) {
  149               throw new SshException(
  150                   "The thread was interrupted whilst waiting for an authentication message");
  151           }
  152   
  153           if (msg instanceof SshMsgUserAuthFailure) {
  154               return ((SshMsgUserAuthFailure) msg).getAvailableAuthentications();
  155           } else {
  156               throw new IOException(
  157                   "None request returned success! Insecure feature not supported");
  158           }
  159       }
  160   
  161       /**
  162        *
  163        *
  164        * @param auth
  165        * @param serviceToStart
  166        *
  167        * @return
  168        *
  169        * @throws IOException
  170        * @throws SshException
  171        */
  172       public int authenticate(SshAuthenticationClient auth, Service serviceToStart)
  173           throws IOException {
  174           try {
  175               if (!auth.canAuthenticate() && auth.canPrompt()) {
  176                   SshAuthenticationPrompt prompt = auth.getAuthenticationPrompt();
  177   
  178                   if (!prompt.showPrompt(auth)) {
  179                       return AuthenticationProtocolState.CANCELLED;
  180                   }
  181               }
  182   
  183               auth.authenticate(this, serviceToStart.getServiceName());
  184   
  185               SshMessage msg = parseMessage(messageStore.getMessage(resultFilter));
  186   
  187               // We should not get this far
  188               throw new AuthenticationProtocolException(
  189                   "Unexpected authentication message " + msg.getMessageName());
  190           } catch (TerminatedStateException tse) {
  191               if (tse.getState() == AuthenticationProtocolState.COMPLETE) {
  192                   serviceToStart.init(Service.ACCEPTING_SERVICE, transport); //, nativeSettings);
  193                   serviceToStart.start();
  194   
  195                   for (Iterator it = listeners.iterator(); it.hasNext();) {
  196                       AuthenticationProtocolListener listener = (AuthenticationProtocolListener) it.next();
  197   
  198                       if (listener != null) {
  199                           listener.onAuthenticationComplete();
  200                       }
  201                   }
  202               }
  203   
  204               return tse.getState();
  205           } catch (InterruptedException ex) {
  206               throw new SshException(
  207                   "The thread was interrupted whilst waiting for an authentication message");
  208           }
  209       }
  210   
  211       /**
  212        *
  213        *
  214        * @param msg
  215        *
  216        * @throws IOException
  217        */
  218       public void sendMessage(SshMessage msg) throws IOException {
  219           transport.sendMessage(msg, this);
  220       }
  221   
  222       /**
  223        *
  224        *
  225        * @return
  226        */
  227       public byte[] getSessionIdentifier() {
  228           return transport.getSessionIdentifier();
  229       }
  230   
  231       /**
  232        *
  233        *
  234        * @param cls
  235        * @param messageId
  236        */
  237       public void registerMessage(Class cls, int messageId) {
  238           messageStore.registerMessage(messageId, cls);
  239       }
  240   
  241       /**
  242        *
  243        *
  244        * @param messageId
  245        *
  246        * @return
  247        *
  248        * @throws TerminatedStateException
  249        * @throws IOException
  250        */
  251       public SshMessage readMessage(int messageId)
  252           throws TerminatedStateException, IOException {
  253           singleIdFilter[2] = messageId;
  254   
  255           return internalReadMessage(singleIdFilter);
  256       }
  257   
  258       private SshMessage internalReadMessage(int[] messageIdFilter)
  259           throws TerminatedStateException, IOException {
  260           try {
  261               SshMessage msg = messageStore.getMessage(messageIdFilter);
  262   
  263               return parseMessage(msg);
  264           } catch (MessageStoreEOFException meof) {
  265               throw new AuthenticationProtocolException("Failed to read messages");
  266           } catch (InterruptedException ex) {
  267               throw new SshException(
  268                   "The thread was interrupted whilst waiting for an authentication message");
  269           }
  270       }
  271   
  272       /**
  273        *
  274        *
  275        * @param messageId
  276        *
  277        * @return
  278        *
  279        * @throws TerminatedStateException
  280        * @throws IOException
  281        */
  282       public SshMessage readMessage(int[] messageId)
  283           throws TerminatedStateException, IOException {
  284           int[] messageIdFilter = new int[messageId.length + resultFilter.length];
  285           System.arraycopy(resultFilter, 0, messageIdFilter, 0,
  286               resultFilter.length);
  287           System.arraycopy(messageId, 0, messageIdFilter, resultFilter.length,
  288               messageId.length);
  289   
  290           return internalReadMessage(messageIdFilter);
  291       }
  292   
  293       /**
  294        *
  295        *
  296        * @throws IOException
  297        * @throws TerminatedStateException
  298        */
  299       public void readAuthenticationState()
  300           throws IOException, TerminatedStateException {
  301           internalReadMessage(resultFilter);
  302       }
  303   
  304       private SshMessage parseMessage(SshMessage msg)
  305           throws TerminatedStateException {
  306           if (msg instanceof SshMsgUserAuthFailure) {
  307               if (((SshMsgUserAuthFailure) msg).getPartialSuccess()) {
  308                   throw new TerminatedStateException(AuthenticationProtocolState.PARTIAL);
  309               } else {
  310                   throw new TerminatedStateException(AuthenticationProtocolState.FAILED);
  311               }
  312           } else if (msg instanceof SshMsgUserAuthSuccess) {
  313               throw new TerminatedStateException(AuthenticationProtocolState.COMPLETE);
  314           } else {
  315               return msg;
  316           }
  317       }
  318   
  319       /**
  320        *
  321        *
  322        * @param timeout
  323        *
  324        * @return
  325        *
  326        * @throws IOException
  327        * @throws SshException
  328        */
  329       public String getBannerMessage(int timeout) throws IOException {
  330           try {
  331               log.debug(
  332                   "getBannerMessage is attempting to read the authentication banner");
  333   
  334               SshMessage msg = messageStore.peekMessage(SshMsgUserAuthBanner.SSH_MSG_USERAUTH_BANNER,
  335                       timeout);
  336   
  337               return ((SshMsgUserAuthBanner) msg).getBanner();
  338           } catch (MessageNotAvailableException e) {
  339               return "";
  340           } catch (MessageStoreEOFException eof) {
  341               log.error(
  342                   "Failed to retreive banner becasue the message store is EOF");
  343   
  344               return "";
  345           } catch (InterruptedException ex) {
  346               throw new SshException(
  347                   "The thread was interrupted whilst waiting for an authentication message");
  348           }
  349       }
  350   }

Save This Page
Home » j2ssh-0.2.9-src » com.sshtools.j2ssh.authentication » [javadoc | source]