00001 using System;
00002 using System.IO;
00003
00004 namespace Tamir.SharpSsh.jsch
00005 {
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 class UserAuthPublicKey : UserAuth
00036 {
00037 internal UserInfo userinfo;
00038 internal UserAuthPublicKey(UserInfo userinfo)
00039 {
00040 this.userinfo=userinfo;
00041 }
00042
00043 public override bool start(Session session)
00044 {
00045
00046
00047
00048 System.Collections.ArrayList identities=session.jsch.identities;
00049
00050 Packet packet=session.packet;
00051 Buffer buf=session.buf;
00052
00053 String passphrase=null;
00054 String username=session.username;
00055
00056 byte[] _username=null;
00057 try{ _username= Util.getBytesUTF8( username); }
00058 catch
00059 {
00060 _username=Util.getBytes(username);
00061 }
00062
00063 for(int i=0; i<identities.Count; i++)
00064 {
00065 Identity identity=(Identity)(identities[i]);
00066 byte[] pubkeyblob=identity.getPublicKeyBlob();
00067
00068
00069
00070 if(pubkeyblob!=null)
00071 {
00072
00073
00074
00075
00076
00077
00078
00079 packet.reset();
00080 buf.putByte((byte)Session.SSH_MSG_USERAUTH_REQUEST);
00081 buf.putString(_username);
00082 buf.putString(Util.getBytes("ssh-connection"));
00083 buf.putString(Util.getBytes("publickey"));
00084 buf.putByte((byte)0);
00085 buf.putString(Util.getBytes(identity.getAlgName()));
00086 buf.putString(pubkeyblob);
00087 session.write(packet);
00088
00089 loop1:
00090 while(true)
00091 {
00092
00093
00094
00095 buf=session.read(buf);
00096
00097 if(buf.buffer[5]==Session.SSH_MSG_USERAUTH_PK_OK)
00098 {
00099 break;
00100 }
00101 else if(buf.buffer[5]==Session.SSH_MSG_USERAUTH_FAILURE)
00102 {
00103
00104
00105 break;
00106 }
00107 else if(buf.buffer[5]==Session.SSH_MSG_USERAUTH_BANNER)
00108 {
00109 buf.getInt(); buf.getByte(); buf.getByte();
00110 byte[] _message=buf.getString();
00111 byte[] lang=buf.getString();
00112 String message=null;
00113 try{ message=Util.getStringUTF8(_message); }
00114 catch
00115 {
00116 message=Util.getString(_message);
00117 }
00118 if(userinfo!=null)
00119 {
00120 userinfo.showMessage(message);
00121 }
00122 goto loop1;
00123 }
00124 else
00125 {
00126
00127
00128 break;
00129 }
00130 }
00131 if(buf.buffer[5]!=Session.SSH_MSG_USERAUTH_PK_OK)
00132 {
00133 continue;
00134 }
00135 }
00136
00137
00138
00139 int count=5;
00140 while(true)
00141 {
00142 if((identity.isEncrypted() && passphrase==null))
00143 {
00144 if(userinfo==null) throw new JSchException("USERAUTH fail");
00145 if(identity.isEncrypted() &&
00146 !userinfo.promptPassphrase("Passphrase for "+identity.getName()))
00147 {
00148 throw new JSchAuthCancelException("publickey");
00149
00150
00151 }
00152 passphrase=userinfo.getPassphrase();
00153 }
00154
00155 if(!identity.isEncrypted() || passphrase!=null)
00156 {
00157
00158 if(identity.setPassphrase(passphrase))
00159 break;
00160 }
00161 passphrase=null;
00162 count--;
00163 if(count==0)break;
00164 }
00165
00166
00167
00168 if(identity.isEncrypted()) continue;
00169 if(pubkeyblob==null) pubkeyblob=identity.getPublicKeyBlob();
00170
00171
00172
00173 if(pubkeyblob==null) continue;
00174
00175
00176
00177
00178
00179
00180
00181
00182 packet.reset();
00183 buf.putByte((byte)Session.SSH_MSG_USERAUTH_REQUEST);
00184 buf.putString(_username);
00185 buf.putString(Util.getBytes("ssh-connection"));
00186 buf.putString(Util.getBytes("publickey"));
00187 buf.putByte((byte)1);
00188 buf.putString(Util.getBytes(identity.getAlgName()));
00189 buf.putString(pubkeyblob);
00190
00191
00192
00193
00194
00195 byte[] sid=session.getSessionId();
00196 uint sidlen=(uint)sid.Length;
00197 byte[] tmp=new byte[4+sidlen+buf.index-5];
00198 tmp[0]=(byte)(sidlen>>24);
00199 tmp[1]=(byte)(sidlen>>16);
00200 tmp[2]=(byte)(sidlen>>8);
00201 tmp[3]=(byte)(sidlen);
00202 Array.Copy(sid, 0, tmp, 4, sidlen);
00203 Array.Copy(buf.buffer, 5, tmp, 4+sidlen, buf.index-5);
00204
00205 byte[] signature=identity.getSignature(session, tmp);
00206 if(signature==null)
00207 {
00208 break;
00209 }
00210 buf.putString(signature);
00211
00212 session.write(packet);
00213
00214 loop2:
00215 while(true)
00216 {
00217
00218
00219
00220 buf=session.read(buf);
00221
00222 if(buf.buffer[5]==Session.SSH_MSG_USERAUTH_SUCCESS)
00223 {
00224 return true;
00225 }
00226 else if(buf.buffer[5]==Session.SSH_MSG_USERAUTH_BANNER)
00227 {
00228 buf.getInt(); buf.getByte(); buf.getByte();
00229 byte[] _message=buf.getString();
00230 byte[] lang=buf.getString();
00231 String message=null;
00232 try{ message=Util.getStringUTF8(_message); }
00233 catch
00234 {
00235 message=Util.getString(_message);
00236 }
00237 if(userinfo!=null)
00238 {
00239 userinfo.showMessage(message);
00240 }
00241 goto loop2;
00242 }
00243 else if(buf.buffer[5]==Session.SSH_MSG_USERAUTH_FAILURE)
00244 {
00245 buf.getInt(); buf.getByte(); buf.getByte();
00246 byte[] foo=buf.getString();
00247 int partial_success=buf.getByte();
00248
00249
00250 if(partial_success!=0)
00251 {
00252 throw new JSchPartialAuthException(Util.getString(foo));
00253 }
00254 break;
00255 }
00256
00257
00258 break;
00259 }
00260 }
00261 return false;
00262 }
00263 }
00264
00265 }