| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you 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. |
| |
| |
| module Qpid::Proton |
| |
| # The SSL support for Transport. |
| # |
| # A Transport may be configured ot use SLL for encryption and/or |
| # authentication. A Transport can be configured as either the SSL |
| # client or the server. An SSL client is the party that proctively |
| # establishes a connection to an SSL server. An SSL server is the |
| # party that accepts a connection request from the remote SSL client. |
| # |
| # If either the client or the server needs to identify itself with the |
| # remote node, it must have its SSL certificate configured. |
| # |
| # @see SSLDomain#credentials For setting the SSL certificate. |
| # |
| # If either the client or the server needs to verify the identify of the |
| # remote node, it must have its database of trusted CAs configured. |
| # |
| # @see SSLDomain#trusted_ca_db Setting the CA database. |
| # |
| # An SSL server connection may allow the remote client to connect without |
| # SS (i.e., "in the clear"). |
| # |
| # @see SSLDomain#allow_unsecured_client Allowing unsecured clients. |
| # |
| # The level of verification required of the remote may be configured. |
| # |
| # @see SSLDomain#peer_authentication Setting peer authentication. |
| # |
| # Support for SSL client session resume is provided as well. |
| # |
| # @see SSLDomain |
| # @see #resume_status |
| # |
| class SSL |
| |
| # Session resume state is unkonnwn or not supported. |
| RESUME_UNKNOWN = Cproton::PN_SSL_RESUME_UNKNOWN |
| # Session renegotiated and not resumed. |
| RESUME_NEW = Cproton::PN_SSL_RESUME_NEW |
| # Session resumed from the previous session. |
| RESUME_REUSED = Cproton::PN_SSL_RESUME_REUSED |
| |
| # @private |
| PROTON_METHOD_PREFIX = "pn_ssl" |
| # @private |
| include Util::Wrapper |
| # @private |
| include Util::ErrorHandler |
| |
| # Returns whether SSL is supported. |
| # |
| # @return [Boolean] True if SSL support is available. |
| # |
| def self.present? |
| Cproton.pn_ssl_present |
| end |
| |
| # @private |
| def self.create(transport, domain, session_details = nil) |
| result = nil |
| # like python, make sure we're not creating a different SSL |
| # object for a transport with an existing SSL object |
| if transport.ssl? |
| transport.instance_eval { result = @ssl } |
| if ((!domain.nil? && (result.domain != domain)) || |
| (!session_details.nil? && (result.session_details != session_details))) |
| raise SSLException.new("cannot re-configure existing SSL object") |
| end |
| else |
| impl = Cproton.pn_ssl(transport.impl) |
| session_id = nil |
| session_id = session_details.session_id unless session_details.nil? |
| result = SSL.new(impl, domain, session_details, session_id) |
| end |
| return result |
| end |
| |
| private |
| |
| def initialize(impl, domain, session_details, session_id) |
| @impl = impl |
| @domain = domain.impl unless domain.nil? |
| @session_details = session_details |
| @session_id = session_id |
| Cproton.pn_ssl_init(@impl, @domain, @session_id) |
| end |
| |
| public |
| |
| # Returns the cipher name that is currently in used. |
| # |
| # Gets the text description of the cipher that is currently active, or |
| # returns nil if SSL is not active. Note that the cipher in use my change |
| # over time due to renegotiation or other changes to the SSL layer. |
| # |
| # @return [String, nil] The cipher name. |
| # |
| def cipher_name |
| rc, name = Cproton.pn_ssl_get_cipher_name(@impl, 128) |
| return name if rc |
| nil |
| end |
| |
| # Returns the name of the SSL protocol that is currently active, or |
| # returns nil if SSL is nota ctive. Not that the protocol may change over |
| # time due to renegotation. |
| # |
| # @return [String, nil] The protocol name. |
| # |
| def protocol_name |
| rc, name = Cproton.pn_ssl_get_protocol_name(@impl, 128) |
| name if rc |
| end |
| |
| # Checks whether or not the state has resumed. |
| # |
| # Used for client session resume. When called on an active session, it |
| # indicates wehther the state has been resumed from a previous session. |
| # |
| # *NOTE:* This is a best-effort service - there is no guarantee that the |
| # remote server will accept the resumed parameters. The remote server may |
| # choose to ignore these parameters, and request a renegotation instead. |
| # |
| def resume_status |
| Cproton.pn_ssl_resume_status(@impl) |
| end |
| |
| # Gets the peer hostname. |
| # |
| # @return [String] The peer hostname. |
| def peer_hostname |
| (error, name) = Cproton.pn_ssl_get_peer_hostname(@impl, 1024) |
| raise SSLError.new if error < 0 |
| return name |
| end |
| end |
| end |