/* void dump(byte[] foo){ for(int i=0; i<foo.length; i++){ if((foo[i]&0xf0)==0)System.out.print("0"); System.out.print(Integer.toHexString(foo[i]&0xff)); if(i%16==15){System.out.println(""); continue;} if(i%2==1)System.out.print(" "); } } */ internal static SharpSSH.SharpSsh.java.String[] guess(byte[]I_S, byte[]I_C) { //System.out.println("guess: "); SharpSSH.SharpSsh.java.String[] guess=new SharpSSH.SharpSsh.java.String[PROPOSAL_MAX]; Buffer sb=new Buffer(I_S); sb.setOffSet(17); Buffer cb=new Buffer(I_C); cb.setOffSet(17); for(int i=0; i<PROPOSAL_MAX; i++) { byte[] sp=sb.getString(); // server proposal byte[] cp=cb.getString(); // client proposal //System.out.println("server-proposal: |"+new String(sp)+"|"); //System.out.println("client-proposal: |"+new String(cp)+"|"); int j=0; int k=0; //System.out.println(new String(cp)); //loop(using BREAK instead): while(j<cp.Length) { while(j<cp.Length && cp[j]!=',')j++; if(k==j) return null; String algorithm=Util.getString(cp, k, j-k); //System.out.println("algorithm: "+algorithm); int l=0; int m=0; while(l<sp.Length) { while(l<sp.Length && sp[l]!=',')l++; if(m==l) return null; //System.out.println(" "+new String(sp, m, l-m)); if(algorithm.Equals(Util.getString(sp, m, l-m))) { guess[i]=algorithm; //System.out.println(" "+algorithm); goto BREAK; } l++; m=l; } j++; k=j; } BREAK: if(j==0) { guess[i]=""; } else if(guess[i]==null) { //System.out.println(" fail"); return null; } } // for(int i=0; i<PROPOSAL_MAX; i++){ // System.out.println("guess: ["+guess[i]+"]"); // } return guess; }
public static KeyPair load(JSch jsch, String prvkey, String pubkey) { byte[] iv=new byte[8]; // 8 bool encrypted=true; byte[] data=null; byte[] publickeyblob=null; int type=ERROR; int vendor=VENDOR_OPENSSH; try { //File file=new File(prvkey); FileStream fis=File.OpenRead(prvkey); byte[] buf=new byte[(int)(fis.Length)]; int len=fis.Read(buf, 0, buf.Length); fis.Close(); int i=0; while(i<len) { if(buf[i]=='B'&& buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I') { i+=6; if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSA; } else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; } else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H') { // FSecure type=UNKNOWN; vendor=VENDOR_FSECURE; } else { //System.outs.println("invalid format: "+identity); throw new JSchException("invaid privatekey: "+prvkey); } i+=3; continue; } if(buf[i]=='C'&& buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==',') { i+=4; for(int ii=0; ii<iv.Length; ii++) { iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+(a2b(buf[i++])&0xf)); } continue; } if(buf[i]==0x0d && i+1<buf.Length && buf[i+1]==0x0a) { i++; continue; } if(buf[i]==0x0a && i+1<buf.Length) { if(buf[i+1]==0x0a){ i+=2; break; } if(buf[i+1]==0x0d && i+2<buf.Length && buf[i+2]==0x0a) { i+=3; break; } bool inheader=false; for(int j=i+1; j<buf.Length; j++) { if(buf[j]==0x0a) break; //if(buf[j]==0x0d) break; if(buf[j]==':'){inheader=true; break;} } if(!inheader) { i++; encrypted=false; // no passphrase break; } } i++; } if(type==ERROR) { throw new JSchException("invaid privatekey: "+prvkey); } int start=i; while(i<len) { if(buf[i]==0x0a) { bool xd=(buf[i-1]==0x0d); Array.Copy(buf, i+1, buf, i-(xd ? 1 : 0), len-i-1-(xd ? 1 : 0) ); if(xd)len--; len--; continue; } if(buf[i]=='-'){ break; } i++; } data=Util.fromBase64(buf, start, i-start); if(data.Length>4 && // FSecure data[0]==(byte)0x3f && data[1]==(byte)0x6f && data[2]==(byte)0xf9 && data[3]==(byte)0xeb) { Buffer _buf=new Buffer(data); _buf.getInt(); // 0x3f6ff9be _buf.getInt(); byte[]_type=_buf.getString(); //System.outs.println("type: "+new String(_type)); byte[] _cipher=_buf.getString(); String cipher=Util.getString(_cipher); //System.outs.println("cipher: "+cipher); if(cipher.Equals("3des-cbc")) { _buf.getInt(); byte[] foo=new byte[data.Length-_buf.getOffSet()]; _buf.getByte(foo); data=foo; encrypted=true; throw new JSchException("unknown privatekey format: "+prvkey); } else if(cipher.Equals("none")) { _buf.getInt(); _buf.getInt(); encrypted=false; byte[] foo=new byte[data.Length-_buf.getOffSet()]; _buf.getByte(foo); data=foo; } } if(pubkey!=null) { try { //file=new File(pubkey); fis=File.OpenRead(pubkey); buf=new byte[(int)(fis.Length)]; len=fis.Read(buf, 0, buf.Length); fis.Close(); if(buf.Length>4 && // FSecure's public key buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-') { bool valid=true; i=0; do{i++;}while(buf.Length>i && buf[i]!=0x0a); if(buf.Length<=i) {valid=false;} while(valid) { if(buf[i]==0x0a) { bool inheader=false; for(int j=i+1; j<buf.Length; j++) { if(buf[j]==0x0a) break; if(buf[j]==':'){inheader=true; break;} } if(!inheader) { i++; break; } } i++; } if(buf.Length<=i){valid=false;} start=i; while(valid && i<len) { if(buf[i]==0x0a) { Array.Copy(buf, i+1, buf, i, len-i-1); len--; continue; } if(buf[i]=='-'){ break; } i++; } if(valid) { publickeyblob=Util.fromBase64(buf, start, i-start); if(type==UNKNOWN) { if(publickeyblob[8]=='d'){ type=DSA; } else if(publickeyblob[8]=='r'){ type=RSA; } } } } else { if(buf[0]=='s'&& buf[1]=='s'&& buf[2]=='h' && buf[3]=='-') { i=0; while(i<len){ if(buf[i]==' ')break; i++;} i++; if(i<len) { start=i; while(i<len){ if(buf[i]==' ')break; i++;} publickeyblob=Util.fromBase64(buf, start, i-start); } } } } catch//(Exception ee) { } } } catch(Exception e) { if(e is JSchException) throw (JSchException)e; throw new JSchException(e.ToString()); } KeyPair kpair=null; if(type==DSA){ kpair=new KeyPairDSA(jsch); } else if(type==RSA){ kpair=new KeyPairRSA(jsch); } if(kpair!=null) { kpair.encrypted=encrypted; kpair.publickeyblob=publickeyblob; kpair.vendor=vendor; if(encrypted) { kpair.iv=iv; kpair.data=data; } else { if(kpair.parse(data)) { return kpair; } else { throw new JSchException("invaid privatekey: "+prvkey); } } } return kpair; }
public override bool next(Buffer _buf) { int i,j; bool result = false; switch(state) { case SSH_MSG_KEXDH_REPLY: // The server responds with: // byte SSH_MSG_KEXDH_REPLY(31) // string server public host key and certificates (K_S) // mpint f // string signature of H j=_buf.getInt(); j=_buf.getByte(); j=_buf.getByte(); if(j!=31) { Console.WriteLine("type: must be 31 "+j); result = false; break; } K_S=_buf.getString(); // K_S is server_key_blob, which includes .... // string ssh-dss // impint p of dsa // impint q of dsa // impint g of dsa // impint pub_key of dsa //System.out.print("K_S: "); //dump(K_S, 0, K_S.length); byte[] f=_buf.getMPInt(); byte[] sig_of_H=_buf.getString(); /* for(int ii=0; ii<sig_of_H.length;ii++){ System.out.print(Integer.toHexString(sig_of_H[ii]&0xff)); System.out.print(": "); } Console.WriteLine(""); */ dh.setF(f); K=dh.getK(); //The hash H is computed as the HASH hash of the concatenation of the //following: // string V_C, the client's version string (CR and NL excluded) // string V_S, the server's version string (CR and NL excluded) // string I_C, the payload of the client's SSH_MSG_KEXINIT // string I_S, the payload of the server's SSH_MSG_KEXINIT // string K_S, the host key // mpint e, exchange value sent by the client // mpint f, exchange value sent by the server // mpint K, the shared secret // This value is called the exchange hash, and it is used to authenti- // cate the key exchange. buf.reset(); buf.putString(V_C); buf.putString(V_S); buf.putString(I_C); buf.putString(I_S); buf.putString(K_S); buf.putMPInt(e); buf.putMPInt(f); buf.putMPInt(K); byte[] foo=new byte[buf.getLength()]; buf.getByte(foo); sha.update(foo, 0, foo.Length); H=sha.digest(); //System.out.print("H -> "); //dump(H, 0, H.length); i=0; j=0; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); String alg=Util.getString(K_S, i, j); i+=j; result=false; if(alg.Equals("ssh-rsa")) { byte[] tmp; byte[] ee; byte[] n; type=RSA; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; ee=tmp; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; n=tmp; // SignatureRSA sig=new SignatureRSA(); // sig.init(); SignatureRSA sig=null; try { Type t=Type.GetType(session.getConfig("signature.rsa")); sig=(SignatureRSA)(Activator.CreateInstance(t)); sig.init(); } catch(Exception eee) { Console.WriteLine(eee); } sig.setPubKey(ee, n); sig.update(H); result=sig.verify(sig_of_H); //MainClass.dump(ee, n, sig_of_H, H); } else if(alg.Equals("ssh-dss")) { byte[] q=null; byte[] tmp; byte[] p; byte[] g; type=DSS; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; p=tmp; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; q=tmp; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; g=tmp; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; f=tmp; // SignatureDSA sig=new SignatureDSA(); // sig.init(); SignatureDSA sig=null; try { Type t=Type.GetType(session.getConfig("signature.dss")); sig=(SignatureDSA)(Activator.CreateInstance(t)); sig.init(); } catch(Exception ee) { Console.WriteLine(ee); } sig.setPubKey(f, p, q, g); sig.update(H); result=sig.verify(sig_of_H); } else { Console.WriteLine("unknow alg"); } state=STATE_END; break; } return result; }
public override bool next(Buffer _buf) { int i,j; bool result=false; switch(state) { case SSH_MSG_KEX_DH_GEX_GROUP: // byte SSH_MSG_KEX_DH_GEX_GROUP(31) // mpint p, safe prime // mpint g, generator for subgroup in GF (p) _buf.getInt(); _buf.getByte(); j=_buf.getByte(); if(j!=31) { Console.WriteLine("type: must be 31 "+j); result = false; } p=_buf.getMPInt(); g=_buf.getMPInt(); /* for(int iii=0; iii<p.length; iii++){ System.out.println("0x"+Integer.toHexString(p[iii]&0xff)+","); } System.out.println(""); for(int iii=0; iii<g.length; iii++){ System.out.println("0x"+Integer.toHexString(g[iii]&0xff)+","); } */ dh.setP(p); dh.setG(g); // The client responds with: // byte SSH_MSG_KEX_DH_GEX_INIT(32) // mpint e <- g^x mod p // x is a random number (1 < x < (p-1)/2) e=dh.getE(); packet.reset(); buf.putByte((byte)0x20); buf.putMPInt(e); session.write(packet); state=SSH_MSG_KEX_DH_GEX_REPLY; result = true; break; case SSH_MSG_KEX_DH_GEX_REPLY: // The server responds with: // byte SSH_MSG_KEX_DH_GEX_REPLY(33) // string server public host key and certificates (K_S) // mpint f // string signature of H j=_buf.getInt(); j=_buf.getByte(); j=_buf.getByte(); if(j!=33) { Console.WriteLine("type: must be 33 "+j); result = false; } K_S=_buf.getString(); // K_S is server_key_blob, which includes .... // string ssh-dss // impint p of dsa // impint q of dsa // impint g of dsa // impint pub_key of dsa //System.out.print("K_S: "); dump(K_S, 0, K_S.length); byte[] f=_buf.getMPInt(); byte[] sig_of_H=_buf.getString(); dh.setF(f); K=dh.getK(); //The hash H is computed as the HASH hash of the concatenation of the //following: // string V_C, the client's version string (CR and NL excluded) // string V_S, the server's version string (CR and NL excluded) // string I_C, the payload of the client's SSH_MSG_KEXINIT // string I_S, the payload of the server's SSH_MSG_KEXINIT // string K_S, the host key // uint32 min, minimal size in bits of an acceptable group // uint32 n, preferred size in bits of the group the server should send // uint32 max, maximal size in bits of an acceptable group // mpint p, safe prime // mpint g, generator for subgroup // mpint e, exchange value sent by the client // mpint f, exchange value sent by the server // mpint K, the shared secret // This value is called the exchange hash, and it is used to authenti- // cate the key exchange. buf.reset(); buf.putString(V_C); buf.putString(V_S); buf.putString(I_C); buf.putString(I_S); buf.putString(K_S); buf.putInt(min); buf.putInt(preferred); buf.putInt(max); buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f); buf.putMPInt(K); byte[] foo=new byte[buf.getLength()]; buf.getByte(foo); sha.update(foo, 0, foo.Length); H=sha.digest(); // System.out.print("H -> "); dump(H, 0, H.length); i=0; j=0; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); String alg=Util.getString(K_S, i, j); i+=j; if(alg.Equals("ssh-rsa")) { byte[] tmp; byte[] ee; byte[] n; type=RSA; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; ee=tmp; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; n=tmp; // SignatureRSA sig=new SignatureRSA(); // sig.init(); SignatureRSA sig=null; try { Type t=Type.GetType(session.getConfig("signature.rsa")); sig=(SignatureRSA)(Activator.CreateInstance(t)); sig.init(); } catch(Exception eee) { Console.WriteLine(eee); } sig.setPubKey(ee, n); sig.update(H); result=sig.verify(sig_of_H); } else if(alg.Equals("ssh-dss")) { byte[] q=null; byte[] tmp; type=DSS; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; p=tmp; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; q=tmp; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; g=tmp; j=(int)((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i+=j; f=tmp; // SignatureDSA sig=new SignatureDSA(); // sig.init(); SignatureDSA sig=null; try { Type t=Type.GetType(session.getConfig("signature.dss")); sig=(SignatureDSA)(Activator.CreateInstance(t)); sig.init(); } catch(Exception ee) { Console.WriteLine(ee); } sig.setPubKey(f, p, q, g); sig.update(H); result=sig.verify(sig_of_H); } else { Console.WriteLine("unknow alg"); } state=STATE_END; break; } return result; }
internal static SftpATTRS getATTR(Buffer buf) { SftpATTRS attr=new SftpATTRS(); attr.flags=buf.getInt(); if((attr.flags&SSH_FILEXFER_ATTR_SIZE)!=0){ attr.size=buf.getLong(); } if((attr.flags&SSH_FILEXFER_ATTR_UIDGID)!=0) { attr.uid=buf.getInt(); attr.gid=buf.getInt(); } if((attr.flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0) { attr.permissions=buf.getInt(); } if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0) { attr.atime=buf.getInt(); } if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0) { attr.mtime=buf.getInt(); } if((attr.flags&SSH_FILEXFER_ATTR_EXTENDED)!=0) { int count=buf.getInt(); if(count>0) { attr.extended=new String[count*2]; for(int i=0; i<count; i++) { attr.extended[i*2]=Util.getString(buf.getString()); attr.extended[i*2+1]=Util.getString(buf.getString()); } } } return attr; }
internal IdentityFile(String identity, JSch jsch) { this.identity=identity; this.jsch=jsch; try { Type c=Type.GetType(jsch.getConfig("3des-cbc")); cipher=(Cipher)Activator.CreateInstance(c); key=new byte[cipher.getBlockSize()]; // 24 iv=new byte[cipher.getIVSize()]; // 8 c=Type.GetType(jsch.getConfig("md5")); hash=(HASH)(Activator.CreateInstance(c)); hash.init(); FileInfo file=new FileInfo(identity); FileStream fis = File.OpenRead(identity); byte[] buf=new byte[(int)(file.Length)]; int len=fis.Read(buf, 0, buf.Length); fis.Close(); int i=0; while(i<len) { if(buf[i]=='B'&& buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I') { i+=6; if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSS; } else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; } else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H') { // FSecure type=UNKNOWN; keytype=FSECURE; } else { //System.out.println("invalid format: "+identity); throw new JSchException("invaid privatekey: "+identity); } i+=3; continue; } if(buf[i]=='C'&& buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==',') { i+=4; for(int ii=0; ii<iv.Length; ii++) { iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+ (a2b(buf[i++])&0xf)); } continue; } if(buf[i]==0x0d && i+1<buf.Length && buf[i+1]==0x0a) { i++; continue; } if(buf[i]==0x0a && i+1<buf.Length) { if(buf[i+1]==0x0a){ i+=2; break; } if(buf[i+1]==0x0d && i+2<buf.Length && buf[i+2]==0x0a) { i+=3; break; } bool inheader=false; for(int j=i+1; j<buf.Length; j++) { if(buf[j]==0x0a) break; //if(buf[j]==0x0d) break; if(buf[j]==':'){inheader=true; break;} } if(!inheader) { i++; encrypted=false; // no passphrase break; } } i++; } if(type==ERROR) { throw new JSchException("invaid privatekey: "+identity); } int start=i; while(i<len) { if(buf[i]==0x0a) { bool xd=(buf[i-1]==0x0d); Array.Copy(buf, i+1, buf, i-(xd ? 1 : 0), len-i-1-(xd ? 1 : 0) ); if(xd)len--; len--; continue; } if(buf[i]=='-'){ break; } i++; } encoded_data=Util.fromBase64(buf, start, i-start); if(encoded_data.Length>4 && // FSecure encoded_data[0]==(byte)0x3f && encoded_data[1]==(byte)0x6f && encoded_data[2]==(byte)0xf9 && encoded_data[3]==(byte)0xeb) { Buffer _buf=new Buffer(encoded_data); _buf.getInt(); // 0x3f6ff9be _buf.getInt(); byte[]_type=_buf.getString(); //System.out.println("type: "+new String(_type)); byte[] _cipher=_buf.getString(); String s_cipher=System.Text.Encoding.Default.GetString(_cipher); //System.out.println("cipher: "+cipher); if(s_cipher.Equals("3des-cbc")) { _buf.getInt(); byte[] foo=new byte[encoded_data.Length-_buf.getOffSet()]; _buf.getByte(foo); encoded_data=foo; encrypted=true; throw new JSchException("unknown privatekey format: "+identity); } else if(s_cipher.Equals("none")) { _buf.getInt(); //_buf.getInt(); encrypted=false; byte[] foo=new byte[encoded_data.Length-_buf.getOffSet()]; _buf.getByte(foo); encoded_data=foo; } } try { file=new FileInfo(identity+".pub"); fis=File.OpenRead(identity+".pub"); buf=new byte[(int)(file.Length)]; len=fis.Read(buf, 0, buf.Length); fis.Close(); } catch { return; } if(buf.Length>4 && // FSecure's public key buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-') { i=0; do{i++;}while(buf.Length>i && buf[i]!=0x0a); if(buf.Length<=i) return; while(true) { if(buf[i]==0x0a) { bool inheader=false; for(int j=i+1; j<buf.Length; j++) { if(buf[j]==0x0a) break; if(buf[j]==':'){inheader=true; break;} } if(!inheader) { i++; break; } } i++; } if(buf.Length<=i) return; start=i; while(i<len) { if(buf[i]==0x0a) { Array.Copy(buf, i+1, buf, i, len-i-1); len--; continue; } if(buf[i]=='-'){ break; } i++; } publickeyblob=Util.fromBase64(buf, start, i-start); if(type==UNKNOWN) { if(publickeyblob[8]=='d') { type=DSS; } else if(publickeyblob[8]=='r') { type=RSA; } } } else { if(buf[0]!='s'|| buf[1]!='s'|| buf[2]!='h'|| buf[3]!='-') return; i=0; while(i<len){ if(buf[i]==' ')break; i++;} i++; if(i>=len) return; start=i; while(i<len){ if(buf[i]==' ')break; i++;} publickeyblob=Util.fromBase64(buf, start, i-start); } } catch(Exception e) { Console.WriteLine("Identity: "+e); if(e is JSchException) throw (JSchException)e; throw new JSchException(e.ToString()); } }
public void run() { thread=this; byte[] foo; Buffer buf=new Buffer(); Packet packet=new Packet(buf); int i=0; Channel channel; int[] start=new int[1]; int[] length=new int[1]; KeyExchange kex=null; try { while(_isConnected && thread!=null) { buf=read(buf); int msgType=buf.buffer[5]&0xff; // if(msgType!=94) //System.Console.WriteLine("read: 94 ? "+msgType); if(kex!=null && kex.getState()==msgType) { bool result=kex.next(buf); if(!result) { throw new JSchException("verify: "+result); } continue; } switch(msgType) { case SSH_MSG_KEXINIT: //System.Console.WriteLine("KEXINIT"); kex=receive_kexinit(buf); break; case SSH_MSG_NEWKEYS: //System.Console.WriteLine("NEWKEYS"); send_newkeys(); receive_newkeys(buf, kex); kex=null; break; case SSH_MSG_CHANNEL_DATA: buf.getInt(); buf.getByte(); buf.getByte(); i=buf.getInt(); channel=Channel.getChannel(i, this); foo=buf.getString(start, length); if(channel==null) { break; } try { channel.write(foo, start[0], length[0]); } catch(Exception e) { //System.Console.WriteLine(e); try{channel.disconnect();} catch(Exception ee){} break; } int len=length[0]; channel.setLocalWindowSize(channel.lwsize-len); if(channel.lwsize<channel.lwsize_max/2) { packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST); buf.putInt(channel.getRecipient()); buf.putInt(channel.lwsize_max-channel.lwsize); write(packet); channel.setLocalWindowSize(channel.lwsize_max); } break; case SSH_MSG_CHANNEL_EXTENDED_DATA: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); buf.getInt(); // data_type_code == 1 foo=buf.getString(start, length); //System.Console.WriteLine("stderr: "+new String(foo,start[0],length[0])); if(channel==null) { break; } //channel.write(foo, start[0], length[0]); channel.write_ext(foo, start[0], length[0]); len=length[0]; channel.setLocalWindowSize(channel.lwsize-len); if(channel.lwsize<channel.lwsize_max/2) { packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST); buf.putInt(channel.getRecipient()); buf.putInt(channel.lwsize_max-channel.lwsize); write(packet); channel.setLocalWindowSize(channel.lwsize_max); } break; case SSH_MSG_CHANNEL_WINDOW_ADJUST: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.addRemoteWindowSize(buf.getInt()); break; case SSH_MSG_CHANNEL_EOF: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel!=null) { //channel._eof_remote=true; //channel.eof(); channel.eof_remote(); } /* packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_EOF); buf.putInt(channel.getRecipient()); write(packet); */ break; case SSH_MSG_CHANNEL_CLOSE: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel!=null) { // channel.close(); channel.disconnect(); } /* if(Channel.pool.size()==0){ thread=null; } */ break; case SSH_MSG_CHANNEL_OPEN_CONFIRMATION: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { //break; } channel.setRecipient(buf.getInt()); channel.setRemoteWindowSize(buf.getInt()); channel.setRemotePacketSize(buf.getInt()); break; case SSH_MSG_CHANNEL_OPEN_FAILURE: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { //break; } int reason_code=buf.getInt(); //foo=buf.getString(); // additional textual information //foo=buf.getString(); // language tag channel.exitstatus=reason_code; channel._close=true; channel._eof_remote=true; channel.setRecipient(0); break; case SSH_MSG_CHANNEL_REQUEST: buf.getInt(); buf.getShort(); i=buf.getInt(); foo=buf.getString(); bool reply=(buf.getByte()!=0); channel=Channel.getChannel(i, this); if(channel!=null) { byte reply_type=(byte)SSH_MSG_CHANNEL_FAILURE; if((new String(foo)).equals("exit-status")) { i=buf.getInt(); // exit-status channel.setExitStatus(i); // System.Console.WriteLine("exit-stauts: "+i); // channel.close(); reply_type=(byte)SSH_MSG_CHANNEL_SUCCESS; } if(reply) { packet.reset(); buf.putByte(reply_type); buf.putInt(channel.getRecipient()); write(packet); } } else { } break; case SSH_MSG_CHANNEL_OPEN: buf.getInt(); buf.getShort(); foo=buf.getString(); String ctyp=new String(foo); //System.Console.WriteLine("type="+ctyp); if(!new String("forwarded-tcpip").equals(ctyp) && !(new String("x11").equals(ctyp) && x11_forwarding)) { System.Console.WriteLine("Session.run: CHANNEL OPEN "+ctyp); throw new IOException("Session.run: CHANNEL OPEN "+ctyp); } else { channel=Channel.getChannel(ctyp); addChannel(channel); channel.getData(buf); channel.init(); packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION); buf.putInt(channel.getRecipient()); buf.putInt(channel.id); buf.putInt(channel.lwsize); buf.putInt(channel.lmpsize); write(packet); Thread tmp=new Thread(channel); tmp.setName("Channel "+ctyp+" "+host); tmp.start(); break; } case SSH_MSG_CHANNEL_SUCCESS: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.reply=1; break; case SSH_MSG_CHANNEL_FAILURE: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); if(channel==null) { break; } channel.reply=0; break; case SSH_MSG_GLOBAL_REQUEST: buf.getInt(); buf.getShort(); foo=buf.getString(); // request name reply=(buf.getByte()!=0); if(reply) { packet.reset(); buf.putByte((byte)SSH_MSG_REQUEST_FAILURE); write(packet); } break; case SSH_MSG_REQUEST_FAILURE: case SSH_MSG_REQUEST_SUCCESS: Thread t=grr.getThread(); if(t!=null) { grr.setReply(msgType==SSH_MSG_REQUEST_SUCCESS? 1 : 0); t.interrupt(); } break; default: System.Console.WriteLine("Session.run: unsupported type "+msgType); throw new IOException("Unknown SSH message type "+msgType); } } } catch(Exception e) { //System.Console.WriteLine("# Session.run"); //e.printStackTrace(); } try { disconnect(); } catch(NullReferenceException e) { //System.Console.WriteLine("@1"); //e.printStackTrace(); } catch(Exception e) { //System.Console.WriteLine("@2"); //e.printStackTrace(); } _isConnected=false; }
public Buffer read(Buffer buf) { int j=0; while(true) { buf.reset(); io.getByte(buf.buffer, buf.index, cipher_size); buf.index+=cipher_size; if(s2ccipher!=null) { s2ccipher.update(buf.buffer, 0, cipher_size, buf.buffer, 0); } // j=((buf.buffer[0]<<24)&0xff000000)| // ((buf.buffer[1]<<16)&0x00ff0000)| // ((buf.buffer[2]<< 8)&0x0000ff00)| // ((buf.buffer[3] )&0x000000ff); j=Util.ToInt32( buf.buffer, 0 ); j=j-4-cipher_size+8; if(j<0 || (buf.index+j)>buf.buffer.Length) { throw new IOException("invalid data"); } if(j>0) { io.getByte(buf.buffer, buf.index, j); buf.index+=(j); if(s2ccipher!=null) { s2ccipher.update(buf.buffer, cipher_size, j, buf.buffer, cipher_size); } } if(s2cmac!=null) { s2cmac.update(seqi); s2cmac.update(buf.buffer, 0, buf.index); byte[] result=s2cmac.doFinal(); io.getByte(mac_buf, 0, mac_buf.Length); if(!Arrays.equals(result, mac_buf)) { throw new IOException("MAC Error"); } } seqi++; if(inflater!=null) { //inflater.uncompress(buf); int pad=buf.buffer[4]; uncompress_len[0]=buf.index-5-pad; byte[] foo=inflater.uncompress(buf.buffer, 5, uncompress_len); if(foo!=null) { buf.buffer=foo; buf.index=5+uncompress_len[0]; } else { System.Console.Error.WriteLine("fail in inflater"); break; } } int type=buf.buffer[5]&0xff; //System.Console.WriteLine("read: "+type); if(type==SSH_MSG_DISCONNECT) { buf.rewind(); buf.getInt();buf.getShort(); int reason_code=buf.getInt(); byte[] description=buf.getString(); byte[] language_tag=buf.getString(); /* System.Console.Error.WriteLine("SSH_MSG_DISCONNECT:"+ " "+reason_code+ " "+new String(description)+ " "+new String(language_tag)); */ throw new JSchException("SSH_MSG_DISCONNECT:"+ " "+reason_code+ " "+new String(description)+ " "+new String(language_tag)); //break; } else if(type==SSH_MSG_IGNORE) { } else if(type==SSH_MSG_DEBUG) { buf.rewind(); buf.getInt();buf.getShort(); /* byte always_display=(byte)buf.getByte(); byte[] message=buf.getString(); byte[] language_tag=buf.getString(); System.Console.Error.WriteLine("SSH_MSG_DEBUG:"+ " "+new String(message)+ " "+new String(language_tag)); */ } else if(type==SSH_MSG_CHANNEL_WINDOW_ADJUST) { buf.rewind(); buf.getInt();buf.getShort(); Channel c=Channel.getChannel(buf.getInt(), this); if(c==null) { } else { c.addRemoteWindowSize(buf.getInt()); } } else { break; } } buf.rewind(); return buf; }