~ubuntu-branches/ubuntu/trusty/jsch/trusty-proposed

« back to all changes in this revision

Viewing changes to src/com/jcraft/jsch/KnownHosts.java

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2008-03-21 11:41:01 UTC
  • mfrom: (3.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080321114101-2g9w5l8ynwf6pbsq
Tags: 0.1.37-3
Add OSGi manifest patch. Thanks to Roberto Jimenoca. Closes: #471209.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2
2
/*
3
 
Copyright (c) 2002,2003,2004,2005,2006 ymnk, JCraft,Inc. All rights reserved.
 
3
Copyright (c) 2002-2008 ymnk, JCraft,Inc. All rights reserved.
4
4
 
5
5
Redistribution and use in source and binary forms, with or without
6
6
modification, are permitted provided that the following conditions are met:
34
34
public
35
35
class KnownHosts implements HostKeyRepository{
36
36
  private static final String _known_hosts="known_hosts";
37
 
  /*
38
 
  static final int OK=0;
39
 
  static final int NOT_INCLUDED=1;
40
 
  static final int CHANGED=2;
41
 
  */
42
37
 
43
38
  /*
44
39
  static final int SSHDSS=0;
50
45
  private String known_hosts=null;
51
46
  private java.util.Vector pool=null;
52
47
 
 
48
  private MAC hmacsha1=null;
 
49
 
53
50
  KnownHosts(JSch jsch){
54
51
    super();
55
52
    this.jsch=jsch;
83
80
        bufl=0;
84
81
        while(true){
85
82
          j=fis.read();
86
 
          if(j==-1){ break loop;}
 
83
          if(j==-1){
 
84
            if(bufl==0){ break loop; }
 
85
            else{ break; }
 
86
          }
87
87
          if(j==0x0d){ continue; }
88
88
          if(j==0x0a){ break; }
89
89
          if(buf.length<=bufl){
150
150
          continue loop; 
151
151
        }
152
152
 
153
 
        //System.out.println(host);
154
 
        //System.out.println("|"+key+"|");
 
153
        //System.err.println(host);
 
154
        //System.err.println("|"+key+"|");
155
155
 
156
 
        HostKey hk = new HostKey(host, type, 
157
 
                                 Util.fromBase64(key.getBytes(), 0, 
158
 
                                                 key.length()));
 
156
        HostKey hk = null;
 
157
        hk = new HashedHostKey(host, type, 
 
158
                               Util.fromBase64(key.getBytes(), 0, 
 
159
                                               key.length()));
159
160
        pool.addElement(hk);
160
161
      }
161
162
      fis.close();
164
165
      }
165
166
    }
166
167
    catch(Exception e){
167
 
      if(e instanceof JSchException){
 
168
      if(e instanceof JSchException)
168
169
        throw (JSchException)e;         
169
 
      }
 
170
      if(e instanceof Throwable)
 
171
        throw new JSchException(e.toString(), (Throwable)e);
170
172
      throw new JSchException(e.toString());
171
173
    }
172
174
  }
173
 
  private void addInvalidLine(String line){
 
175
  private void addInvalidLine(String line) throws JSchException {
174
176
    HostKey hk = new HostKey(line, HostKey.UNKNOWN, null);
175
177
    pool.addElement(hk);
176
178
  }
178
180
  public String getKnownHostsRepositoryID(){ return known_hosts; }
179
181
 
180
182
  public int check(String host, byte[] key){
181
 
    String foo; 
182
 
    byte[] bar;
183
 
    HostKey hk;
184
183
    int result=NOT_INCLUDED;
 
184
    if(host==null){
 
185
      return result;
 
186
    }
 
187
 
185
188
    int type=getType(key);
 
189
    HostKey hk;
186
190
 
187
191
    synchronized(pool){
188
192
    for(int i=0; i<pool.size(); i++){
189
193
      hk=(HostKey)(pool.elementAt(i));
190
 
      if(isIncluded(hk.host, host) && hk.type==type){
 
194
      if(hk.isMatched(host) && hk.type==type){
191
195
        if(Util.array_equals(hk.key, key)){
192
 
          //System.out.println("find!!");
 
196
          //System.err.println("find!!");
193
197
          return OK;
194
198
        }
195
199
        else{
198
202
      }
199
203
    }
200
204
    }
201
 
    //System.out.println("fail!!");
 
205
    //System.err.println("fail!!");
202
206
    return result;
203
207
  }
204
 
  public void add(String host, byte[] key, UserInfo userinfo){
205
 
    HostKey hk;
206
 
    int type=getType(key);
 
208
  public void add(HostKey hostkey, UserInfo userinfo){
 
209
    int type=hostkey.type;
 
210
    String host=hostkey.getHost();
 
211
    byte[] key=hostkey.key;
207
212
 
 
213
    HostKey hk=null;
208
214
    synchronized(pool){
209
215
      for(int i=0; i<pool.size(); i++){
210
216
        hk=(HostKey)(pool.elementAt(i));
211
 
        if(isIncluded(hk.host, host) && hk.type==type){
 
217
        if(hk.isMatched(host) && hk.type==type){
212
218
/*
213
219
          if(Util.array_equals(hk.key, key)){ return; }
214
220
          if(hk.host.equals(host)){
224
230
      }
225
231
    }
226
232
 
227
 
    hk=new HostKey(host, type, key);
 
233
    hk=hostkey;
 
234
 
228
235
    pool.addElement(hk);
229
236
 
230
237
    String bar=getKnownHostsRepositoryID();
259
266
        try{ 
260
267
          sync(bar); 
261
268
        }
262
 
        catch(Exception e){ System.out.println("sync known_hosts: "+e); }
 
269
        catch(Exception e){ System.err.println("sync known_hosts: "+e); }
263
270
      }
264
271
    }
265
272
  }
274
281
        HostKey hk=(HostKey)pool.elementAt(i);
275
282
        if(hk.type==HostKey.UNKNOWN) continue;
276
283
        if(host==null || 
277
 
           (isIncluded(hk.host, host) && 
 
284
           (hk.isMatched(host) && 
278
285
            (type==null || hk.getType().equals(type)))){
279
286
          count++;
280
287
        }
286
293
        HostKey hk=(HostKey)pool.elementAt(i);
287
294
        if(hk.type==HostKey.UNKNOWN) continue;
288
295
        if(host==null || 
289
 
           (isIncluded(hk.host, host) && 
 
296
           (hk.isMatched(host) && 
290
297
            (type==null || hk.getType().equals(type)))){
291
298
          foo[j++]=hk;
292
299
        }
302
309
    synchronized(pool){
303
310
    for(int i=0; i<pool.size(); i++){
304
311
      HostKey hk=(HostKey)(pool.elementAt(i));
305
 
      String hosts=hk.getHost();
306
312
      if(host==null ||
307
 
         (isIncluded(hosts, host) && 
 
313
         (hk.isMatched(host) && 
308
314
          (type==null || (hk.getType().equals(type) &&
309
315
                          (key==null || Util.array_equals(key, hk.key)))))){
310
 
        if(hosts.equals(host)){
 
316
        String hosts=hk.getHost();
 
317
        if(hosts.equals(host) || 
 
318
           ((hk instanceof HashedHostKey) &&
 
319
            ((HashedHostKey)hk).isHashed())){
311
320
          pool.removeElement(hk);
312
321
        }
313
322
        else{
359
368
      }
360
369
    }
361
370
    catch(Exception e){
362
 
      System.out.println(e);
 
371
      System.err.println(e);
363
372
    }
364
373
  }
365
374
  private int getType(byte[] key){
386
395
    }
387
396
    return hosts;
388
397
  }
389
 
  private boolean isIncluded(String hosts, String host){
390
 
    int i=0;
391
 
    int hostlen=host.length();
392
 
    int hostslen=hosts.length();
393
 
    int j;
394
 
    while(i<hostslen){
395
 
      j=hosts.indexOf(',', i);
396
 
      if(j==-1){
397
 
       if(hostlen!=hostslen-i) return false;
398
 
       return hosts.regionMatches(true, i, host, 0, hostlen);
399
 
       //return hosts.substring(i).equals(host);
400
 
      }
401
 
      if(hostlen==(j-i)){
402
 
        if(hosts.regionMatches(true, i, host, 0, hostlen)) return true;
403
 
        //if(hosts.substring(i, i+hostlen).equals(host)) return true;
404
 
      }
405
 
      i=j+1;
406
 
    }
407
 
    return false;
408
 
  }
409
 
  /*
410
 
  private static boolean equals(byte[] foo, byte[] bar){
411
 
    if(foo.length!=bar.length)return false;
412
 
    for(int i=0; i<foo.length; i++){
413
 
      if(foo[i]!=bar[i])return false;
414
 
    }
415
 
    return true;
416
 
  }
417
 
  */
418
 
 
419
 
  /*
420
 
  private static final byte[] space={(byte)0x20};
421
 
  private static final byte[] sshdss="ssh-dss".getBytes();
422
 
  private static final byte[] sshrsa="ssh-rsa".getBytes();
423
 
  private static final byte[] cr="\n".getBytes();
424
 
 
425
 
  public class HostKey{
426
 
    String host;
427
 
    int type;
428
 
    byte[] key;
429
 
    HostKey(String host, int type, byte[] key){
430
 
      this.host=host; this.type=type; this.key=key;
431
 
    }
432
 
    void dump(OutputStream out) throws IOException{
433
 
      if(type==UNKNOWN){
434
 
        out.write(host.getBytes());
435
 
        out.write(cr);
436
 
        return;
437
 
      }
438
 
      out.write(host.getBytes());
439
 
      out.write(space);
440
 
      if(type==HostKey.SSHDSS){ out.write(sshdss); }
441
 
      else if(type==HostKey.SSHRSA){ out.write(sshrsa);}
442
 
      out.write(space);
443
 
      out.write(Util.toBase64(key, 0, key.length));
444
 
      out.write(cr);
445
 
    }
446
 
 
447
 
    public String getHost(){ return host; }
448
 
    public String getType(){
449
 
      if(type==SSHDSS){ return new String(sshdss); }
450
 
      if(type==SSHRSA){ return new String(sshrsa);}
451
 
      return "UNKNOWN";
452
 
    }
453
 
    public String getKey(){
454
 
      return new String(Util.toBase64(key, 0, key.length));
455
 
    }
456
 
    public String getFingerPrint(){
457
 
      HASH hash=null;
458
 
      try{
459
 
        Class c=Class.forName(jsch.getConfig("md5"));
460
 
        hash=(HASH)(c.newInstance());
461
 
      }
462
 
      catch(Exception e){ System.err.println("getFingerPrint: "+e); }
463
 
      return Util.getFingerPrint(hash, key);
464
 
    }
465
 
  }
466
 
  */
 
398
 
 
399
  private synchronized MAC getHMACSHA1(){
 
400
    if(hmacsha1==null){
 
401
      try{
 
402
        Class c=Class.forName(jsch.getConfig("hmac-sha1"));
 
403
        hmacsha1=(MAC)(c.newInstance());
 
404
      }
 
405
      catch(Exception e){ 
 
406
        System.err.println("hmacsha1: "+e); 
 
407
      }
 
408
    }
 
409
    return hmacsha1;
 
410
  }
 
411
 
 
412
  HostKey createHashedHostKey(String host, byte[]key) throws JSchException {
 
413
    HashedHostKey hhk=new HashedHostKey(host, key);
 
414
    hhk.hash();
 
415
    return hhk;
 
416
  } 
 
417
  class HashedHostKey extends HostKey{
 
418
    private static final String HASH_MAGIC="|1|";
 
419
    private static final String HASH_DELIM="|";
 
420
 
 
421
    private boolean hashed=false;
 
422
    byte[] salt=null;
 
423
    byte[] hash=null;
 
424
 
 
425
 
 
426
    HashedHostKey(String host, byte[] key) throws JSchException {
 
427
      this(host, GUESS, key);
 
428
    }
 
429
    HashedHostKey(String host, int type, byte[] key) throws JSchException {
 
430
      super(host, type, key);
 
431
      if(this.host.startsWith(HASH_MAGIC) &&
 
432
         this.host.substring(HASH_MAGIC.length()).indexOf(HASH_DELIM)>0){
 
433
        String data=this.host.substring(HASH_MAGIC.length());
 
434
        String _salt=data.substring(0, data.indexOf(HASH_DELIM));
 
435
        String _hash=data.substring(data.indexOf(HASH_DELIM)+1);
 
436
        salt=Util.fromBase64(_salt.getBytes(), 0, _salt.length());
 
437
        hash=Util.fromBase64(_hash.getBytes(), 0, _hash.length());
 
438
        if(salt.length!=20 ||  // block size of hmac-sha1
 
439
           hash.length!=20){
 
440
          salt=null;
 
441
          hash=null;
 
442
          return;
 
443
        }
 
444
        hashed=true;
 
445
      }
 
446
    }
 
447
 
 
448
    boolean isMatched(String _host){
 
449
      if(!hashed){
 
450
        return super.isMatched(_host);
 
451
      }
 
452
      MAC macsha1=getHMACSHA1();
 
453
      try{
 
454
        synchronized(macsha1){
 
455
          macsha1.init(salt);
 
456
          byte[] foo=_host.getBytes();
 
457
          macsha1.update(foo, 0, foo.length);
 
458
          byte[] bar=new byte[macsha1.getBlockSize()];
 
459
          macsha1.doFinal(bar, 0);
 
460
          return Util.array_equals(hash, bar);
 
461
        }
 
462
      }
 
463
      catch(Exception e){
 
464
        System.out.println(e);
 
465
      }
 
466
      return false;
 
467
    }
 
468
 
 
469
    boolean isHashed(){
 
470
      return hashed;
 
471
    }
 
472
 
 
473
    void hash(){
 
474
      if(hashed)
 
475
        return;
 
476
      MAC macsha1=getHMACSHA1();
 
477
      if(salt==null){
 
478
        Random random=Session.random;
 
479
        synchronized(random){
 
480
          salt=new byte[macsha1.getBlockSize()];
 
481
          random.fill(salt, 0, salt.length);
 
482
        }
 
483
      }
 
484
      try{
 
485
        synchronized(macsha1){
 
486
          macsha1.init(salt);
 
487
          byte[] foo=host.getBytes();
 
488
          macsha1.update(foo, 0, foo.length);
 
489
          hash=new byte[macsha1.getBlockSize()];
 
490
          macsha1.doFinal(hash, 0);
 
491
        }
 
492
      }
 
493
      catch(Exception e){
 
494
      }
 
495
      host=HASH_MAGIC+new String(Util.toBase64(salt, 0, salt.length))+
 
496
        HASH_DELIM+new String(Util.toBase64(hash, 0, hash.length));
 
497
      hashed=true;
 
498
    }
 
499
  }
467
500
}