~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/NSch/NSch/UserAuthGSSAPIWithMIC.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2006-2010 ymnk, JCraft,Inc. All rights reserved.
 
3
 
 
4
Redistribution and use in source and binary forms, with or without
 
5
modification, are permitted provided that the following conditions are met:
 
6
 
 
7
  1. Redistributions of source code must retain the above copyright notice,
 
8
     this list of conditions and the following disclaimer.
 
9
 
 
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.
 
13
 
 
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.
 
16
 
 
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.
 
27
 
 
28
This code is based on jsch (http://www.jcraft.com/jsch).
 
29
All credit should go to the authors of jsch.
 
30
*/
 
31
 
 
32
using System;
 
33
using NSch;
 
34
using Sharpen;
 
35
 
 
36
namespace NSch
 
37
{
 
38
        public class UserAuthGSSAPIWithMIC : UserAuth
 
39
        {
 
40
                private const int SSH_MSG_USERAUTH_GSSAPI_RESPONSE = 60;
 
41
 
 
42
                private const int SSH_MSG_USERAUTH_GSSAPI_TOKEN = 61;
 
43
 
 
44
                private const int SSH_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE = 63;
 
45
 
 
46
                private const int SSH_MSG_USERAUTH_GSSAPI_ERROR = 64;
 
47
 
 
48
                private const int SSH_MSG_USERAUTH_GSSAPI_ERRTOK = 65;
 
49
 
 
50
                private const int SSH_MSG_USERAUTH_GSSAPI_MIC = 66;
 
51
 
 
52
                private static readonly byte[][] supported_oid = new byte[][] { new byte[] { unchecked(
 
53
                        (byte)unchecked((int)(0x6))), unchecked((byte)unchecked((int)(0x9))), unchecked(
 
54
                        (byte)unchecked((int)(0x2a))), unchecked((byte)unchecked((int)(0x86))), unchecked(
 
55
                        (byte)unchecked((int)(0x48))), unchecked((byte)unchecked((int)(0x86))), unchecked(
 
56
                        (byte)unchecked((int)(0xf7))), unchecked((byte)unchecked((int)(0x12))), unchecked(
 
57
                        (byte)unchecked((int)(0x1))), unchecked((byte)unchecked((int)(0x2))), unchecked(
 
58
                        (byte)unchecked((int)(0x2))) } };
 
59
 
 
60
                private static readonly string[] supported_method = new string[] { "gssapi-with-mic.krb5"
 
61
                         };
 
62
 
 
63
                // OID 1.2.840.113554.1.2.2 in DER
 
64
                /// <exception cref="System.Exception"></exception>
 
65
                public override bool Start(Session session)
 
66
                {
 
67
                        base.Start(session);
 
68
                        byte[] _username = Util.Str2byte(username);
 
69
                        packet.Reset();
 
70
                        // byte            SSH_MSG_USERAUTH_REQUEST(50)
 
71
                        // string          user name(in ISO-10646 UTF-8 encoding)
 
72
                        // string          service name(in US-ASCII)
 
73
                        // string          "gssapi"(US-ASCII)
 
74
                        // uint32          n, the number of OIDs client supports
 
75
                        // string[n]       mechanism OIDS
 
76
                        buf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_REQUEST));
 
77
                        buf.PutString(_username);
 
78
                        buf.PutString(Util.Str2byte("ssh-connection"));
 
79
                        buf.PutString(Util.Str2byte("gssapi-with-mic"));
 
80
                        buf.PutInt(supported_oid.Length);
 
81
                        for (int i = 0; i < supported_oid.Length; i++)
 
82
                        {
 
83
                                buf.PutString(supported_oid[i]);
 
84
                        }
 
85
                        session.Write(packet);
 
86
                        string method = null;
 
87
                        int command;
 
88
                        while (true)
 
89
                        {
 
90
                                buf = session.Read(buf);
 
91
                                command = buf.GetCommand() & unchecked((int)(0xff));
 
92
                                if (command == SSH_MSG_USERAUTH_FAILURE)
 
93
                                {
 
94
                                        return false;
 
95
                                }
 
96
                                if (command == SSH_MSG_USERAUTH_GSSAPI_RESPONSE)
 
97
                                {
 
98
                                        buf.GetInt();
 
99
                                        buf.GetByte();
 
100
                                        buf.GetByte();
 
101
                                        byte[] message = buf.GetString();
 
102
                                        for (int i_1 = 0; i_1 < supported_oid.Length; i_1++)
 
103
                                        {
 
104
                                                if (Util.Array_equals(message, supported_oid[i_1]))
 
105
                                                {
 
106
                                                        method = supported_method[i_1];
 
107
                                                        break;
 
108
                                                }
 
109
                                        }
 
110
                                        if (method == null)
 
111
                                        {
 
112
                                                return false;
 
113
                                        }
 
114
                                        break;
 
115
                                }
 
116
                                // success
 
117
                                if (command == SSH_MSG_USERAUTH_BANNER)
 
118
                                {
 
119
                                        buf.GetInt();
 
120
                                        buf.GetByte();
 
121
                                        buf.GetByte();
 
122
                                        byte[] _message = buf.GetString();
 
123
                                        byte[] lang = buf.GetString();
 
124
                                        string message = Util.Byte2str(_message);
 
125
                                        if (userinfo != null)
 
126
                                        {
 
127
                                                userinfo.ShowMessage(message);
 
128
                                        }
 
129
                                        continue;
 
130
                                }
 
131
                                return false;
 
132
                        }
 
133
                        NSch.GSSContext context = null;
 
134
                        try
 
135
                        {
 
136
                                Type c = Sharpen.Runtime.GetType(session.GetConfig(method));
 
137
                                context = (NSch.GSSContext)(System.Activator.CreateInstance(c));
 
138
                        }
 
139
                        catch (Exception)
 
140
                        {
 
141
                                return false;
 
142
                        }
 
143
                        try
 
144
                        {
 
145
                                context.Create(username, session.host);
 
146
                        }
 
147
                        catch (JSchException)
 
148
                        {
 
149
                                return false;
 
150
                        }
 
151
                        byte[] token = new byte[0];
 
152
                        while (!context.IsEstablished())
 
153
                        {
 
154
                                try
 
155
                                {
 
156
                                        token = context.Init(token, 0, token.Length);
 
157
                                }
 
158
                                catch (JSchException)
 
159
                                {
 
160
                                        // TODO
 
161
                                        // ERRTOK should be sent?
 
162
                                        // byte        SSH_MSG_USERAUTH_GSSAPI_ERRTOK
 
163
                                        // string      error token
 
164
                                        return false;
 
165
                                }
 
166
                                if (token != null)
 
167
                                {
 
168
                                        packet.Reset();
 
169
                                        buf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_GSSAPI_TOKEN));
 
170
                                        buf.PutString(token);
 
171
                                        session.Write(packet);
 
172
                                }
 
173
                                if (!context.IsEstablished())
 
174
                                {
 
175
                                        buf = session.Read(buf);
 
176
                                        command = buf.GetCommand() & unchecked((int)(0xff));
 
177
                                        if (command == SSH_MSG_USERAUTH_GSSAPI_ERROR)
 
178
                                        {
 
179
                                                // uint32    major_status
 
180
                                                // uint32    minor_status
 
181
                                                // string    message
 
182
                                                // string    language tag
 
183
                                                buf = session.Read(buf);
 
184
                                                command = buf.GetCommand() & unchecked((int)(0xff));
 
185
                                        }
 
186
                                        else
 
187
                                        {
 
188
                                                //return false;
 
189
                                                if (command == SSH_MSG_USERAUTH_GSSAPI_ERRTOK)
 
190
                                                {
 
191
                                                        // string error token
 
192
                                                        buf = session.Read(buf);
 
193
                                                        command = buf.GetCommand() & unchecked((int)(0xff));
 
194
                                                }
 
195
                                        }
 
196
                                        //return false;
 
197
                                        if (command == SSH_MSG_USERAUTH_FAILURE)
 
198
                                        {
 
199
                                                return false;
 
200
                                        }
 
201
                                        buf.GetInt();
 
202
                                        buf.GetByte();
 
203
                                        buf.GetByte();
 
204
                                        token = buf.GetString();
 
205
                                }
 
206
                        }
 
207
                        Buffer mbuf = new Buffer();
 
208
                        // string    session identifier
 
209
                        // byte      SSH_MSG_USERAUTH_REQUEST
 
210
                        // string    user name
 
211
                        // string    service
 
212
                        // string    "gssapi-with-mic"
 
213
                        mbuf.PutString(session.GetSessionId());
 
214
                        mbuf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_REQUEST));
 
215
                        mbuf.PutString(_username);
 
216
                        mbuf.PutString(Util.Str2byte("ssh-connection"));
 
217
                        mbuf.PutString(Util.Str2byte("gssapi-with-mic"));
 
218
                        byte[] mic = context.GetMIC(mbuf.buffer, 0, mbuf.GetLength());
 
219
                        if (mic == null)
 
220
                        {
 
221
                                return false;
 
222
                        }
 
223
                        packet.Reset();
 
224
                        buf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_GSSAPI_MIC));
 
225
                        buf.PutString(mic);
 
226
                        session.Write(packet);
 
227
                        context.Dispose();
 
228
                        buf = session.Read(buf);
 
229
                        command = buf.GetCommand() & unchecked((int)(0xff));
 
230
                        if (command == SSH_MSG_USERAUTH_SUCCESS)
 
231
                        {
 
232
                                return true;
 
233
                        }
 
234
                        else
 
235
                        {
 
236
                                if (command == SSH_MSG_USERAUTH_FAILURE)
 
237
                                {
 
238
                                        buf.GetInt();
 
239
                                        buf.GetByte();
 
240
                                        buf.GetByte();
 
241
                                        byte[] foo = buf.GetString();
 
242
                                        int partial_success = buf.GetByte();
 
243
                                        //System.err.println(new String(foo)+
 
244
                                        //               " partial_success:"+(partial_success!=0));
 
245
                                        if (partial_success != 0)
 
246
                                        {
 
247
                                                throw new JSchPartialAuthException(Util.Byte2str(foo));
 
248
                                        }
 
249
                                }
 
250
                        }
 
251
                        return false;
 
252
                }
 
253
        }
 
254
}