From dbab46d5f8228f8dd56bbca2e63405e818c598f9 Mon Sep 17 00:00:00 2001 From: Saku Ytti Date: Mon, 29 Aug 2016 14:27:57 +0300 Subject: support terminal and ssh auth for same model Some boxes like prokurwa may authenticate via SSH (proper), or may have no auth on SSH and use terminal auth (improper) Even if SSH is configured for terminal auth, in this change we attempt to detect prompt, so that we won't expect terminal auth, even when requested, if it is not presented. --- lib/oxidized/input/ssh.rb | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'lib/oxidized/input/ssh.rb') diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb index cd12167..c0b7cf9 100644 --- a/lib/oxidized/input/ssh.rb +++ b/lib/oxidized/input/ssh.rb @@ -42,7 +42,7 @@ module Oxidized unless @exec shell_open @ssh begin - @username ? shell_login : expect(@node.prompt) + login rescue Timeout::Error raise PromptUndetect, [ @output, 'not matching configured prompt', @node.prompt ].join(' ') end @@ -102,13 +102,18 @@ module Oxidized end end - # Cisco WCS has extremely dubious SSH implementation, SSH auth is always - # success, it always opens shell and then run auth in shell. I guess - # they'll never support exec() :) - def shell_login - expect username - cmd @node.auth[:username], password - cmd @node.auth[:password] + # some models have SSH auth or terminal auth based on version of code + # if SSH is configured for terminal auth, we'll still try to detect prompt + def login + if @username + match = expect username, @node.prompt + if match == username + cmd @node.auth[:username], password + cmd @node.auth[:password] + end + else + expect @node.prompt + end end def exec state=nil @@ -123,14 +128,18 @@ module Oxidized @output end - def expect regexp - Oxidized.logger.debug "lib/oxidized/input/ssh.rb: expecting #{regexp.inspect} at #{node.name}" + def expect *regexps + regexps = [regexps].flatten + Oxidized.logger.debug "lib/oxidized/input/ssh.rb: expecting #{regexps.inspect} at #{node.name}" Timeout::timeout(Oxidized.config.timeout) do @ssh.loop(0.1) do sleep 0.1 - not @output.match regexp + match = regexps.find { |regexp| @output.match regexp } + return match if match + true end end end + end end -- cgit v1.2.1 From 22755169b513ebde33de2704afd2f7a0b366723a Mon Sep 17 00:00:00 2001 From: Denver Abrey Date: Thu, 13 Oct 2016 22:00:33 +0200 Subject: Add key authentication to ssh input --- lib/oxidized/input/ssh.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/oxidized/input/ssh.rb') diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb index c0b7cf9..32f4e40 100644 --- a/lib/oxidized/input/ssh.rb +++ b/lib/oxidized/input/ssh.rb @@ -23,6 +23,7 @@ module Oxidized secure = Oxidized.config.input.ssh.secure @log = File.open(Oxidized::Config::Log + "/#{@node.ip}-ssh", 'w') if Oxidized.config.input.debug? port = vars(:ssh_port) || 22 + keys = node.auth[:private_key].is_a?(Array) ? @node.auth[:private_key] : [@node.auth[:private_key]] if proxy_host = vars(:ssh_proxy) proxy = Net::SSH::Proxy::Command.new("ssh #{proxy_host} -W %h:%p") end @@ -32,7 +33,8 @@ module Oxidized :paranoid => secure, :auth_methods => %w(none publickey password keyboard-interactive), :number_of_password_prompts => 0, - :proxy => proxy + :proxy => proxy, + :keys => keys } ssh_opts[:kex] = vars(:ssh_kex).split(/,\s*/) if vars(:ssh_kex) ssh_opts[:encryption] = vars(:ssh_encryption).split(/,\s*/) if vars(:ssh_encryption) -- cgit v1.2.1 From 75534fa493013a5e563877ffc05eca6f4372999c Mon Sep 17 00:00:00 2001 From: Denver Abrey Date: Mon, 17 Oct 2016 20:42:10 +0200 Subject: Use variable vars(:ssh_keys) for private key authentication --- lib/oxidized/input/ssh.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib/oxidized/input/ssh.rb') diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb index 32f4e40..15f1427 100644 --- a/lib/oxidized/input/ssh.rb +++ b/lib/oxidized/input/ssh.rb @@ -23,7 +23,6 @@ module Oxidized secure = Oxidized.config.input.ssh.secure @log = File.open(Oxidized::Config::Log + "/#{@node.ip}-ssh", 'w') if Oxidized.config.input.debug? port = vars(:ssh_port) || 22 - keys = node.auth[:private_key].is_a?(Array) ? @node.auth[:private_key] : [@node.auth[:private_key]] if proxy_host = vars(:ssh_proxy) proxy = Net::SSH::Proxy::Command.new("ssh #{proxy_host} -W %h:%p") end @@ -34,9 +33,9 @@ module Oxidized :auth_methods => %w(none publickey password keyboard-interactive), :number_of_password_prompts => 0, :proxy => proxy, - :keys => keys } - ssh_opts[:kex] = vars(:ssh_kex).split(/,\s*/) if vars(:ssh_kex) + ssh_opts[:keys] = vars(:ssh_keys).is_a?(Array) ? vars(:ssh_keys) : [vars(:ssh_keys)] if vars(:ssh_keys) + ssh_opts[:kex] = vars(:ssh_kex).split(/,\s*/) if vars(:ssh_kex) ssh_opts[:encryption] = vars(:ssh_encryption).split(/,\s*/) if vars(:ssh_encryption) Oxidized.logger.debug "lib/oxidized/input/ssh.rb: Connecting to #{@node.name}" -- cgit v1.2.1 From 98ee2d2fadd56b9efadfc4f9ff667f71f6b22f6c Mon Sep 17 00:00:00 2001 From: Saku Ytti Date: Mon, 31 Oct 2016 17:54:47 +0200 Subject: Allow model to specify SSH PTY options --- lib/oxidized/input/ssh.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/oxidized/input/ssh.rb') diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb index 15f1427..30b481d 100644 --- a/lib/oxidized/input/ssh.rb +++ b/lib/oxidized/input/ssh.rb @@ -17,8 +17,9 @@ module Oxidized class NoShell < OxidizedError; end def connect node - @node = node - @output = '' + @node = node + @output = '' + @pty_options = { term: "vt100" } @node.model.cfg['ssh'].each { |cb| instance_exec(&cb) } secure = Oxidized.config.input.ssh.secure @log = File.open(Oxidized::Config::Log + "/#{@node.ip}-ssh", 'w') if Oxidized.config.input.debug? @@ -74,6 +75,10 @@ module Oxidized private + def pty_options hash + @pty_options = @pty_options.merge hash + end + def disconnect disconnect_cli # if disconnect does not disconnect us, give up after timeout @@ -94,7 +99,7 @@ module Oxidized @output << data @output = @node.model.expects @output end - ch.request_pty (_opts={:term=>'vt100'}) do |_ch, success_pty| + ch.request_pty (@pty_options) do |_ch, success_pty| raise NoShell, "Can't get PTY" unless success_pty ch.send_channel_request 'shell' do |_ch, success_shell| raise NoShell, "Can't get shell" unless success_shell -- cgit v1.2.1 From a87fc34a84a893b86d5ccb401d3bd4b9e544bfc2 Mon Sep 17 00:00:00 2001 From: Saku Ytti Date: Mon, 31 Oct 2016 17:56:37 +0200 Subject: it shouldn't be a private method --- lib/oxidized/input/ssh.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/oxidized/input/ssh.rb') diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb index 30b481d..9a5c508 100644 --- a/lib/oxidized/input/ssh.rb +++ b/lib/oxidized/input/ssh.rb @@ -73,12 +73,12 @@ module Oxidized @output end - private - def pty_options hash @pty_options = @pty_options.merge hash end + private + def disconnect disconnect_cli # if disconnect does not disconnect us, give up after timeout -- cgit v1.2.1