summaryrefslogtreecommitdiff
path: root/test/integration/test_cert_host_auth.rb
blob: 312be855a578b2acc965fe160b484e05bd10d194 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
require_relative 'common'
require 'fileutils'
require 'tmpdir'
require 'net/ssh'

require 'timeout'

# see Vagrantfile,playbook for env.
# we're running as net_ssh_1 user password foo
# and usually connecting to net_ssh_2 user password foo2pwd
class TestCertHostAuth < NetSSHTest
  include IntegrationTestHelpers

  def setup_ssh_env(&block)
    tmpdir do |dir|
      @badcert = "#{dir}/badca"
      sh "rm -rf #{@badcert} #{@badcert}.pub"
      sh "ssh-keygen -t rsa -N '' -C 'ca@hosts.netssh' -f #{@badcert}"

      @cert = "#{dir}/ca"
      sh "rm -rf #{@cert} #{@cert}.pub"
      sh "ssh-keygen -t rsa -N '' -C 'ca@hosts.netssh' -f #{@cert}"
      FileUtils.cp "/etc/ssh/ssh_host_ecdsa_key.pub", "#{dir}/one.hosts.netssh.pub"
      Dir.chdir(dir) do
        sh "ssh-keygen -s #{@cert} -h -I one.hosts.netssh -n one.hosts.netssh #{dir}/one.hosts.netssh.pub"
        sh "ssh-keygen -L -f one.hosts.netssh-cert.pub"
      end
      # FileUtils.cp "#{dir}/cloud.jameshfisher.com-cert.pub", "/etc/ssh/ssh_host_ecdsa_key-cert.pub"
      sh "sudo cp -f #{dir}/one.hosts.netssh-cert.pub /etc/ssh/ssh_host_ecdsa_key-cert.pub"
      yield(cert_pub: "#{@cert}.pub", badcert_pub: "#{@badcert}.pub")
    end
  end

  def test_smoke
    config_lines = []
    config_lines.push("HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub")

    Tempfile.open('cert_kh') do |f|
      setup_ssh_env do |params|
        data = File.read(params[:cert_pub])
        puts "Data: #{data}"
        f.write("@cert-authority *.hosts.netssh #{data}")
        f.close

        start_sshd_7_or_later(config: config_lines, debug: true) do |_pid, port|
          Timeout.timeout(400) do
            # We have our own sshd, give it a chance to come up before
            # listening.
            ret = Net::SSH.start("one.hosts.netssh", "net_ssh_1", password: 'foopwd', port: port, verify_host_key: :always, user_known_hosts_file: [f.path], verbose: :debug) do |ssh|
              # assert_equal ssh.transport.algorithms.kex, "curve25519-sha256"
              ssh.exec! "echo 'foo'"
            end
            assert_equal "foo\n", ret
          rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH
            sleep 0.25
            retry
          end
        end
      end
    end
  end

  def test_failure
    config_lines = []
    config_lines.push("HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub")

    Tempfile.open('empty_kh') do |f|
      setup_ssh_env do |params|
        data = File.read(params[:badcert_pub])

        puts "Data: #{data}"
        f.write("@cert-authority *.hosts.netssh #{data}")
        f.close

        start_sshd_7_or_later(config: config_lines, debug: true) do |_pid, port|
          Timeout.timeout(400) do
            # sh "ssh net_ssh_1@one.hosts.netssh -p #{port} -o UserKnownHostsFile=#{f.path}"

            sleep 0.2
            assert_raises(Net::SSH::HostKeyMismatch) do
              Net::SSH.start("one.hosts.netssh", "net_ssh_1", password: 'foopwd', port: port, verify_host_key: :always, user_known_hosts_file: [f.path], verbose: :debug) do |ssh|
                # assert_equal ssh.transport.algorithms.kex, "curve25519-sha256"
                ssh.exec! "echo 'foo'"
              end
            end
          rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH
            sleep 0.25
            retry
          end
        end
      end
    end
  end
end