]> Joshua Wise's Git repositories - dumload.git/blob - src/com/jcraft/jsch/UserAuthKeyboardInteractive.java
Initial commit.
[dumload.git] / src / com / jcraft / jsch / UserAuthKeyboardInteractive.java
1 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2 /*
3 Copyright (c) 2002-2010 ymnk, JCraft,Inc. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8   1. Redistributions of source code must retain the above copyright notice,
9      this list of conditions and the following disclaimer.
10
11   2. Redistributions in binary form must reproduce the above copyright 
12      notice, this list of conditions and the following disclaimer in 
13      the documentation and/or other materials provided with the distribution.
14
15   3. The names of the authors may not be used to endorse or promote products
16      derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 package com.jcraft.jsch;
31
32 class UserAuthKeyboardInteractive extends UserAuth{
33   public boolean start(Session session) throws Exception{
34     super.start(session);
35
36     if(userinfo!=null && !(userinfo instanceof UIKeyboardInteractive)){
37       return false;
38     }
39
40     String dest=username+"@"+session.host;
41     if(session.port!=22){
42       dest+=(":"+session.port);
43     }
44     byte[] password=session.password;
45
46     boolean cancel=false;
47
48     byte[] _username=null;
49     _username=Util.str2byte(username);
50
51     while(true){
52       // send
53       // byte      SSH_MSG_USERAUTH_REQUEST(50)
54       // string    user name (ISO-10646 UTF-8, as defined in [RFC-2279])
55       // string    service name (US-ASCII) "ssh-userauth" ? "ssh-connection"
56       // string    "keyboard-interactive" (US-ASCII)
57       // string    language tag (as defined in [RFC-3066])
58       // string    submethods (ISO-10646 UTF-8)
59       packet.reset();
60       buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
61       buf.putString(_username);
62       buf.putString(Util.str2byte("ssh-connection"));
63       //buf.putString("ssh-userauth".getBytes());
64       buf.putString(Util.str2byte("keyboard-interactive"));
65       buf.putString(Util.empty);
66       buf.putString(Util.empty);
67       session.write(packet);
68
69       boolean firsttime=true;
70       loop:
71       while(true){
72         buf=session.read(buf);
73         int command=buf.getCommand()&0xff;
74
75         if(command==SSH_MSG_USERAUTH_SUCCESS){
76           return true;
77         }
78         if(command==SSH_MSG_USERAUTH_BANNER){
79           buf.getInt(); buf.getByte(); buf.getByte();
80           byte[] _message=buf.getString();
81           byte[] lang=buf.getString();
82           String message=Util.byte2str(_message);
83           if(userinfo!=null){
84             userinfo.showMessage(message);
85           }
86           continue loop;
87         }
88         if(command==SSH_MSG_USERAUTH_FAILURE){
89           buf.getInt(); buf.getByte(); buf.getByte(); 
90           byte[] foo=buf.getString();
91           int partial_success=buf.getByte();
92 //        System.err.println(new String(foo)+
93 //                           " partial_success:"+(partial_success!=0));
94
95           if(partial_success!=0){
96             throw new JSchPartialAuthException(Util.byte2str(foo));
97           }
98
99           if(firsttime){
100             return false;
101             //throw new JSchException("USERAUTH KI is not supported");
102             //cancel=true;  // ??
103           }
104           break;
105         }
106         if(command==SSH_MSG_USERAUTH_INFO_REQUEST){
107           firsttime=false;
108           buf.getInt(); buf.getByte(); buf.getByte();
109           String name=Util.byte2str(buf.getString());
110           String instruction=Util.byte2str(buf.getString());
111           String languate_tag=Util.byte2str(buf.getString());
112           int num=buf.getInt();
113           String[] prompt=new String[num];
114           boolean[] echo=new boolean[num];
115           for(int i=0; i<num; i++){
116             prompt[i]=Util.byte2str(buf.getString());
117             echo[i]=(buf.getByte()!=0);
118           }
119
120           byte[][] response=null;
121
122           if(password!=null && 
123              prompt.length==1 &&
124              !echo[0] &&
125              prompt[0].toLowerCase().startsWith("password:")){
126             response=new byte[1][];
127             response[0]=password;
128             password=null;
129           }
130           else if(num>0
131              ||(name.length()>0 || instruction.length()>0)
132              ){
133             if(userinfo!=null){
134               UIKeyboardInteractive kbi=(UIKeyboardInteractive)userinfo;
135               String[] _response=kbi.promptKeyboardInteractive(dest,
136                                                                name,
137                                                                instruction,
138                                                                prompt,
139                                                                echo);
140               if(_response!=null){
141                 response=new byte[_response.length][];
142                 for(int i=0; i<_response.length; i++){
143                   response[i]=Util.str2byte(_response[i]);
144                 }
145               }
146             }
147           }
148
149           // byte      SSH_MSG_USERAUTH_INFO_RESPONSE(61)
150           // int       num-responses
151           // string    response[1] (ISO-10646 UTF-8)
152           // ...
153           // string    response[num-responses] (ISO-10646 UTF-8)
154           packet.reset();
155           buf.putByte((byte)SSH_MSG_USERAUTH_INFO_RESPONSE);
156           if(num>0 &&
157              (response==null ||  // cancel
158               num!=response.length)){
159
160             if(response==null){  
161               // working around the bug in OpenSSH ;-<
162               buf.putInt(num);
163               for(int i=0; i<num; i++){
164                 buf.putString(Util.empty);
165               }
166             }
167             else{
168               buf.putInt(0);
169             }
170
171             if(response==null)
172               cancel=true;
173           }
174           else{
175             buf.putInt(num);
176             for(int i=0; i<num; i++){
177               buf.putString(response[i]);
178             }
179           }
180           session.write(packet);
181           /*
182           if(cancel)
183             break;
184           */
185           continue loop;
186         }
187         //throw new JSchException("USERAUTH fail ("+command+")");
188         return false;
189       }
190       if(cancel){
191         throw new JSchAuthCancelException("keyboard-interactive");
192         //break;
193       }
194     }
195     //return false;
196   }
197 }
This page took 0.035268 seconds and 4 git commands to generate.