Class: Registration::ConnectHelpers

Inherits:
Object
  • Object
show all
Extended by:
Yast::I18n
Includes:
Yast::Logger
Defined in:
src/lib/registration/connect_helpers.rb

Overview

FIXME: change to a module and include it in the clients

Constant Summary collapse

IMPORT_ERROR_CODES =

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)

UI::ImportCertificateDialog::OPENSSL_ERROR_MESSAGES.keys

Class Method Summary collapse

Class Method Details

.ask_import_ssl_certificate(cert) ⇒ Object


200
201
202
203
204
205
206
207
208
# File 'src/lib/registration/connect_helpers.rb', line 200

def self.ask_import_ssl_certificate(cert)
  # run the import dialog, check the user selection
  if UI::ImportCertificateDialog.run(cert) != :import
    log.info "Certificate import rejected"
    return false
  end

  import_ssl_certificate(cert)
end

.catch_registration_errors(message_prefix: "", show_update_hint: false, &block) ⇒ Boolean

Call a block, rescuing various exceptions including StandardError. Return a boolean success value instead.


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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'src/lib/registration/connect_helpers.rb', line 60

def self.catch_registration_errors(message_prefix: "", show_update_hint: false, &block)
  # import the SSL certificate just once to avoid an infinite loop
  certificate_imported = false
  begin
    # reset the previous SSL errors
    Storage::SSLErrors.instance.reset

    block.call

    true
  rescue SocketError, Errno::ENETUNREACH => e
    log.error "Network error: #{e.class}: #{e.message}"
    handle_network_error(message_prefix, e)
    false
  rescue Timeout::Error
    # Error popup
    Yast::Report.Error(_("Connection time out."))
    false
  rescue SUSE::Connect::ApiError => e
    log.error "Received error: #{e.response.inspect}"
    case e.code
    when 401
      if show_update_hint
        # TRANSLATORS: additional hint for an error message
        msg = _("Check that this system is known to the registration server.")

        # probably missing NCC->SCC sync, display a hint unless SMT is used
        if UrlHelpers.registration_url == SUSE::Connect::YaST::DEFAULT_URL
          msg += "\n\n"
          # TRANSLATORS: additional hint for an error message
          msg += _("If you are upgrading from SLE11 make sure the SCC server\n" \
              "knows the old NCC registration. Synchronization from NCC to SCC\n" \
              "might take very long time.\n\n" \
              "If the SLE11 system was installed recently you could log into\n" \
              "%s to speed up the synchronization process.\n" \
              "Just wait several minutes after logging in and then retry \n" \
              "the upgrade again.") % \
            SUSE::Connect::YaST::DEFAULT_URL
        end

        # add the hint to the error details
        e.message << "\n\n\n" + msg
      end

      report_error(message_prefix + _("Connection to registration server failed."), e)
    when 404
      # update the message when an old SMT server is found
      check_smt_api(e)

      report_error(message_prefix + _("Connection to registration server failed."), e)
    when 422
      # Error popup
      report_error(message_prefix + _("Connection to registration server failed."), e)
    when 400..499
      report_error(message_prefix + _("Registration client error."), e)
    when 500..599
      report_error(message_prefix + _("Registration server error.\n" \
            "Retry the operation later."), e)
    else
      report_error(message_prefix + _("Connection to registration server failed."), e)
    end
    false
  rescue ::Registration::ServiceError => e
    log.error("Service error: #{e.message % e.service}")
    Yast::Report.Error(_(e.message) % e.service)
    false
  rescue ::Registration::PkgError => e
    log.error("Pkg error: #{e.message}")
    Yast::Report.Error(_(e.message))
    false
  rescue OpenSSL::SSL::SSLError => e
    log.error "OpenSSL error: #{e}"

    cert = Storage::SSLErrors.instance.ssl_failed_cert
    error_code = Storage::SSLErrors.instance.ssl_error_code
    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)
      # retry after successfull import
      retry if ask_import_ssl_certificate(cert)
      # in AutoYast mode check whether the certificate fingerprint match
      # the configured value (if present)
    elsif Yast::Mode.autoinst && cert && expected_cert_type && !expected_cert_type.empty?
      expected_fingerprint = Fingerprint.new(expected_cert_type,
        Storage::Config.instance.reg_server_cert_fingerprint)

      if cert.fingerprint(expected_cert_type) == expected_fingerprint
        # import the certificate and retry (just once)
        if !certificate_imported
          import_ssl_certificate(cert)
          certificate_imported = true
          retry
        end

        report_ssl_error(e.message, cert)
      else
        # error message
        Yast::Report.Error(_("Received SSL Certificate does not match " \
              "the expected certificate."))
      end
    else
      report_ssl_error(e.message, cert)
    end

    false
  rescue JSON::ParserError => e
    # update the message when an old SMT server is found
    check_smt_api(e)

    report_error(message_prefix + _("Connection to registration server failed."), e)
  rescue StandardError => e
    log.error("SCC registration failed: #{e.class}: #{e}, #{e.backtrace}")
    Yast::Report.Error(
      error_with_details(_("Connection to registration server failed."), e.message)
    )
    false
  end
end