|
| 1 | +/* |
| 2 | + * Copyright (C)2009 - SSHJ Contributors |
| 3 | + * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + * you may not use this file except in compliance with the License. |
| 6 | + * You may obtain a copy of the License at |
| 7 | + * |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | + * |
| 10 | + * Unless required by applicable law or agreed to in writing, software |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + * See the License for the specific language governing permissions and |
| 14 | + * limitations under the License. |
| 15 | + */ |
| 16 | +package com.hierynomus.sshj.transport.verification |
| 17 | + |
| 18 | +import net.schmizz.sshj.common.KeyType |
| 19 | +import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts |
| 20 | +import net.schmizz.sshj.util.KeyUtil |
| 21 | +import org.junit.Ignore |
| 22 | +import org.junit.Rule |
| 23 | +import org.junit.Test |
| 24 | +import org.junit.rules.TemporaryFolder |
| 25 | +import spock.lang.Specification |
| 26 | +import spock.lang.Unroll |
| 27 | + |
| 28 | +import java.security.GeneralSecurityException |
| 29 | +import java.security.PublicKey |
| 30 | + |
| 31 | +import static org.hamcrest.CoreMatchers.equalTo |
| 32 | +import static org.hamcrest.CoreMatchers.instanceOf |
| 33 | +import static org.hamcrest.MatcherAssert.assertThat |
| 34 | + |
| 35 | +class OpenSSHKnownHostsSpec extends Specification { |
| 36 | + |
| 37 | + @Rule |
| 38 | + public TemporaryFolder temp = new TemporaryFolder(); |
| 39 | + |
| 40 | + |
| 41 | + @Unroll |
| 42 | + def "should add comment lines"() { |
| 43 | + given: |
| 44 | + def file = writeKnownHosts(contents) |
| 45 | + |
| 46 | + when: |
| 47 | + OpenSSHKnownHosts openSSHKnownHosts = new OpenSSHKnownHosts(file) |
| 48 | + |
| 49 | + then: |
| 50 | + openSSHKnownHosts.entries().size() == 1 |
| 51 | + openSSHKnownHosts.entries()[0] instanceof OpenSSHKnownHosts.CommentEntry |
| 52 | + |
| 53 | + where: |
| 54 | + contents << ["", "# this is a comment"] |
| 55 | + } |
| 56 | + |
| 57 | + def "should parse and verify plain host entry with RSA key"() { |
| 58 | + given: |
| 59 | + def f = writeKnownHosts("schmizz.net,69.163.155.180 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ==") |
| 60 | + final PublicKey key = KeyUtil |
| 61 | + .newRSAPublicKey( |
| 62 | + "e8ff4797075a861db9d2319960a836b2746ada3da514955d2921f2c6a6c9895cbd557f604e43772b6303e3cab2ad82d83b21acdef4edb72524f9c2bef893335115acacfe2989bcbb2e978e4fedc8abc090363e205d975c1fdc35e55ba4daa4b5d5ab7a22c40f547a4a0fd1c683dfff10551c708ff8c34ea4e175cb9bf2313865308fa23601e5a610e2f76838be7ded3b4d3a2c49d2d40fa20db51d1cc8ab20d330bb0dadb88b1a12853f0ecb7c7632947b098dcf435a54566bcf92befd55e03ee2a57d17524cd3d59d6e800c66059067e5eb6edb81946b3286950748240ec9afa4389f9b62bc92f94ec0fba9e64d6dc2f455f816016a4c5f3d507382ed5d3365", |
| 63 | + "23"); |
| 64 | + |
| 65 | + when: |
| 66 | + OpenSSHKnownHosts openSSHKnownHosts = new OpenSSHKnownHosts(f) |
| 67 | + |
| 68 | + then: |
| 69 | + openSSHKnownHosts.verify("schmizz.net", 22, key) |
| 70 | + openSSHKnownHosts.verify("69.163.155.180", 22, key) |
| 71 | + !openSSHKnownHosts.verify("69.163.155.18", 22, key) |
| 72 | + } |
| 73 | + |
| 74 | + def "should parse and verify hashed host entry"() { |
| 75 | + given: |
| 76 | + def f = writeKnownHosts("|1|F1E1KeoE/eEWhi10WpGv4OdiO6Y=|3988QV0VE8wmZL7suNrYQLITLCg= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6P9Hlwdahh250jGZYKg2snRq2j2lFJVdKSHyxqbJiVy9VX9gTkN3K2MD48qyrYLYOyGs3vTttyUk+cK++JMzURWsrP4piby7LpeOT+3Iq8CQNj4gXZdcH9w15Vuk2qS11at6IsQPVHpKD9HGg9//EFUccI/4w06k4XXLm/IxOGUwj6I2AeWmEOL3aDi+fe07TTosSdLUD6INtR0cyKsg0zC7Da24ixoShT8Oy3x2MpR7CY3PQ1pUVmvPkr79VeA+4qV9F1JM09WdboAMZgWQZ+XrbtuBlGsyhpUHSCQOya+kOJ+bYryS+U7A+6nmTW3C9FX4FgFqTF89UHOC7V0zZQ=="); |
| 77 | + final PublicKey key = KeyUtil |
| 78 | + .newRSAPublicKey( |
| 79 | + "e8ff4797075a861db9d2319960a836b2746ada3da514955d2921f2c6a6c9895cbd557f604e43772b6303e3cab2ad82d83b21acdef4edb72524f9c2bef893335115acacfe2989bcbb2e978e4fedc8abc090363e205d975c1fdc35e55ba4daa4b5d5ab7a22c40f547a4a0fd1c683dfff10551c708ff8c34ea4e175cb9bf2313865308fa23601e5a610e2f76838be7ded3b4d3a2c49d2d40fa20db51d1cc8ab20d330bb0dadb88b1a12853f0ecb7c7632947b098dcf435a54566bcf92befd55e03ee2a57d17524cd3d59d6e800c66059067e5eb6edb81946b3286950748240ec9afa4389f9b62bc92f94ec0fba9e64d6dc2f455f816016a4c5f3d507382ed5d3365", |
| 80 | + "23"); |
| 81 | + |
| 82 | + when: |
| 83 | + OpenSSHKnownHosts openSSHKnownHosts = new OpenSSHKnownHosts(f) |
| 84 | + |
| 85 | + then: |
| 86 | + openSSHKnownHosts.verify("192.168.1.61", 22, key) |
| 87 | + !openSSHKnownHosts.verify("192.168.1.2", 22, key) |
| 88 | + } |
| 89 | + |
| 90 | + def "should parse and verify v1 host entry"() { |
| 91 | + given: |
| 92 | + def f = writeKnownHosts("test.com,1.1.1.1 2048 35 22017496617994656680820635966392838863613340434802393112245951008866692373218840197754553998457793202561151141246686162285550121243768846314646395880632789308110750881198697743542374668273149584280424505890648953477691795864456749782348425425954366277600319096366690719901119774784695056100331902394094537054256611668966698242432417382422091372756244612839068092471592121759862971414741954991375710930168229171638843329213652899594987626853020377726482288618521941129157643483558764875338089684351824791983007780922947554898825663693324944982594850256042689880090306493029526546183035567296830604572253312294059766327") |
| 93 | + def key = KeyUtil.newRSAPublicKey("ae6983ed63a33afc69fe0b88b4ba14393120a0b66e1460916a8390ff109139cd14f4e1701ab5c5feeb479441fe2091d04c0ba7d3fa1756b80ed103657ab53b5d7daa38af22f59f9cbfc16892d4ef1f8fd3ae49663c295be1f568a160d54328fbc2c0598f48d32296b1b9942336234952c440cda1bfac904e3391db98e52f9b1de229adc18fc34a9a569717aa9a5b1145e73b8a8394354028d02054ca760243fb8fc1575490607dd098e698e02b5d8bdf22d55ec958245222ef4c65b8836b9f13674a2d2895a587bfd4423b4eeb6d3ef98451640e3d63d2fc6a761ffd34446abab028494caf36d67ffd65298d69f19f2d90bae4c207b671db563a08f1bb9bf237", |
| 94 | + "23") |
| 95 | + when: |
| 96 | + OpenSSHKnownHosts knownHosts = new OpenSSHKnownHosts(f) |
| 97 | + |
| 98 | + then: |
| 99 | + knownHosts.verify("test.com", 22, key) |
| 100 | + } |
| 101 | + |
| 102 | + def "should ignore malformed line"() { |
| 103 | + given: |
| 104 | + def f = writeKnownHosts("M36Lo+Ik5ukNugvvoNFlpnyiHMmtKxt3FpyEfYuryXjNqMNWHn/ARVnpUIl5jRLTB7WBzyLYMG7X5nuoFL9zYqKGtHxChbDunxMVbspw5WXI9VN+qxcLwmITmpEvI9ApyS/Ox2ZyN7zw==") |
| 105 | + |
| 106 | + when: |
| 107 | + OpenSSHKnownHosts knownHosts = new OpenSSHKnownHosts(f) |
| 108 | + |
| 109 | + then: |
| 110 | + knownHosts.entries().size() == 0 |
| 111 | + } |
| 112 | + |
| 113 | + File writeKnownHosts(String line) |
| 114 | + throws IOException { |
| 115 | + File known_hosts = temp.newFile("known_hosts"); |
| 116 | + FileWriter fileWriter = new FileWriter(known_hosts); |
| 117 | + BufferedWriter writer = new BufferedWriter(fileWriter); |
| 118 | + writer.write(line); |
| 119 | + writer.write("\r\n"); |
| 120 | + writer.flush(); |
| 121 | + writer.close(); |
| 122 | + return known_hosts; |
| 123 | + } |
| 124 | + |
| 125 | + |
| 126 | +} |
0 commit comments