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

« back to all changes in this revision

Viewing changes to contrib/NSch/NSch/KnownHosts.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 System.Collections;
 
34
using System.IO;
 
35
using System.Text;
 
36
using NSch;
 
37
using Sharpen;
 
38
 
 
39
namespace NSch
 
40
{
 
41
        public class KnownHosts : HostKeyRepository
 
42
        {
 
43
                private static readonly string _known_hosts = "known_hosts";
 
44
 
 
45
                private JSch jsch = null;
 
46
 
 
47
                private string known_hosts = null;
 
48
 
 
49
                private ArrayList pool = null;
 
50
 
 
51
                private MAC hmacsha1 = null;
 
52
 
 
53
                internal KnownHosts(JSch jsch) : base()
 
54
                {
 
55
                        this.jsch = jsch;
 
56
                        pool = new ArrayList();
 
57
                }
 
58
 
 
59
                /// <exception cref="NSch.JSchException"></exception>
 
60
                internal virtual void SetKnownHosts(string foo)
 
61
                {
 
62
                        try
 
63
                        {
 
64
                                known_hosts = foo;
 
65
                                FileInputStream fis = new FileInputStream(foo);
 
66
                                SetKnownHosts(fis);
 
67
                        }
 
68
                        catch (FileNotFoundException)
 
69
                        {
 
70
                        }
 
71
                }
 
72
 
 
73
                /// <exception cref="NSch.JSchException"></exception>
 
74
                internal virtual void SetKnownHosts(InputStream foo)
 
75
                {
 
76
                        pool.Clear();
 
77
                        StringBuilder sb = new StringBuilder();
 
78
                        byte i;
 
79
                        int j;
 
80
                        bool error = false;
 
81
                        try
 
82
                        {
 
83
                                InputStream fis = foo;
 
84
                                string host;
 
85
                                string key = null;
 
86
                                int type;
 
87
                                byte[] buf = new byte[1024];
 
88
                                int bufl = 0;
 
89
                                while (true)
 
90
                                {
 
91
                                        bufl = 0;
 
92
                                        while (true)
 
93
                                        {
 
94
                                                j = fis.Read();
 
95
                                                if (j == -1)
 
96
                                                {
 
97
                                                        if (bufl == 0)
 
98
                                                        {
 
99
                                                                goto loop_break;
 
100
                                                        }
 
101
                                                        else
 
102
                                                        {
 
103
                                                                break;
 
104
                                                        }
 
105
                                                }
 
106
                                                if (j == unchecked((int)(0x0d)))
 
107
                                                {
 
108
                                                        continue;
 
109
                                                }
 
110
                                                if (j == unchecked((int)(0x0a)))
 
111
                                                {
 
112
                                                        break;
 
113
                                                }
 
114
                                                if (buf.Length <= bufl)
 
115
                                                {
 
116
                                                        if (bufl > 1024 * 10)
 
117
                                                        {
 
118
                                                                break;
 
119
                                                        }
 
120
                                                        // too long...
 
121
                                                        byte[] newbuf = new byte[buf.Length * 2];
 
122
                                                        System.Array.Copy(buf, 0, newbuf, 0, buf.Length);
 
123
                                                        buf = newbuf;
 
124
                                                }
 
125
                                                buf[bufl++] = unchecked((byte)j);
 
126
                                        }
 
127
                                        j = 0;
 
128
                                        while (j < bufl)
 
129
                                        {
 
130
                                                i = buf[j];
 
131
                                                if (i == ' ' || i == '\t')
 
132
                                                {
 
133
                                                        j++;
 
134
                                                        continue;
 
135
                                                }
 
136
                                                if (i == '#')
 
137
                                                {
 
138
                                                        AddInvalidLine(Util.Byte2str(buf, 0, bufl));
 
139
                                                        goto loop_continue;
 
140
                                                }
 
141
                                                break;
 
142
                                        }
 
143
                                        if (j >= bufl)
 
144
                                        {
 
145
                                                AddInvalidLine(Util.Byte2str(buf, 0, bufl));
 
146
                                                goto loop_continue;
 
147
                                        }
 
148
                                        sb.Length = 0;
 
149
                                        while (j < bufl)
 
150
                                        {
 
151
                                                i = buf[j++];
 
152
                                                if (i == unchecked((int)(0x20)) || i == '\t')
 
153
                                                {
 
154
                                                        break;
 
155
                                                }
 
156
                                                sb.Append((char)i);
 
157
                                        }
 
158
                                        host = sb.ToString();
 
159
                                        if (j >= bufl || host.Length == 0)
 
160
                                        {
 
161
                                                AddInvalidLine(Util.Byte2str(buf, 0, bufl));
 
162
                                                goto loop_continue;
 
163
                                        }
 
164
                                        sb.Length = 0;
 
165
                                        type = -1;
 
166
                                        while (j < bufl)
 
167
                                        {
 
168
                                                i = buf[j++];
 
169
                                                if (i == unchecked((int)(0x20)) || i == '\t')
 
170
                                                {
 
171
                                                        break;
 
172
                                                }
 
173
                                                sb.Append((char)i);
 
174
                                        }
 
175
                                        if (sb.ToString().Equals("ssh-dss"))
 
176
                                        {
 
177
                                                type = HostKey.SSHDSS;
 
178
                                        }
 
179
                                        else
 
180
                                        {
 
181
                                                if (sb.ToString().Equals("ssh-rsa"))
 
182
                                                {
 
183
                                                        type = HostKey.SSHRSA;
 
184
                                                }
 
185
                                                else
 
186
                                                {
 
187
                                                        j = bufl;
 
188
                                                }
 
189
                                        }
 
190
                                        if (j >= bufl)
 
191
                                        {
 
192
                                                AddInvalidLine(Util.Byte2str(buf, 0, bufl));
 
193
                                                goto loop_continue;
 
194
                                        }
 
195
                                        sb.Length = 0;
 
196
                                        while (j < bufl)
 
197
                                        {
 
198
                                                i = buf[j++];
 
199
                                                if (i == unchecked((int)(0x0d)))
 
200
                                                {
 
201
                                                        continue;
 
202
                                                }
 
203
                                                if (i == unchecked((int)(0x0a)))
 
204
                                                {
 
205
                                                        break;
 
206
                                                }
 
207
                                                sb.Append((char)i);
 
208
                                        }
 
209
                                        key = sb.ToString();
 
210
                                        if (key.Length == 0)
 
211
                                        {
 
212
                                                AddInvalidLine(Util.Byte2str(buf, 0, bufl));
 
213
                                                goto loop_continue;
 
214
                                        }
 
215
                                        //System.err.println(host);
 
216
                                        //System.err.println("|"+key+"|");
 
217
                                        HostKey hk = null;
 
218
                                        hk = new KnownHosts.HashedHostKey(this, host, type, Util.FromBase64(Util.Str2byte
 
219
                                                (key), 0, key.Length));
 
220
                                        pool.Add(hk);
 
221
loop_continue: ;
 
222
                                }
 
223
loop_break: ;
 
224
                                fis.Close();
 
225
                                if (error)
 
226
                                {
 
227
                                        throw new JSchException("KnownHosts: invalid format");
 
228
                                }
 
229
                        }
 
230
                        catch (Exception e)
 
231
                        {
 
232
                                if (e is JSchException)
 
233
                                {
 
234
                                        throw (JSchException)e;
 
235
                                }
 
236
                                if (e is Exception)
 
237
                                {
 
238
                                        throw new JSchException(e.ToString(), (Exception)e);
 
239
                                }
 
240
                                throw new JSchException(e.ToString());
 
241
                        }
 
242
                }
 
243
 
 
244
                /// <exception cref="NSch.JSchException"></exception>
 
245
                private void AddInvalidLine(string line)
 
246
                {
 
247
                        HostKey hk = new HostKey(line, HostKey.UNKNOWN, null);
 
248
                        pool.Add(hk);
 
249
                }
 
250
 
 
251
                internal virtual string GetKnownHostsFile()
 
252
                {
 
253
                        return known_hosts;
 
254
                }
 
255
 
 
256
                public override string GetKnownHostsRepositoryID()
 
257
                {
 
258
                        return known_hosts;
 
259
                }
 
260
 
 
261
                public override int Check(string host, byte[] key)
 
262
                {
 
263
                        int result = NOT_INCLUDED;
 
264
                        if (host == null)
 
265
                        {
 
266
                                return result;
 
267
                        }
 
268
                        int type = GetType(key);
 
269
                        HostKey hk;
 
270
                        lock (pool)
 
271
                        {
 
272
                                for (int i = 0; i < pool.Count; i++)
 
273
                                {
 
274
                                        hk = (HostKey)(pool[i]);
 
275
                                        if (hk.IsMatched(host) && hk.type == type)
 
276
                                        {
 
277
                                                if (Util.Array_equals(hk.key, key))
 
278
                                                {
 
279
                                                        return OK;
 
280
                                                }
 
281
                                                else
 
282
                                                {
 
283
                                                        result = CHANGED;
 
284
                                                }
 
285
                                        }
 
286
                                }
 
287
                        }
 
288
                        if (result == NOT_INCLUDED && host.StartsWith("[") && host.IndexOf("]:") > 1)
 
289
                        {
 
290
                                return Check(Sharpen.Runtime.Substring(host, 1, host.IndexOf("]:")), key);
 
291
                        }
 
292
                        return result;
 
293
                }
 
294
 
 
295
                public override void Add(HostKey hostkey, UserInfo userinfo)
 
296
                {
 
297
                        int type = hostkey.type;
 
298
                        string host = hostkey.GetHost();
 
299
                        byte[] key = hostkey.key;
 
300
                        HostKey hk = null;
 
301
                        lock (pool)
 
302
                        {
 
303
                                for (int i = 0; i < pool.Count; i++)
 
304
                                {
 
305
                                        hk = (HostKey)(pool[i]);
 
306
                                        if (hk.IsMatched(host) && hk.type == type)
 
307
                                        {
 
308
                                        }
 
309
                                }
 
310
                        }
 
311
                        hk = hostkey;
 
312
                        pool.Add(hk);
 
313
                        string bar = GetKnownHostsRepositoryID();
 
314
                        if (bar != null)
 
315
                        {
 
316
                                bool foo = true;
 
317
                                FilePath goo = new FilePath(bar);
 
318
                                if (!goo.Exists())
 
319
                                {
 
320
                                        foo = false;
 
321
                                        if (userinfo != null)
 
322
                                        {
 
323
                                                foo = userinfo.PromptYesNo(bar + " does not exist.\n" + "Are you sure you want to create it?"
 
324
                                                        );
 
325
                                                goo = goo.GetParentFile();
 
326
                                                if (foo && goo != null && !goo.Exists())
 
327
                                                {
 
328
                                                        foo = userinfo.PromptYesNo("The parent directory " + goo + " does not exist.\n" +
 
329
                                                                 "Are you sure you want to create it?");
 
330
                                                        if (foo)
 
331
                                                        {
 
332
                                                                if (!goo.Mkdirs())
 
333
                                                                {
 
334
                                                                        userinfo.ShowMessage(goo + " has not been created.");
 
335
                                                                        foo = false;
 
336
                                                                }
 
337
                                                                else
 
338
                                                                {
 
339
                                                                        userinfo.ShowMessage(goo + " has been succesfully created.\nPlease check its access permission."
 
340
                                                                                );
 
341
                                                                }
 
342
                                                        }
 
343
                                                }
 
344
                                                if (goo == null)
 
345
                                                {
 
346
                                                        foo = false;
 
347
                                                }
 
348
                                        }
 
349
                                }
 
350
                                if (foo)
 
351
                                {
 
352
                                        try
 
353
                                        {
 
354
                                                Sync(bar);
 
355
                                        }
 
356
                                        catch (Exception e)
 
357
                                        {
 
358
                                                System.Console.Error.WriteLine("sync known_hosts: " + e);
 
359
                                        }
 
360
                                }
 
361
                        }
 
362
                }
 
363
 
 
364
                public override HostKey[] GetHostKey()
 
365
                {
 
366
                        return GetHostKey(null, null);
 
367
                }
 
368
 
 
369
                public override HostKey[] GetHostKey(string host, string type)
 
370
                {
 
371
                        lock (pool)
 
372
                        {
 
373
                                int count = 0;
 
374
                                for (int i = 0; i < pool.Count; i++)
 
375
                                {
 
376
                                        HostKey hk = (HostKey)pool[i];
 
377
                                        if (hk.type == HostKey.UNKNOWN)
 
378
                                        {
 
379
                                                continue;
 
380
                                        }
 
381
                                        if (host == null || (hk.IsMatched(host) && (type == null || hk.GetType().Equals(type
 
382
                                                ))))
 
383
                                        {
 
384
                                                count++;
 
385
                                        }
 
386
                                }
 
387
                                if (count == 0)
 
388
                                {
 
389
                                        return null;
 
390
                                }
 
391
                                HostKey[] foo = new HostKey[count];
 
392
                                int j = 0;
 
393
                                for (int i_1 = 0; i_1 < pool.Count; i_1++)
 
394
                                {
 
395
                                        HostKey hk = (HostKey)pool[i_1];
 
396
                                        if (hk.type == HostKey.UNKNOWN)
 
397
                                        {
 
398
                                                continue;
 
399
                                        }
 
400
                                        if (host == null || (hk.IsMatched(host) && (type == null || hk.GetType().Equals(type
 
401
                                                ))))
 
402
                                        {
 
403
                                                foo[j++] = hk;
 
404
                                        }
 
405
                                }
 
406
                                return foo;
 
407
                        }
 
408
                }
 
409
 
 
410
                public override void Remove(string host, string type)
 
411
                {
 
412
                        Remove(host, type, null);
 
413
                }
 
414
 
 
415
                public override void Remove(string host, string type, byte[] key)
 
416
                {
 
417
                        bool sync = false;
 
418
                        lock (pool)
 
419
                        {
 
420
                                for (int i = 0; i < pool.Count; i++)
 
421
                                {
 
422
                                        HostKey hk = (HostKey)(pool[i]);
 
423
                                        if (host == null || (hk.IsMatched(host) && (type == null || (hk.GetType().Equals(
 
424
                                                type) && (key == null || Util.Array_equals(key, hk.key))))))
 
425
                                        {
 
426
                                                string hosts = hk.GetHost();
 
427
                                                if (hosts.Equals(host) || ((hk is KnownHosts.HashedHostKey) && ((KnownHosts.HashedHostKey
 
428
                                                        )hk).IsHashed()))
 
429
                                                {
 
430
                                                        pool.RemoveElement(hk);
 
431
                                                }
 
432
                                                else
 
433
                                                {
 
434
                                                        hk.host = DeleteSubString(hosts, host);
 
435
                                                }
 
436
                                                sync = true;
 
437
                                        }
 
438
                                }
 
439
                        }
 
440
                        if (sync)
 
441
                        {
 
442
                                try
 
443
                                {
 
444
                                        Sync();
 
445
                                }
 
446
                                catch (Exception)
 
447
                                {
 
448
                                }
 
449
                        }
 
450
                }
 
451
 
 
452
                /// <exception cref="System.IO.IOException"></exception>
 
453
                protected internal virtual void Sync()
 
454
                {
 
455
                        if (known_hosts != null)
 
456
                        {
 
457
                                Sync(known_hosts);
 
458
                        }
 
459
                }
 
460
 
 
461
                /// <exception cref="System.IO.IOException"></exception>
 
462
                protected internal virtual void Sync(string foo)
 
463
                {
 
464
                        lock (this)
 
465
                        {
 
466
                                if (foo == null)
 
467
                                {
 
468
                                        return;
 
469
                                }
 
470
                                FileOutputStream fos = new FileOutputStream(foo);
 
471
                                Dump(fos);
 
472
                                fos.Close();
 
473
                        }
 
474
                }
 
475
 
 
476
                private static readonly byte[] space = new byte[] { unchecked((byte)unchecked((int
 
477
                        )(0x20))) };
 
478
 
 
479
                private static readonly byte[] cr = Util.Str2byte("\n");
 
480
 
 
481
                /// <exception cref="System.IO.IOException"></exception>
 
482
                internal virtual void Dump(OutputStream @out)
 
483
                {
 
484
                        try
 
485
                        {
 
486
                                HostKey hk;
 
487
                                lock (pool)
 
488
                                {
 
489
                                        for (int i = 0; i < pool.Count; i++)
 
490
                                        {
 
491
                                                hk = (HostKey)(pool[i]);
 
492
                                                //hk.dump(out);
 
493
                                                string host = hk.GetHost();
 
494
                                                string type = hk.GetType();
 
495
                                                if (type.Equals("UNKNOWN"))
 
496
                                                {
 
497
                                                        @out.Write(Util.Str2byte(host));
 
498
                                                        @out.Write(cr);
 
499
                                                        continue;
 
500
                                                }
 
501
                                                @out.Write(Util.Str2byte(host));
 
502
                                                @out.Write(space);
 
503
                                                @out.Write(Util.Str2byte(type));
 
504
                                                @out.Write(space);
 
505
                                                @out.Write(Util.Str2byte(hk.GetKey()));
 
506
                                                @out.Write(cr);
 
507
                                        }
 
508
                                }
 
509
                        }
 
510
                        catch (Exception e)
 
511
                        {
 
512
                                System.Console.Error.WriteLine(e);
 
513
                        }
 
514
                }
 
515
 
 
516
                private int GetType(byte[] key)
 
517
                {
 
518
                        if (key[8] == 'd')
 
519
                        {
 
520
                                return HostKey.SSHDSS;
 
521
                        }
 
522
                        if (key[8] == 'r')
 
523
                        {
 
524
                                return HostKey.SSHRSA;
 
525
                        }
 
526
                        return HostKey.UNKNOWN;
 
527
                }
 
528
 
 
529
                private string DeleteSubString(string hosts, string host)
 
530
                {
 
531
                        int i = 0;
 
532
                        int hostlen = host.Length;
 
533
                        int hostslen = hosts.Length;
 
534
                        int j;
 
535
                        while (i < hostslen)
 
536
                        {
 
537
                                j = hosts.IndexOf(',', i);
 
538
                                if (j == -1)
 
539
                                {
 
540
                                        break;
 
541
                                }
 
542
                                if (!host.Equals(Sharpen.Runtime.Substring(hosts, i, j)))
 
543
                                {
 
544
                                        i = j + 1;
 
545
                                        continue;
 
546
                                }
 
547
                                return Sharpen.Runtime.Substring(hosts, 0, i) + Sharpen.Runtime.Substring(hosts, 
 
548
                                        j + 1);
 
549
                        }
 
550
                        if (hosts.EndsWith(host) && hostslen - i == hostlen)
 
551
                        {
 
552
                                return Sharpen.Runtime.Substring(hosts, 0, (hostlen == hostslen) ? 0 : hostslen -
 
553
                                         hostlen - 1);
 
554
                        }
 
555
                        return hosts;
 
556
                }
 
557
 
 
558
                private MAC GetHMACSHA1()
 
559
                {
 
560
                        lock (this)
 
561
                        {
 
562
                                if (hmacsha1 == null)
 
563
                                {
 
564
                                        try
 
565
                                        {
 
566
                                                Type c = Sharpen.Runtime.GetType(JSch.GetConfig("hmac-sha1"));
 
567
                                                hmacsha1 = (MAC)(System.Activator.CreateInstance(c));
 
568
                                        }
 
569
                                        catch (Exception e)
 
570
                                        {
 
571
                                                System.Console.Error.WriteLine("hmacsha1: " + e);
 
572
                                        }
 
573
                                }
 
574
                                return hmacsha1;
 
575
                        }
 
576
                }
 
577
 
 
578
                /// <exception cref="NSch.JSchException"></exception>
 
579
                internal virtual HostKey CreateHashedHostKey(string host, byte[] key)
 
580
                {
 
581
                        KnownHosts.HashedHostKey hhk = new KnownHosts.HashedHostKey(this, host, key);
 
582
                        hhk.Hash();
 
583
                        return hhk;
 
584
                }
 
585
 
 
586
                internal class HashedHostKey : HostKey
 
587
                {
 
588
                        private static readonly string HASH_MAGIC = "|1|";
 
589
 
 
590
                        private static readonly string HASH_DELIM = "|";
 
591
 
 
592
                        private bool hashed = false;
 
593
 
 
594
                        internal byte[] salt = null;
 
595
 
 
596
                        internal byte[] hash = null;
 
597
 
 
598
                        /// <exception cref="NSch.JSchException"></exception>
 
599
                        public HashedHostKey(KnownHosts _enclosing, string host, byte[] key) : this(_enclosing, host, 
 
600
                                HostKey.GUESS, key)
 
601
                        {
 
602
                                this._enclosing = _enclosing;
 
603
                        }
 
604
 
 
605
                        /// <exception cref="NSch.JSchException"></exception>
 
606
                        public HashedHostKey(KnownHosts _enclosing, string host, int type, byte[] key) : 
 
607
                                base(host, type, key)
 
608
                        {
 
609
                                this._enclosing = _enclosing;
 
610
                                if (this.host.StartsWith(KnownHosts.HashedHostKey.HASH_MAGIC) && Sharpen.Runtime.Substring
 
611
                                        (this.host, KnownHosts.HashedHostKey.HASH_MAGIC.Length).IndexOf(KnownHosts.HashedHostKey
 
612
                                        .HASH_DELIM) > 0)
 
613
                                {
 
614
                                        string data = Sharpen.Runtime.Substring(this.host, KnownHosts.HashedHostKey.HASH_MAGIC
 
615
                                                .Length);
 
616
                                        string _salt = Sharpen.Runtime.Substring(data, 0, data.IndexOf(KnownHosts.HashedHostKey
 
617
                                                .HASH_DELIM));
 
618
                                        string _hash = Sharpen.Runtime.Substring(data, data.IndexOf(KnownHosts.HashedHostKey
 
619
                                                .HASH_DELIM) + 1);
 
620
                                        this.salt = Util.FromBase64(Util.Str2byte(_salt), 0, _salt.Length);
 
621
                                        this.hash = Util.FromBase64(Util.Str2byte(_hash), 0, _hash.Length);
 
622
                                        if (this.salt.Length != 20 || this.hash.Length != 20)
 
623
                                        {
 
624
                                                // block size of hmac-sha1
 
625
                                                this.salt = null;
 
626
                                                this.hash = null;
 
627
                                                return;
 
628
                                        }
 
629
                                        this.hashed = true;
 
630
                                }
 
631
                        }
 
632
 
 
633
                        internal override bool IsMatched(string _host)
 
634
                        {
 
635
                                if (!this.hashed)
 
636
                                {
 
637
                                        return base.IsMatched(_host);
 
638
                                }
 
639
                                MAC macsha1 = this._enclosing.GetHMACSHA1();
 
640
                                try
 
641
                                {
 
642
                                        lock (macsha1)
 
643
                                        {
 
644
                                                macsha1.Init(this.salt);
 
645
                                                byte[] foo = Util.Str2byte(_host);
 
646
                                                macsha1.Update(foo, 0, foo.Length);
 
647
                                                byte[] bar = new byte[macsha1.GetBlockSize()];
 
648
                                                macsha1.DoFinal(bar, 0);
 
649
                                                return Util.Array_equals(this.hash, bar);
 
650
                                        }
 
651
                                }
 
652
                                catch (Exception e)
 
653
                                {
 
654
                                        System.Console.Out.WriteLine(e);
 
655
                                }
 
656
                                return false;
 
657
                        }
 
658
 
 
659
                        internal virtual bool IsHashed()
 
660
                        {
 
661
                                return this.hashed;
 
662
                        }
 
663
 
 
664
                        internal virtual void Hash()
 
665
                        {
 
666
                                if (this.hashed)
 
667
                                {
 
668
                                        return;
 
669
                                }
 
670
                                MAC macsha1 = this._enclosing.GetHMACSHA1();
 
671
                                if (this.salt == null)
 
672
                                {
 
673
                                        Random random = Session.random;
 
674
                                        lock (random)
 
675
                                        {
 
676
                                                this.salt = new byte[macsha1.GetBlockSize()];
 
677
                                                random.Fill(this.salt, 0, this.salt.Length);
 
678
                                        }
 
679
                                }
 
680
                                try
 
681
                                {
 
682
                                        lock (macsha1)
 
683
                                        {
 
684
                                                macsha1.Init(this.salt);
 
685
                                                byte[] foo = Util.Str2byte(this.host);
 
686
                                                macsha1.Update(foo, 0, foo.Length);
 
687
                                                this.hash = new byte[macsha1.GetBlockSize()];
 
688
                                                macsha1.DoFinal(this.hash, 0);
 
689
                                        }
 
690
                                }
 
691
                                catch (Exception)
 
692
                                {
 
693
                                }
 
694
                                this.host = KnownHosts.HashedHostKey.HASH_MAGIC + Util.Byte2str(Util.ToBase64(this
 
695
                                        .salt, 0, this.salt.Length)) + KnownHosts.HashedHostKey.HASH_DELIM + Util.Byte2str
 
696
                                        (Util.ToBase64(this.hash, 0, this.hash.Length));
 
697
                                this.hashed = true;
 
698
                        }
 
699
 
 
700
                        private readonly KnownHosts _enclosing;
 
701
                }
 
702
        }
 
703
}