UserAuthGSSAPIWithMIC.java

Go to the documentation of this file.
00001 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
00002 /*
00003 Copyright (c) 2006-2011 ymnk, JCraft,Inc. All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008   1. Redistributions of source code must retain the above copyright notice,
00009      this list of conditions and the following disclaimer.
00010 
00011   2. Redistributions in binary form must reproduce the above copyright 
00012      notice, this list of conditions and the following disclaimer in 
00013      the documentation and/or other materials provided with the distribution.
00014 
00015   3. The names of the authors may not be used to endorse or promote products
00016      derived from this software without specific prior written permission.
00017 
00018 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
00019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00020 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
00021 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
00022 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT
00023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY OF
00025 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
00026 NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00027 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028 */
00029 
00030 package com.jcraft.jsch;
00031 
00061 public class UserAuthGSSAPIWithMIC extends UserAuth {
00062   private static final int SSH_MSG_USERAUTH_GSSAPI_RESPONSE=         60;
00063   private static final int SSH_MSG_USERAUTH_GSSAPI_TOKEN=            61;
00064   private static final int SSH_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE=63;
00065   private static final int SSH_MSG_USERAUTH_GSSAPI_ERROR=            64;
00066   private static final int SSH_MSG_USERAUTH_GSSAPI_ERRTOK=           65;
00067   private static final int SSH_MSG_USERAUTH_GSSAPI_MIC=              66;
00068 
00069   private static final byte[][] supported_oid={
00070     // OID 1.2.840.113554.1.2.2 in DER
00071     {(byte)0x6,(byte)0x9,(byte)0x2a,(byte)0x86,(byte)0x48,
00072      (byte)0x86,(byte)0xf7,(byte)0x12,(byte)0x1,(byte)0x2,
00073      (byte)0x2}
00074   };
00075 
00076   private static final String[] supported_method={
00077     "gssapi-with-mic.krb5"
00078   };
00079 
00084   public boolean start(Session session)throws Exception{
00085     super.start(session);
00086 
00087     byte[] _username=Util.str2byte(username);
00088 
00089     packet.reset();
00090 
00091     // byte            SSH_MSG_USERAUTH_REQUEST(50)
00092     // string          user name(in ISO-10646 UTF-8 encoding)
00093     // string          service name(in US-ASCII)
00094     // string          "gssapi"(US-ASCII)
00095     // uint32          n, the number of OIDs client supports
00096     // string[n]       mechanism OIDS
00097     buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
00098     buf.putString(_username);
00099     buf.putString(Util.str2byte("ssh-connection"));
00100     buf.putString(Util.str2byte("gssapi-with-mic"));
00101     buf.putInt(supported_oid.length);
00102     for(int i=0; i<supported_oid.length; i++){
00103       buf.putString(supported_oid[i]);
00104     }
00105     session.write(packet);
00106 
00107     String method=null;
00108     int command;
00109     while(true){
00110       buf=session.read(buf);
00111       command=buf.getCommand()&0xff;
00112 
00113       if(command==SSH_MSG_USERAUTH_FAILURE){
00114         return false;
00115       }
00116       
00117       if(command==SSH_MSG_USERAUTH_GSSAPI_RESPONSE){
00118         buf.getInt(); buf.getByte(); buf.getByte();
00119         byte[] message=buf.getString();
00120 
00121         for(int i=0; i<supported_oid.length; i++){
00122           if(Util.array_equals(message, supported_oid[i])){
00123             method=supported_method[i];
00124             break;
00125           }
00126         }
00127 
00128         if(method==null){
00129           return false;
00130         }
00131 
00132         break; // success
00133       }
00134 
00135       if(command==SSH_MSG_USERAUTH_BANNER){
00136         buf.getInt(); buf.getByte(); buf.getByte();
00137         byte[] _message=buf.getString();
00138         byte[] lang=buf.getString();
00139         String message=Util.byte2str(_message);
00140         if(userinfo!=null){
00141           userinfo.showMessage(message);
00142         }
00143         continue;
00144       }
00145       return false;
00146     }
00147 
00148     GSSContext context=null;
00149     try{
00150       Class c=Class.forName(session.getConfig(method));
00151       context=(GSSContext)(c.newInstance());
00152     }
00153     catch(Exception e){ 
00154       return false;
00155     }
00156 
00157     try{
00158       context.create(username, session.host);
00159     }
00160     catch(JSchException e){
00161       return false;
00162     }
00163 
00164     byte[] token=new byte[0];
00165 
00166     while(!context.isEstablished()){
00167       try{
00168         token=context.init(token, 0, token.length);
00169       }
00170       catch(JSchException e){
00171         // TODO
00172         // ERRTOK should be sent?
00173         // byte        SSH_MSG_USERAUTH_GSSAPI_ERRTOK
00174         // string      error token
00175         return false;
00176       }
00177 
00178       if(token!=null){
00179         packet.reset();
00180         buf.putByte((byte)SSH_MSG_USERAUTH_GSSAPI_TOKEN);
00181         buf.putString(token);
00182         session.write(packet);
00183       }
00184 
00185       if(!context.isEstablished()){
00186         buf=session.read(buf);
00187         command=buf.getCommand()&0xff;
00188         if(command==SSH_MSG_USERAUTH_GSSAPI_ERROR){
00189           // uint32    major_status
00190           // uint32    minor_status
00191           // string    message
00192           // string    language tag
00193 
00194           buf=session.read(buf);
00195           command=buf.getCommand()&0xff;
00196           //return false;
00197         }
00198         else if(command==SSH_MSG_USERAUTH_GSSAPI_ERRTOK){
00199           // string error token
00200 
00201           buf=session.read(buf);
00202           command=buf.getCommand()&0xff;
00203           //return false;
00204         }
00205 
00206         if(command==SSH_MSG_USERAUTH_FAILURE){
00207           return false;
00208         }
00209 
00210         buf.getInt(); buf.getByte(); buf.getByte();
00211         token=buf.getString();
00212       }
00213     }
00214 
00215     Buffer mbuf=new Buffer();
00216     // string    session identifier
00217     // byte      SSH_MSG_USERAUTH_REQUEST
00218     // string    user name
00219     // string    service
00220     // string    "gssapi-with-mic"
00221     mbuf.putString(session.getSessionId());
00222     mbuf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
00223     mbuf.putString(_username);
00224     mbuf.putString(Util.str2byte("ssh-connection"));
00225     mbuf.putString(Util.str2byte("gssapi-with-mic"));
00226 
00227     byte[] mic=context.getMIC(mbuf.buffer, 0, mbuf.getLength());
00228 
00229     if(mic==null){
00230       return false;
00231     }
00232 
00233     packet.reset();
00234     buf.putByte((byte)SSH_MSG_USERAUTH_GSSAPI_MIC);
00235     buf.putString(mic);
00236     session.write(packet);
00237 
00238     context.dispose();
00239 
00240     buf=session.read(buf);
00241     command=buf.getCommand()&0xff;
00242 
00243     if(command==SSH_MSG_USERAUTH_SUCCESS){
00244       return true;
00245     }
00246     else if(command==SSH_MSG_USERAUTH_FAILURE){
00247       buf.getInt(); buf.getByte(); buf.getByte(); 
00248       byte[] foo=buf.getString();
00249       int partial_success=buf.getByte();
00250       //System.err.println(new String(foo)+
00251       //         " partial_success:"+(partial_success!=0));
00252       if(partial_success!=0){
00253         throw new JSchPartialAuthException(Util.byte2str(foo));
00254       }
00255     }
00256     return false;
00257   }
00258 }
00259 
00260 

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1