diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/openssl/lib/openssl/ssl.rb | 84 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.c | 106 | ||||
-rw-r--r-- | ext/tk/lib/tk.rb | 13 | ||||
-rw-r--r-- | ext/tk/lib/tk/scale.rb | 13 | ||||
-rw-r--r-- | ext/tk/lib/tk/scrollbar.rb | 13 | ||||
-rw-r--r-- | ext/tk/lib/tkextlib/blt/ted.rb | 2 | ||||
-rw-r--r-- | ext/tk/lib/tkextlib/blt/unix_dnd.rb | 6 | ||||
-rw-r--r-- | ext/tk/lib/tkextlib/treectrl/tktreectrl.rb | 8 | ||||
-rw-r--r-- | ext/tk/lib/tkextlib/version.rb | 2 | ||||
-rw-r--r-- | ext/tk/sample/ttk_wrapper.rb | 4 |
10 files changed, 175 insertions, 76 deletions
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb index ad9559f6b6..f722cb0c45 100644 --- a/ext/openssl/lib/openssl/ssl.rb +++ b/ext/openssl/lib/openssl/ssl.rb @@ -20,6 +20,33 @@ require "fcntl" module OpenSSL module SSL + class SSLContext + DEFAULT_PARAMS = { + :ssl_version => "SSLv23", + :verify_mode => OpenSSL::SSL::VERIFY_PEER, + :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW", + :options => OpenSSL::SSL::OP_ALL, + } + + DEFAULT_CERT_STORE = OpenSSL::X509::Store.new + DEFAULT_CERT_STORE.set_default_paths + if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL) + DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL + end + + def set_params(params={}) + params = DEFAULT_PARAMS.merge(params) + self.ssl_version = params.delete(:ssl_version) + params.each{|name, value| self.__send__("#{name}=", value) } + if self.verify_mode != OpenSSL::SSL::VERIFY_NONE + unless self.ca_file or self.ca_path or self.cert_store + self.cert_store = DEFAULT_CERT_STORE + end + end + return params + end + end + module SocketForwarder def addr to_io.addr @@ -59,36 +86,43 @@ module OpenSSL end end + def verify_certificate_identity(cert, hostname) + should_verify_common_name = true + cert.extensions.each{|ext| + next if ext.oid != "subjectAltName" + ext.value.split(/,\s+/).each{|general_name| + if /\ADNS:(.*)/ =~ general_name + should_verify_common_name = false + reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+") + return true if /\A#{reg}\z/i =~ hostname + elsif /\AIP Address:(.*)/ =~ general_name + should_verify_common_name = false + return true if $1 == hostname + end + } + } + if should_verify_common_name + cert.subject.to_a.each{|oid, value| + if oid == "CN" + reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") + return true if /\A#{reg}\z/i =~ hostname + end + } + end + return false + end + module_function :verify_certificate_identity + class SSLSocket include Buffering include SocketForwarder include Nonblock def post_connection_check(hostname) - check_common_name = true - cert = peer_cert - cert.extensions.each{|ext| - next if ext.oid != "subjectAltName" - ext.value.split(/,\s+/).each{|general_name| - if /\ADNS:(.*)/ =~ general_name - check_common_name = false - reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+") - return true if /\A#{reg}\z/i =~ hostname - elsif /\AIP Address:(.*)/ =~ general_name - check_common_name = false - return true if $1 == hostname - end - } - } - if check_common_name - cert.subject.to_a.each{|oid, value| - if oid == "CN" - reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") - return true if /\A#{reg}\z/i =~ hostname - end - } + unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) + raise SSLError, "hostname was not match with the server certificate" end - raise SSLError, "hostname was not match with the server certificate" + return true end def session @@ -120,6 +154,10 @@ module OpenSSL @svr.listen(backlog) end + def shutdown(how=Socket::SHUT_RDWR) + @svr.shutdown(how) + end + def accept sock = @svr.accept begin diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 98c374b95f..675fe657b0 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -141,31 +141,14 @@ ossl_sslctx_s_alloc(VALUE klass) return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx); } -/* - * call-seq: - * SSLContext.new => ctx - * SSLContext.new(:TLSv1) => ctx - * SSLContext.new("SSLv23_client") => ctx - * - * You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS - */ static VALUE -ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self) +ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method) { - VALUE ssl_method; SSL_METHOD *method = NULL; - SSL_CTX *ctx; - int i; const char *s; + int i; - for(i = 0; i < numberof(ossl_sslctx_attrs); i++){ - char buf[32]; - snprintf(buf, sizeof(buf), "@%s", ossl_sslctx_attrs[i]); - rb_iv_set(self, buf, Qnil); - } - if (rb_scan_args(argc, argv, "01", &ssl_method) == 0){ - return self; - } + SSL_CTX *ctx; if(TYPE(ssl_method) == T_SYMBOL) s = rb_id2name(SYM2ID(ssl_method)); else @@ -184,6 +167,33 @@ ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self) ossl_raise(eSSLError, "SSL_CTX_set_ssl_version:"); } + return ssl_method; +} + +/* + * call-seq: + * SSLContext.new => ctx + * SSLContext.new(:TLSv1) => ctx + * SSLContext.new("SSLv23_client") => ctx + * + * You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS + */ +static VALUE +ossl_sslctx_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE ssl_method; + int i; + + for(i = 0; i < numberof(ossl_sslctx_attrs); i++){ + char buf[32]; + snprintf(buf, sizeof(buf), "@%s", ossl_sslctx_attrs[i]); + rb_iv_set(self, buf, Qnil); + } + if (rb_scan_args(argc, argv, "01", &ssl_method) == 0){ + return self; + } + ossl_sslctx_set_ssl_version(self, ssl_method); + return self; } @@ -436,6 +446,14 @@ ossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg) return i; } +/* + * call-seq: + * ctx.setup => Qtrue # first time + * ctx.setup => nil # thereafter + * + * This method is called automatically when a new SSLSocket is created. + * Normally you do not need to call this method (unless you are writing an extension in C). + */ static VALUE ossl_sslctx_setup(VALUE self) { @@ -769,18 +787,18 @@ ossl_sslctx_get_session_cache_stats(VALUE self) Data_Get_Struct(self, SSL_CTX, ctx); hash = rb_hash_new(); - rb_hash_aset(hash, rb_str_new2("cache_num"), LONG2NUM(SSL_CTX_sess_number(ctx))); - rb_hash_aset(hash, rb_str_new2("connect"), LONG2NUM(SSL_CTX_sess_connect(ctx))); - rb_hash_aset(hash, rb_str_new2("connect_good"), LONG2NUM(SSL_CTX_sess_connect_good(ctx))); - rb_hash_aset(hash, rb_str_new2("connect_renegotiate"), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx))); - rb_hash_aset(hash, rb_str_new2("accept"), LONG2NUM(SSL_CTX_sess_accept(ctx))); - rb_hash_aset(hash, rb_str_new2("accept_good"), LONG2NUM(SSL_CTX_sess_accept_good(ctx))); - rb_hash_aset(hash, rb_str_new2("accept_renegotiate"), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx))); - rb_hash_aset(hash, rb_str_new2("cache_hits"), LONG2NUM(SSL_CTX_sess_hits(ctx))); - rb_hash_aset(hash, rb_str_new2("cb_hits"), LONG2NUM(SSL_CTX_sess_cb_hits(ctx))); - rb_hash_aset(hash, rb_str_new2("cache_misses"), LONG2NUM(SSL_CTX_sess_misses(ctx))); - rb_hash_aset(hash, rb_str_new2("cache_full"), LONG2NUM(SSL_CTX_sess_cache_full(ctx))); - rb_hash_aset(hash, rb_str_new2("timeouts"), LONG2NUM(SSL_CTX_sess_timeouts(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("connect")), LONG2NUM(SSL_CTX_sess_connect(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("connect_good")), LONG2NUM(SSL_CTX_sess_connect_good(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("connect_renegotiate")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("accept")), LONG2NUM(SSL_CTX_sess_accept(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("accept_good")), LONG2NUM(SSL_CTX_sess_accept_good(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("accept_renegotiate")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("cache_hits")), LONG2NUM(SSL_CTX_sess_hits(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("cb_hits")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("cache_misses")), LONG2NUM(SSL_CTX_sess_misses(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("cache_full")), LONG2NUM(SSL_CTX_sess_cache_full(ctx))); + rb_hash_aset(hash, ID2SYM(rb_intern("timeouts")), LONG2NUM(SSL_CTX_sess_timeouts(ctx))); return hash; } @@ -1300,6 +1318,19 @@ ossl_ssl_set_session(VALUE self, VALUE arg1) return arg1; } +static VALUE +ossl_ssl_get_verify_result(VALUE self) +{ + SSL *ssl; + + Data_Get_Struct(self, SSL, ssl); + if (!ssl) { + rb_warning("SSL session is not started yet."); + return Qnil; + } + + return INT2FIX(SSL_get_verify_result(ssl)); +} void Init_ossl_ssl() @@ -1330,18 +1361,22 @@ Init_ossl_ssl() * * The following attributes are available but don't show up in rdoc. * All attributes must be set before calling SSLSocket.new(io, ctx). - * * cert, key, client_ca, ca_file, ca_path, timeout, verify_mode, verify_depth - * * client_cert_cb, tmp_dh_callback, session_id_context, - * * session_add_cb, session_new_cb, session_remove_cb + * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout, + * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback, + * * session_id_context, session_add_cb, session_new_cb, session_remove_cb */ cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject); rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc); for(i = 0; i < numberof(ossl_sslctx_attrs); i++) rb_attr(cSSLContext, rb_intern(ossl_sslctx_attrs[i]), 1, 1, Qfalse); + rb_define_alias(cSSLContext, "ssl_timeout", "timeout"); rb_define_method(cSSLContext, "initialize", ossl_sslctx_initialize, -1); + rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1); rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0); rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1); + rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0); + rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2FIX(SSL_SESS_CACHE_OFF)); rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */ @@ -1395,6 +1430,7 @@ Init_ossl_ssl() rb_define_method(cSSLSocket, "pending", ossl_ssl_pending, 0); rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0); rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1); + rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0); #define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2FIX(SSL_##x)) diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index a5cb8cb67d..2aafcfecc3 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -4799,8 +4799,15 @@ class TkWindow<TkObject tk_call_without_enc(cmd, @path) keys = __check_available_configure_options(keys) unless keys.empty? - tk_call_without_enc('destroy', @path) - tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) + begin + tk_call_without_enc('destroy', @path) + rescue + # cannot destroy + configure(keys) + else + # re-create widget + tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) + end end end end @@ -5341,7 +5348,7 @@ TkWidget = TkWindow #Tk.freeze module Tk - RELEASE_DATE = '2008-04-15'.freeze + RELEASE_DATE = '2008-04-18'.freeze autoload :AUTO_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable' diff --git a/ext/tk/lib/tk/scale.rb b/ext/tk/lib/tk/scale.rb index bf2791ec55..7e758d92f4 100644 --- a/ext/tk/lib/tk/scale.rb +++ b/ext/tk/lib/tk/scale.rb @@ -26,9 +26,16 @@ class Tk::Scale<TkWindow tk_call_without_enc(self.class::TkCommandNames[0], @path) keys = __check_available_configure_options(keys) unless keys.empty? - tk_call_without_enc('destroy', @path) - tk_call_without_enc(self.class::TkCommandNames[0], @path, - *hash_kv(keys, true)) + begin + tk_call_without_enc('destroy', @path) + rescue + # cannot destroy + configure(keys) + else + # re-create widget + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + end end end end diff --git a/ext/tk/lib/tk/scrollbar.rb b/ext/tk/lib/tk/scrollbar.rb index 521fc7e400..87db46a9f9 100644 --- a/ext/tk/lib/tk/scrollbar.rb +++ b/ext/tk/lib/tk/scrollbar.rb @@ -31,9 +31,16 @@ class Tk::Scrollbar<TkWindow tk_call_without_enc(self.class::TkCommandNames[0], @path) keys = __check_available_configure_options(keys) unless keys.empty? - tk_call_without_enc('destroy', @path) - tk_call_without_enc(self.class::TkCommandNames[0], @path, - *hash_kv(keys, true)) + begin + tk_call_without_enc('destroy', @path) + rescue + # cannot destroy + configure(keys) + else + # re-create widget + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + end end end end diff --git a/ext/tk/lib/tkextlib/blt/ted.rb b/ext/tk/lib/tkextlib/blt/ted.rb index 39495842b4..8b727c1eec 100644 --- a/ext/tk/lib/tkextlib/blt/ted.rb +++ b/ext/tk/lib/tkextlib/blt/ted.rb @@ -34,7 +34,7 @@ module Tk::BLT private :itemconfiginfo, :current_itemconfiginfo def cget(master, option) - itemconfigure(master, slot, value) + itemcget(master, option) end def configure(master, slot, value=None) itemconfigure(master, slot, value) diff --git a/ext/tk/lib/tkextlib/blt/unix_dnd.rb b/ext/tk/lib/tkextlib/blt/unix_dnd.rb index 3130c1e56f..7a994233a2 100644 --- a/ext/tk/lib/tkextlib/blt/unix_dnd.rb +++ b/ext/tk/lib/tkextlib/blt/unix_dnd.rb @@ -34,7 +34,7 @@ module Tk::BLT private :itemconfiginfo, :current_itemconfiginfo def cget(win, option) - itemconfigure(['cget', win], slot, value) + itemcget(['cget', win], option) end def configure(win, slot, value=None) itemconfigure(['configure', win], slot, value) @@ -46,8 +46,8 @@ module Tk::BLT current_itemconfiginfo(['configure', win], slot) end - def tokwn_cget(win, option) - itemconfigure(['token', 'cget', win], slot, value) + def token_cget(win, option) + itemcget(['token', 'cget', win], option) end def token_configure(win, slot, value=None) itemconfigure(['token', 'configure', win], slot, value) diff --git a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb index b72b157dcd..d025bc4086 100644 --- a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb +++ b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb @@ -518,7 +518,8 @@ module Tk::TreeCtrl::ConfigMethod def notify_cget(win, pattern, option) pattern = "<#{pattern}>" - itemconfigure(['notify', [win, pattern]], option) + # "notify" doesn't have cget subcommand. + current_itemconfiginfo(['notify', [win, pattern]])[option.to_s] end def notify_configure(win, pattern, slot, value=None) pattern = "<#{pattern}>" @@ -528,7 +529,10 @@ module Tk::TreeCtrl::ConfigMethod pattern = "<#{pattern}>" itemconfiginfo(['notify', [win, pattern]], slot) end - alias current_notify_configinfo notify_configinfo + def current_notify_configinfo(tagOrId, slot=nil) + pattern = "<#{pattern}>" + current_itemconfiginfo(['notify', [win, pattern]], slot) + end def style_cget(tagOrId, option) itemcget(['style', tagOrId], option) diff --git a/ext/tk/lib/tkextlib/version.rb b/ext/tk/lib/tkextlib/version.rb index 0fc1136e53..08cccf56c2 100644 --- a/ext/tk/lib/tkextlib/version.rb +++ b/ext/tk/lib/tkextlib/version.rb @@ -2,5 +2,5 @@ # release date of tkextlib # module Tk - Tkextlib_RELEASE_DATE = '2008-04-14'.freeze + Tkextlib_RELEASE_DATE = '2008-04-18'.freeze end diff --git a/ext/tk/sample/ttk_wrapper.rb b/ext/tk/sample/ttk_wrapper.rb index 4a4491b5bd..8bd818f5c4 100644 --- a/ext/tk/sample/ttk_wrapper.rb +++ b/ext/tk/sample/ttk_wrapper.rb @@ -4,7 +4,7 @@ # # by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) # -version = '0.1' +version = '0.1.1' # ########################################################################## # parse commandline arguments @@ -144,7 +144,7 @@ setTheme(OPTS[:theme]) if OPTS[:theme] ########################################################################## # load script ########################################################################## -if (script = File.expand_path(ARGV.shift)) +if (path = ARGV.shift) && (script = File.expand_path(path)) print "load script \"#{script}\"\n" if OPTS[:verbose] load(script) else |