класс OpenSSL::SSL::SSLSocket
Следующие атрибуты доступны, но не отображаются в rdoc.
-
io, context, sync_close
Открытые методы класса
static VALUE
ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE io, ctx;
if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) {
ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
}
OSSL_Check_Kind(ctx, cSSLContext);
Check_Type(io, T_FILE);
ossl_ssl_set_io(self, io);
ossl_ssl_set_ctx(self, ctx);
ossl_ssl_set_sync_close(self, Qfalse);
ossl_sslctx_setup(ctx);
rb_iv_set(self, "@hostname", Qnil);
rb_call_super(0, 0);
return self;
} Создает новый сокет SSL из io, который должен быть реальным объектом Ruby (а не объектом, похожим на IO, который отвечает на read/write).
Если ctx предоставлен, начальные параметры сокета SSL будут взяты из контекста.
Модуль OpenSSL::Buffering предоставляет дополнительные методы IO.
Этот метод заморозит SSLContext, если он предоставлен; однако управление сеансами все еще разрешено в замороженном SSLContext.
Открытые методы экземпляра
static VALUE
ossl_ssl_accept(VALUE self)
{
ossl_ssl_setup(self);
return ossl_start_ssl(self, SSL_accept, "SSL_accept", 0);
} Ожидает инициации рукопожатия клиентом SSL/TLS. Рукопожатие может быть начато после отправки данных без шифрования по сокету.
static VALUE
ossl_ssl_accept_nonblock(VALUE self)
{
ossl_ssl_setup(self);
return ossl_start_ssl(self, SSL_accept, "SSL_accept", 1);
} Инициирует рукопожатие SSL/TLS как сервер в режиме, не блокирующем выполнение.
# emulates blocking accept begin ssl.accept_nonblock rescue IO::WaitReadable IO.select([s2]) retry rescue IO::WaitWritable IO.select(nil, [s2]) retry end
static VALUE
ossl_ssl_get_cert(VALUE self)
{
SSL *ssl;
X509 *cert = NULL;
ossl_ssl_data_get_struct(self, ssl);
/*
* Is this OpenSSL bug? Should add a ref?
* TODO: Ask for.
*/
cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */
if (!cert) {
return Qnil;
}
return ossl_x509_new(cert);
} Сертификат X509 для конечной точки этого сокета.
static VALUE
ossl_ssl_get_cipher(VALUE self)
{
SSL *ssl;
SSL_CIPHER *cipher;
ossl_ssl_data_get_struct(self, ssl);
cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);
return ossl_ssl_cipher_to_ary(cipher);
} Шифр, используемый для текущего соединения.
static VALUE
ossl_ssl_get_client_ca_list(VALUE self)
{
SSL *ssl;
STACK_OF(X509_NAME) *ca;
ossl_ssl_data_get_struct(self, ssl);
ca = SSL_get_client_CA_list(ssl);
return ossl_x509name_sk2ary(ca);
} Возвращает список доверенных центров сертификации (ЦС). Обратите внимание, что в отличие от OpenSSL::SSL::SSLContext#client_ca возвращается не массив объектов X509::Certificate, а объекты X509::Name содержащие DN (Distinguished Name) ЦС.
В серверном режиме возвращает список, заданный с помощью OpenSSL::SSL::SSLContext#client_ca. В клиенском режиме возвращает список ЦС, отправленных сервером.
static VALUE
ossl_ssl_connect(VALUE self)
{
ossl_ssl_setup(self);
return ossl_start_ssl(self, SSL_connect, "SSL_connect", 0);
} Инициирует рукопожатие SSL/TLS с сервером. Рукопожатие может быть начато после отправки данных без шифрования по сокету.
static VALUE
ossl_ssl_connect_nonblock(VALUE self)
{
ossl_ssl_setup(self);
return ossl_start_ssl(self, SSL_connect, "SSL_connect", 1);
} Инициирует рукопожатие SSL/TLS как клиент в режиме, не блокирующем выполнение.
# emulates blocking connect begin ssl.connect_nonblock rescue IO::WaitReadable IO.select([s2]) retry rescue IO::WaitWritable IO.select(nil, [s2]) retry end
static VALUE
ossl_ssl_npn_protocol(VALUE self)
{
SSL *ssl;
const unsigned char *out;
unsigned int outlen;
ossl_ssl_data_get_struct(self, ssl);
SSL_get0_next_proto_negotiated(ssl, &out, &outlen);
if (!outlen)
return Qnil;
else
return rb_str_new((const char *) out, outlen);
} Возвращает строку протокола, окончательно выбранную клиентом во время рукопожатия.
static VALUE
ossl_ssl_get_peer_cert(VALUE self)
{
SSL *ssl;
X509 *cert = NULL;
VALUE obj;
ossl_ssl_data_get_struct(self, ssl);
cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */
if (!cert) {
return Qnil;
}
obj = ossl_x509_new(cert);
X509_free(cert);
return obj;
} Сертификат X509 для удалённой стороны сокета.
static VALUE
ossl_ssl_get_peer_cert_chain(VALUE self)
{
SSL *ssl;
STACK_OF(X509) *chain;
X509 *cert;
VALUE ary;
int i, num;
ossl_ssl_data_get_struct(self, ssl);
chain = SSL_get_peer_cert_chain(ssl);
if(!chain) return Qnil;
num = sk_X509_num(chain);
ary = rb_ary_new2(num);
for (i = 0; i < num; i++){
cert = sk_X509_value(chain, i);
rb_ary_push(ary, ossl_x509_new(cert));
}
return ary;
} Цепочка сертификатов X509 для удалённой стороны сокета.
static VALUE
ossl_ssl_pending(VALUE self)
{
SSL *ssl;
ossl_ssl_data_get_struct(self, ssl);
return INT2NUM(SSL_pending(ssl));
} Количество байтов, немедленно доступных для чтения.
# File ext/openssl/lib/openssl/ssl.rb, line 230
def post_connection_check(hostname)
if peer_cert.nil?
msg = "Peer verification enabled, but no certificate received."
if using_anon_cipher?
msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification."
end
raise SSLError, msg
end
unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)
raise SSLError, "hostname \"#{hostname}\" does not match the server certificate"
end
return true
end Выполнение проверки имени хоста после установления соединения SSL.
Этот метод ОБЯЗАТЕЛЬНО должен вызываться после вызова connect для обеспечения проверки имени хоста удалённой стороны.
# File ext/openssl/lib/openssl/ssl.rb, line 245 def session SSL::Session.new(self) rescue SSL::Session::SessionError nil end
static VALUE
ossl_ssl_set_session(VALUE self, VALUE arg1)
{
SSL *ssl;
SSL_SESSION *sess;
/* why is ossl_ssl_setup delayed? */
ossl_ssl_setup(self);
ossl_ssl_data_get_struct(self, ssl);
SafeGetSSLSession(arg1, sess);
if (SSL_set_session(ssl, sess) != 1)
ossl_raise(eSSLError, "SSL_set_session");
return arg1;
} Устанавливает Сеанс, который будет использоваться при установлении соединения.
static VALUE
ossl_ssl_session_reused(VALUE self)
{
SSL *ssl;
ossl_ssl_data_get_struct(self, ssl);
switch(SSL_session_reused(ssl)) {
case 1: return Qtrue;
case 0: return Qfalse;
default: ossl_raise(eSSLError, "SSL_session_reused");
}
UNREACHABLE;
} Возвращает true, если во время рукопожатия был выбран повторно используемый сеанс.
static VALUE
ossl_ssl_get_version(VALUE self)
{
SSL *ssl;
ossl_ssl_data_get_struct(self, ssl);
return rb_str_new2(SSL_get_version(ssl));
} Возвращает строку, представляющую версию SSL/TLS, согласованную для соединения, например «TLSv1.2».
static VALUE
ossl_ssl_get_state(VALUE self)
{
SSL *ssl;
VALUE ret;
ossl_ssl_data_get_struct(self, ssl);
ret = rb_str_new2(SSL_state_string(ssl));
if (ruby_verbose) {
rb_str_cat2(ret, ": ");
rb_str_cat2(ret, SSL_state_string_long(ssl));
}
return ret;
} Описание текущего состояния соединения.
static VALUE
ossl_ssl_close(VALUE self)
{
SSL *ssl;
VALUE io;
/* ossl_ssl_data_get_struct() is not usable here because it may return
* from this function; */
GetSSL(self, ssl);
io = ossl_ssl_get_io(self);
if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) {
if (ssl) {
ossl_ssl_shutdown(ssl);
SSL_free(ssl);
}
DATA_PTR(self) = NULL;
if (RTEST(ossl_ssl_get_sync_close(self)))
rb_funcall(io, rb_intern("close"), 0);
}
return Qnil;
} Закрывает соединение SSL и подготавливает его к новому соединению.
static VALUE
ossl_ssl_read(int argc, VALUE *argv, VALUE self)
{
return ossl_ssl_read_internal(argc, argv, self, 0);
} Читает length байта из соединения SSL. Если предоставлен предварительно выделенный buffer, данные будут записаны в него.
static VALUE
ossl_ssl_write(VALUE self, VALUE str)
{
return ossl_ssl_write_internal(self, str, 0, 0);
} Записывает string в соединение SSL.
static VALUE
ossl_ssl_get_verify_result(VALUE self)
{
SSL *ssl;
ossl_ssl_data_get_struct(self, ssl);
return INT2FIX(SSL_get_verify_result(ssl));
} Возвращает результат проверки сертификатов удалённой стороны. Обратитесь к справке verify(1) для значений ошибок и их описаний.
Если сертификат удалённой стороны не был представлен, возвращается X509_V_OK.
Приватные методы экземпляра
static VALUE
ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
{
return ossl_ssl_read_internal(argc, argv, self, 1);
} Неблокирующая версия sysread. Вызывает SSLError, если чтение заблокирует процесс. Если передано «exception: false», этот метод возвращает символ :wait_readable, :wait_writable или nil вместо исключения.
Читает length байтов из соединения SSL. Если предоставлен предварительно выделенный buffer, данные будут записаны в него.
static VALUE
ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self)
{
VALUE str;
VALUE opts = Qnil;
int no_exception = 0;
rb_scan_args(argc, argv, "1:", &str, &opts);
if (!NIL_P(opts) && Qfalse == rb_hash_aref(opts, sym_exception))
no_exception = 1;
return ossl_ssl_write_internal(self, str, 1, no_exception);
} Записывает string в соединение SSL в неблокирующем режиме. Вызывает SSLError, если запись заблокирует процесс.
# File ext/openssl/lib/openssl/ssl.rb, line 253 def using_anon_cipher? ctx = OpenSSL::SSL::SSLContext.new ctx.ciphers = "aNULL" ctx.ciphers.include?(cipher) end
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.