Save This Page
Home » j2ssh-0.2.9-src » com.sshtools.daemon.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.daemon.authentication;
   27   
   28   import com.sshtools.daemon.configuration;
   29   import com.sshtools.daemon.platform;
   30   
   31   import com.sshtools.j2ssh;
   32   import com.sshtools.j2ssh.authentication;
   33   import com.sshtools.j2ssh.configuration;
   34   import com.sshtools.j2ssh.transport;
   35   
   36   import org.apache.commons.logging;
   37   
   38   import java.io;
   39   
   40   import java.util;
   41   
   42   
   43   /**
   44    *
   45    *
   46    * @author $author$
   47    * @version $Revision: 1.11 $
   48    */
   49   public class AuthenticationProtocolServer extends AsyncService {
   50       private static Log log = LogFactory.getLog(AuthenticationProtocolServer.class);
   51       private List completedAuthentications = new ArrayList();
   52       private Map acceptServices = new HashMap();
   53       private List availableAuths;
   54       private String serviceToStart;
   55       private int[] messageFilter = new int[1];
   56       private SshMessageStore methodMessages = new SshMessageStore();
   57       private int attempts = 0;
   58       private boolean completed = false;
   59   
   60       /**
   61    * Creates a new AuthenticationProtocolServer object.
   62    */
   63       public AuthenticationProtocolServer() {
   64           super("ssh-userauth");
   65           messageFilter[0] = SshMsgUserAuthRequest.SSH_MSG_USERAUTH_REQUEST;
   66       }
   67   
   68       /**
   69    *
   70    *
   71    * @throws java.io.IOException
   72    */
   73       protected void onServiceAccept() throws java.io.IOException {
   74       }
   75   
   76       /**
   77    *
   78    *
   79    * @param startMode
   80    *
   81    * @throws java.io.IOException
   82    */
   83       protected void onServiceInit(int startMode) throws java.io.IOException {
   84           // Register the required messages
   85           messageStore.registerMessage(SshMsgUserAuthRequest.SSH_MSG_USERAUTH_REQUEST,
   86               SshMsgUserAuthRequest.class);
   87           transport.addMessageStore(methodMessages);
   88       }
   89   
   90       /**
   91    *
   92    *
   93    * @return
   94    */
   95       public byte[] getSessionIdentifier() {
   96           return transport.getSessionIdentifier();
   97       }
   98   
   99       /**
  100    *
  101    *
  102    * @return
  103    */
  104       public TransportProtocolState getConnectionState() {
  105           return transport.getState();
  106       }
  107   
  108       /**
  109    *
  110    *
  111    * @param msg
  112    *
  113    * @throws IOException
  114    */
  115       public void sendMessage(SshMessage msg) throws IOException {
  116           transport.sendMessage(msg, this);
  117       }
  118   
  119       /**
  120    *
  121    *
  122    * @return
  123    *
  124    * @throws IOException
  125    * @throws SshException
  126    */
  127       public SshMessage readMessage() throws IOException {
  128           try {
  129               return methodMessages.nextMessage();
  130           } catch (InterruptedException ex) {
  131               throw new SshException("The thread was interrupted");
  132           }
  133       }
  134   
  135       /**
  136    *
  137    *
  138    * @param messageId
  139    * @param cls
  140    */
  141       public void registerMessage(int messageId, Class cls) {
  142           methodMessages.registerMessage(messageId, cls);
  143       }
  144   
  145       /**
  146    *
  147    *
  148    * @throws java.io.IOException
  149    * @throws AuthenticationProtocolException
  150    */
  151       protected void onServiceRequest() throws java.io.IOException {
  152           // Send a user auth banner if configured
  153           ServerConfiguration server = (ServerConfiguration) ConfigurationLoader.getConfiguration(ServerConfiguration.class);
  154   
  155           if (server == null) {
  156               throw new AuthenticationProtocolException(
  157                   "Server configuration unavailable");
  158           }
  159   
  160           availableAuths = new ArrayList();
  161   
  162           Iterator it = SshAuthenticationServerFactory.getSupportedMethods()
  163                                                       .iterator();
  164           String method;
  165           List allowed = server.getAllowedAuthentications();
  166   
  167           while (it.hasNext()) {
  168               method = (String) it.next();
  169   
  170               if (allowed.contains(method)) {
  171                   availableAuths.add(method);
  172               }
  173           }
  174   
  175           if (availableAuths.size() <= 0) {
  176               throw new AuthenticationProtocolException(
  177                   "No valid authentication methods have been specified");
  178           }
  179   
  180           // Accept the service request
  181           sendServiceAccept();
  182   
  183           String bannerFile = server.getAuthenticationBanner();
  184   
  185           if (bannerFile != null) {
  186               if (bannerFile.length() > 0) {
  187                   InputStream in = ConfigurationLoader.loadFile(bannerFile);
  188   
  189                   if (in != null) {
  190                       byte[] data = new byte[in.available()];
  191                       in.read(data);
  192                       in.close();
  193   
  194                       SshMsgUserAuthBanner bannerMsg = new SshMsgUserAuthBanner(new String(
  195                                   data));
  196                       transport.sendMessage(bannerMsg, this);
  197                   } else {
  198                       log.info("The banner file '" + bannerFile +
  199                           "' was not found");
  200                   }
  201               }
  202           }
  203       }
  204   
  205       /**
  206    *
  207    *
  208    * @param msg
  209    *
  210    * @throws java.io.IOException
  211    * @throws AuthenticationProtocolException
  212    */
  213       protected void onMessageReceived(SshMessage msg) throws java.io.IOException {
  214           switch (msg.getMessageId()) {
  215           case SshMsgUserAuthRequest.SSH_MSG_USERAUTH_REQUEST: {
  216               onMsgUserAuthRequest((SshMsgUserAuthRequest) msg);
  217   
  218               break;
  219           }
  220   
  221           default:
  222               throw new AuthenticationProtocolException(
  223                   "Unregistered message received!");
  224           }
  225       }
  226   
  227       /**
  228    *
  229    *
  230    * @return
  231    */
  232       protected int[] getAsyncMessageFilter() {
  233           return messageFilter;
  234       }
  235   
  236       /**
  237    *
  238    *
  239    * @param service
  240    */
  241       public void acceptService(Service service) {
  242           acceptServices.put(service.getServiceName(), service);
  243       }
  244   
  245       private void sendUserAuthFailure(boolean success) throws IOException {
  246           Iterator it = availableAuths.iterator();
  247           String auths = null;
  248   
  249           while (it.hasNext()) {
  250               auths = ((auths == null) ? "" : (auths + ",")) +
  251                   (String) it.next();
  252           }
  253   
  254           SshMsgUserAuthFailure reply = new SshMsgUserAuthFailure(auths, success);
  255           transport.sendMessage(reply, this);
  256       }
  257   
  258       /**
  259    *
  260    */
  261       protected void onStop() {
  262           try {
  263               // If authentication succeeded then wait for the
  264               // disconnect and logoff the user
  265               if (completed) {
  266                   try {
  267                       transport.getState().waitForState(TransportProtocolState.DISCONNECTED);
  268                   } catch (InterruptedException ex) {
  269                       log.warn("The authentication service was interrupted");
  270                   }
  271   
  272                   NativeAuthenticationProvider nap = NativeAuthenticationProvider.getInstance();
  273                   nap.logoffUser();
  274               }
  275           } catch (IOException ex) {
  276               log.warn("Failed to logoff " + SshThread.getCurrentThreadUser());
  277           }
  278       }
  279   
  280       private void sendUserAuthSuccess() throws IOException {
  281           SshMsgUserAuthSuccess msg = new SshMsgUserAuthSuccess();
  282           Service service = (Service) acceptServices.get(serviceToStart);
  283           service.init(Service.ACCEPTING_SERVICE, transport); //, nativeSettings);
  284           service.start();
  285           transport.sendMessage(msg, this);
  286           completed = true;
  287           stop();
  288       }
  289   
  290       private void onMsgUserAuthRequest(SshMsgUserAuthRequest msg)
  291           throws IOException {
  292           if (msg.getMethodName().equals("none")) {
  293               sendUserAuthFailure(false);
  294           } else {
  295               if (attempts >= ((ServerConfiguration) ConfigurationLoader.getConfiguration(
  296                           ServerConfiguration.class)).getMaxAuthentications()) {
  297                   // Too many authentication attempts
  298                   transport.disconnect("Too many failed authentication attempts");
  299               } else {
  300                   // If the service is supported then perfrom the authentication
  301                   if (acceptServices.containsKey(msg.getServiceName())) {
  302                       String method = msg.getMethodName();
  303   
  304                       if (availableAuths.contains(method)) {
  305                           SshAuthenticationServer auth = SshAuthenticationServerFactory.newInstance(method);
  306                           serviceToStart = msg.getServiceName();
  307   
  308                           //auth.setUsername(msg.getUsername());
  309                           int result = auth.authenticate(this, msg); //, nativeSettings);
  310   
  311                           if (result == AuthenticationProtocolState.FAILED) {
  312                               sendUserAuthFailure(false);
  313                           } else if (result == AuthenticationProtocolState.COMPLETE) {
  314                               completedAuthentications.add(auth.getMethodName());
  315   
  316                               ServerConfiguration sc = (ServerConfiguration) ConfigurationLoader.getConfiguration(ServerConfiguration.class);
  317                               Iterator it = sc.getRequiredAuthentications()
  318                                               .iterator();
  319   
  320                               while (it.hasNext()) {
  321                                   if (!completedAuthentications.contains(
  322                                               it.next())) {
  323                                       sendUserAuthFailure(true);
  324   
  325                                       return;
  326                                   }
  327                               }
  328   
  329                               thread.setUsername(msg.getUsername());
  330                               sendUserAuthSuccess();
  331                           } else {
  332                               // Authentication probably returned READY as no completion
  333                               // evaluation was needed
  334                           }
  335                       } else {
  336                           sendUserAuthFailure(false);
  337                       }
  338                   } else {
  339                       sendUserAuthFailure(false);
  340                   }
  341   
  342                   attempts++;
  343               }
  344           }
  345       }
  346   }

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