lib/oneview-sdk/ssl_helper.rb
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
#
# Licensed under the Apache License, Version 2.0 (the "License");
# You may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
require 'addressable'
require 'uri'
require 'net/http'
require 'openssl'
module OneviewSDK
# SSL certificate helper
module SSLHelper
CERT_STORE = File.join(Dir.home, '/.oneview-sdk-ruby/trusted_certs.cer')
# Load any trusted certs and add them to the default SSL cert store.
# Looks for a file at ~/.oneview-sdk-ruby/trusted_certs.cer
# Note: File must be readable and parseable by X509::Store.add_file method
# @return [X509::Store] cert_store
def self.load_trusted_certs
store = OpenSSL::X509::Store.new
store.set_default_paths
begin
store.add_file(CERT_STORE) if File.file?(CERT_STORE)
rescue StandardError => e
puts "WARNING: Failed to load certificate store file at #{CERT_STORE} \n Message: #{e.message}"
end
store
rescue StandardError => e
puts "WARNING: Failure in #{self}##{__method__} \n Message: #{e.message}"
nil
end
# Check to see if the OneView instance's certificate is trusted
# @param [String] url URL for the OneView Instance to be added
# @return [Boolean] Whether or not certificate is trusted
# @raise [OneviewSDK::InvalidURL] if the url is invalid
def self.check_cert(url)
uri = URI.parse(Addressable::URI.escape(url))
raise InvalidURL, "Invalid url '#{url}'" unless uri.host
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == 'https'
trusted_certs = load_trusted_certs
http.cert_store = trusted_certs if trusted_certs
http.request(Net::HTTP::Get.new(uri.request_uri))
true
rescue OpenSSL::SSL::SSLError
false
end
# Fetch and add the SSL certificate for the OneView instance to the trusted certs store.
# Creates/modifies file at ~/.oneview-sdk-ruby/trusted_certs.cer
# @param [String] url URL for the OneView Instance to be added
# @raise [OneviewSDK::InvalidURL] if the url is invalid
def self.install_cert(url)
uri = URI.parse(Addressable::URI.escape(url))
raise InvalidURL, "Invalid url '#{url}'" unless uri.host
options = { use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE }
pem = Net::HTTP.start(uri.host, uri.port, options) do |http|
http.peer_cert.to_pem
end
raise "Could not download cert from #{url}. You may have to do it manually, and append it to '#{CERT_STORE}'" if pem.nil?
name = "OneView at #{url}"
content = "\n#{name}\n"
content << "#{'=' * name.length}\n"
content << pem
cert_dir = File.dirname(CERT_STORE)
Dir.mkdir(cert_dir) unless File.directory?(cert_dir)
if File.file?(CERT_STORE) && File.read(CERT_STORE).include?(pem)
puts 'Cert store already contains this certificate. Skipped!'
false
else
File.open(CERT_STORE, 'a') { |f| f.write content }
puts "Cert added to '#{CERT_STORE}'. Cert Info: #{content}"
true
end
end
end
end