Как я могу записать команду командной строки / linux в моем приложении rails и сохранить результат в переменной? - PullRequest
0 голосов
/ 10 марта 2020

В моем коде rails у меня есть следующий код, который необходимо выполнить в приложении rails. Обычно вы запускаете это в командной строке. Ее код определен:

COMMAND=->(url, port){%x"echo QUIT | openssl s_client -CApath /etc/ssl/certs/ -quiet -no_ign_eof -servername #{url} -verify_hostname #{url} -connect #{url}:#{port}"}

В приложении мне нужно выполнить это:

Model::COMMAND.call('website.com',443)

«Официальный» вывод команды - пустая строка. Тем не менее, я вижу следующее:

[53] pry(main)> SiteCheck::COMMAND.call('website.com',443)
depth=0 C = US, ST = States, L = Somewhere, O =Corp, serialNumber = 123456789, CN = www.website.com, postalCode = 12345, businessCategory = Private Organization, street = JFK Random Street, jurisdictionST = Nevada, jurisdictionC = US
verify error:num=62:Hostname mismatch
verify return:1
depth=3 C = PL, O = Unizeto Technologies S.A., OU = Certum Certification Authority, CN = Certum Trusted Network CA
verify return:1
depth=2 C = US, ST = States, L = Somewhere, O = Corporation, CN = EV Root Certification Authority RSA R2
verify return:1
depth=1 C = US, ST = States, L = Somewhere, O = Corp, CN = EV SSL Intermediate CA RSA R3
verify return:1
depth=0 C = US, ST = States, L = Somewhere, O = Corp, serialNumber = 123456789, CN = www.website.com, postalCode = 12345, businessCategory = Private Organization, street = JFK Random Street, jurisdictionST = Nevada, jurisdictionC = US

verify return:1
DONE
=> ""

Что мне особенно нужно, это verify error: num=62 Hostname mismatch часть. Как я могу захватить это? Я пытался использовать pop3, но моя проблема в том, что возвращаемое значение - пустая строка, поэтому в некотором смысле я получаю возвращаемый результат, но не то, что мне нужно. Есть ли способ, которым я могу захватить это в ruby?

1 Ответ

1 голос
/ 10 марта 2020

Этот вывод отправляется в stderr. Вы можете использовать Open3.capture3:

require 'open3'

stdin, stderr = Open3.capture3(
  "openssl s_client -CApath /etc/ssl/certs/ -quiet -no_ign_eof -servername #{url} -verify_hostname #{url} -connect #{url}:#{port}",
  stdin_data:'QUIT'
)

Кроме того, вместо порождения процесса - вы можете попробовать инициировать это соединение из ruby:

require 'openssl'
require 'socket'

def ssl_connect_verify(host, port)
  context = OpenSSL::SSL::SSLContext.new
  context.ca_file = '/usr/local/etc/openssl@1.1/cert.pem' # this is for mac, your path may differ
  context.verify_mode = OpenSSL::SSL::VERIFY_PEER

  tcp_client = TCPSocket.new host, port
  ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client, context)
  ssl_client.hostname = host # SNI
  ssl_client.connect

  if (san_ext = ssl_client.peer_cert.extensions.select{|e| e.oid == 'subjectAltName' }.first)
    dns_names = san_ext.value.split(/,\s*/).map{|s| s.delete_prefix "DNS:"}
    unless dns_names.any?{|san| OpenSSL::SSL.verify_hostname(host, san)}
      raise "Cannot verify hostname..."
    end
  end

  ssl_client.peer_cert_chain.map{|cert|
    # cert is a OpenSSL::X509::Certificate, see documentation on its fields
    cert.subject.to_s
  }
rescue OpenSSL::SSL::SSLError => e
  # check for error message etc.
  puts "Cannot connect: #{e.to_s}"
  return []
ensure
  ssl_client.close
end


puts ssl_connect_verify('google.com', 443).join("\n")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...