Skip to content

Commit

Permalink
Display SSL certificate import hints
Browse files Browse the repository at this point in the history
  • Loading branch information
lslezak committed Feb 20, 2019
1 parent 91fd728 commit a47341c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
20 changes: 8 additions & 12 deletions src/lib/registration/connect_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@
require "suse/connect"
require "ui/text_helpers"

require "registration/helpers"
require "registration/exceptions"
require "registration/storage"
require "registration/helpers"
require "registration/smt_status"
require "registration/ssl_certificate"
require "registration/ssl_certificate_details"
require "registration/url_helpers"
require "registration/ssl_error_codes"
require "registration/storage"
require "registration/ui/import_certificate_dialog"
require "registration/url_helpers"

module Registration
# FIXME: change to a module and include it in the clients
Expand All @@ -41,11 +42,6 @@ class ConnectHelpers
extend ::UI::TextHelpers
extend Yast::I18n

# openSSL error codes for which the import SSL certificate dialog is shown,
# for the other error codes just the error message is displayed
# (importing the certificate would not help)
IMPORT_ERROR_CODES = UI::ImportCertificateDialog::OPENSSL_ERROR_MESSAGES.keys

textdomain "registration"

Yast.import "Mode"
Expand Down Expand Up @@ -191,7 +187,7 @@ def self.handle_ssl_error(error, certificate_imported)
expected_cert_type = Storage::Config.instance.reg_server_cert_fingerprint_type

# in non-AutoYast mode ask the user to import the certificate
if !Yast::Mode.autoinst && cert && IMPORT_ERROR_CODES.include?(error_code)
if !Yast::Mode.autoinst && cert && SslErrorCodes::IMPORT_ERROR_CODES.include?(error_code)
# retry after successfull import
return true if ask_import_ssl_certificate(cert)
# in AutoYast mode check whether the certificate fingerprint match
Expand Down Expand Up @@ -219,10 +215,10 @@ def self.handle_ssl_error(error, certificate_imported)
false
end

def self.ssl_error_details(cert)
def self.ssl_error_details(cert, code)
return "" if cert.nil?

details = SslCertificateDetails.new(cert)
details = SslCertificateDetails.new(cert, code)
details.summary
end

Expand Down Expand Up @@ -282,7 +278,7 @@ def self.report_ssl_error(message, cert)
msg = url + ": " + msg # workaround after string freeze

Yast::Report.Error(
error_with_details(_("Secure connection error: %s") % msg, ssl_error_details(cert))
error_with_details(_("Secure connection error: %s") % msg, ssl_error_details(cert, error_code))
)
end

Expand Down
37 changes: 35 additions & 2 deletions src/lib/registration/ssl_certificate_details.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require "erb"

require "registration/ssl_certificate"
require "registration/ssl_error_codes"
require "registration/helpers"

module Registration
Expand All @@ -15,9 +16,11 @@ class SslCertificateDetails
# indent size used in summary text
INDENT = " " * 3

def initialize(certificate)
def initialize(certificate, error_code: nil)
Yast.import "Stage"
textdomain "registration"
@certificate = certificate
@error_code = error_code
end

def subject
Expand All @@ -44,6 +47,10 @@ def summary(small_space: false)
INDENT + sha256
end

if error_code == SslErrorCodes::NO_LOCAL_ISSUER_CERTIFICATE
summary += "\n\n" + import_hint
end

summary
end

Expand All @@ -53,7 +60,7 @@ def richtext_summary

private

attr_reader :certificate
attr_reader :certificate, :error_code

def identity_details(cn, o, ou)
# label followed by the SSL certificate identification
Expand All @@ -63,5 +70,31 @@ def identity_details(cn, o, ou)
# label followed by the SSL certificate identification
_("Organization Unit (OU): ") + (ou || "") + "\n"
end

def import_hint
# TRANSLATORS: use max. 70 chars per line,
# %{dir} is replaced by the certificate directory
# %{command} is replaced by the import command(s)
_("The issuer certificate cannot be found locally,\n" \
"it needs to be installed manually.\n\n" \
"Copy the certificate in PEM format to\n" \
"%{dir} directory.\n" \
"And then run commands: \n" \
"%{commands}") % { dir: "/etc/pki/trust/anchors", commands: import_commands }
end

def import_commands
# in the inst-sys we need to import the certificate manually,
# the update-ca-certificates script is missing
commands = if Yast::Stage.initial
["trust extract --format=openssl-directory --filter=ca-anchors \\\n" \
"--overwrite #{SslCertificate::TMP_CA_CERTS_DIR}",
"cp #{SslCertificate::TMP_CA_CERTS_DIR}/* #{SslCertificate::CA_CERTS_DIR}/openssl"]
else
["update-ca-certificates"]
end

commands.join("\n")
end
end
end
8 changes: 5 additions & 3 deletions src/lib/registration/ui/import_certificate_dialog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

require "registration/fingerprint"
require "registration/ssl_certificate_details"
require "registration/ssl_error_codes"

module Registration
module UI
Expand All @@ -17,14 +18,15 @@ class ImportCertificateDialog

# error code => translatable error message
# @see https://www.openssl.org/docs/apps/verify.html
# @see https://github.com/openssl/openssl/blob/2c75f03b39de2fa7d006bc0f0d7c58235a54d9bb/include/openssl/x509_vfy.h#L99-L189
# @note the text messages need to be translated at runtime via _() call
OPENSSL_ERROR_MESSAGES = {
# SSL error message
10 => N_("Certificate has expired"),
SslErrorCodes::EXPIRED => N_("Certificate has expired"),
# SSL error message
18 => N_("Self signed certificate"),
SslErrorCodes::SELF_SIGNED_CERT => N_("Self signed certificate"),
# SSL error message
19 => N_("Self signed certificate in certificate chain")
SslErrorCodes::SELF_SIGNED_CERT_IN_CHAIN => N_("Self signed certificate in certificate chain")
}.freeze

Yast.import "UI"
Expand Down

0 comments on commit a47341c

Please sign in to comment.