2
Copyright (c) 2006-2010 ymnk, JCraft,Inc. All rights reserved.
4
Redistribution and use in source and binary forms, with or without
5
modification, are permitted provided that the following conditions are met:
7
1. Redistributions of source code must retain the above copyright notice,
8
this list of conditions and the following disclaimer.
10
2. Redistributions in binary form must reproduce the above copyright
11
notice, this list of conditions and the following disclaimer in
12
the documentation and/or other materials provided with the distribution.
14
3. The names of the authors may not be used to endorse or promote products
15
derived from this software without specific prior written permission.
17
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
18
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
20
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
21
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
This code is based on jsch (http://www.jcraft.com/jsch).
29
All credit should go to the authors of jsch.
33
using System.Collections;
40
internal class ChannelAgentForwarding : Channel
42
private const int LOCAL_WINDOW_SIZE_MAX = unchecked((int)(0x20000));
44
private const int LOCAL_MAXIMUM_PACKET_SIZE = unchecked((int)(0x4000));
46
private readonly int SSH2_AGENTC_REQUEST_IDENTITIES = 11;
48
private readonly int SSH2_AGENT_IDENTITIES_ANSWER = 12;
50
private readonly int SSH2_AGENTC_SIGN_REQUEST = 13;
52
private readonly int SSH2_AGENT_SIGN_RESPONSE = 14;
54
private readonly int SSH2_AGENTC_ADD_IDENTITY = 17;
56
private readonly int SSH2_AGENTC_REMOVE_IDENTITY = 18;
58
private readonly int SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19;
60
private readonly int SSH2_AGENT_FAILURE = 30;
62
internal bool init = true;
64
private Buffer rbuf = null;
66
private Buffer wbuf = null;
68
private Packet packet = null;
70
private Buffer mbuf = null;
72
public ChannelAgentForwarding() : base()
74
SetLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
75
SetLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
76
SetLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
77
type = Util.Str2byte("auth-agent@openssh.com");
80
//wbuf=new Buffer(rmpsize);
81
//packet=new Packet(wbuf);
86
public override void Run()
90
SendOpenConfirmation();
99
/// <exception cref="System.IO.IOException"></exception>
100
internal override void Write(byte[] foo, int s, int l)
104
wbuf = new Buffer(rmpsize);
105
packet = new Packet(wbuf);
108
if (rbuf.buffer.Length < rbuf.index + l)
110
byte[] newbuf = new byte[rbuf.s + l];
111
System.Array.Copy(rbuf.buffer, 0, newbuf, 0, rbuf.buffer.Length);
112
rbuf.buffer = newbuf;
114
rbuf.PutByte(foo, s, l);
115
int mlen = rbuf.GetInt();
116
if (mlen > rbuf.GetLength())
121
int typ = rbuf.GetByte();
122
Session _session = null;
125
_session = GetSession();
127
catch (JSchException e)
129
throw new IOException(e.ToString());
131
ArrayList identities = _session.jsch.identities;
132
UserInfo userinfo = _session.GetUserInfo();
133
if (typ == SSH2_AGENTC_REQUEST_IDENTITIES)
136
mbuf.PutByte(unchecked((byte)SSH2_AGENT_IDENTITIES_ANSWER));
140
for (int i = 0; i < identities.Count; i++)
142
Identity identity = (Identity)(identities[i]);
143
if (identity.GetPublicKeyBlob() != null)
149
for (int i_1 = 0; i_1 < identities.Count; i_1++)
151
Identity identity = (Identity)(identities[i_1]);
152
byte[] pubkeyblob = identity.GetPublicKeyBlob();
153
if (pubkeyblob == null)
157
mbuf.PutString(pubkeyblob);
158
mbuf.PutString(Util.empty);
161
byte[] bar = new byte[mbuf.GetLength()];
167
if (typ == SSH2_AGENTC_SIGN_REQUEST)
169
byte[] blob = rbuf.GetString();
170
byte[] data = rbuf.GetString();
171
int flags = rbuf.GetInt();
172
// if((flags & 1)!=0){ //SSH_AGENT_OLD_SIGNATURE // old OpenSSH 2.0, 2.1
173
// datafellows = SSH_BUG_SIGBLOB;
175
Identity identity = null;
178
for (int i = 0; i < identities.Count; i++)
180
Identity _identity = (Identity)(identities[i]);
181
if (_identity.GetPublicKeyBlob() == null)
185
if (!Util.Array_equals(blob, _identity.GetPublicKeyBlob()))
189
if (_identity.IsEncrypted())
191
if (userinfo == null)
195
while (_identity.IsEncrypted())
197
if (!userinfo.PromptPassphrase("Passphrase for " + _identity.GetName()))
201
string _passphrase = userinfo.GetPassphrase();
202
if (_passphrase == null)
206
byte[] passphrase = Util.Str2byte(_passphrase);
209
if (_identity.SetPassphrase(passphrase))
214
catch (JSchException)
220
if (!_identity.IsEncrypted())
222
identity = _identity;
227
byte[] signature = null;
228
if (identity != null)
230
signature = identity.GetSignature(data);
233
if (signature == null)
235
mbuf.PutByte(unchecked((byte)SSH2_AGENT_FAILURE));
239
mbuf.PutByte(unchecked((byte)SSH2_AGENT_SIGN_RESPONSE));
240
mbuf.PutString(signature);
242
byte[] bar = new byte[mbuf.GetLength()];
249
private void Send(byte[] message)
252
wbuf.PutByte(unchecked((byte)Session.SSH_MSG_CHANNEL_DATA));
253
wbuf.PutInt(recipient);
254
wbuf.PutInt(4 + message.Length);
255
wbuf.PutString(message);
258
GetSession().Write(packet, this, 4 + message.Length);