[前][次][番号順一覧][スレッド一覧]

ruby-changes:4699

From: ko1@a...
Date: Fri, 25 Apr 2008 15:51:50 +0900 (JST)
Subject: [ruby-changes:4699] knu - Ruby:r16193 (ruby_1_8_7): Merge from ruby_1_8.

knu	2008-04-25 15:51:21 +0900 (Fri, 25 Apr 2008)

  New Revision: 16193

  Modified files:
    branches/ruby_1_8_7/ChangeLog
    branches/ruby_1_8_7/NEWS
    branches/ruby_1_8_7/array.c
    branches/ruby_1_8_7/dln.c
    branches/ruby_1_8_7/eval.c
    branches/ruby_1_8_7/ext/openssl/lib/openssl/ssl.rb
    branches/ruby_1_8_7/ext/openssl/ossl_ssl.c
    branches/ruby_1_8_7/ext/tk/lib/tk/scale.rb
    branches/ruby_1_8_7/ext/tk/lib/tk/scrollbar.rb
    branches/ruby_1_8_7/ext/tk/lib/tk.rb
    branches/ruby_1_8_7/ext/tk/lib/tkextlib/blt/ted.rb
    branches/ruby_1_8_7/ext/tk/lib/tkextlib/blt/unix_dnd.rb
    branches/ruby_1_8_7/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb
    branches/ruby_1_8_7/ext/tk/lib/tkextlib/version.rb
    branches/ruby_1_8_7/ext/tk/sample/ttk_wrapper.rb
    branches/ruby_1_8_7/lib/net/pop.rb
    branches/ruby_1_8_7/test/gdbm/test_gdbm.rb
    branches/ruby_1_8_7/test/openssl/test_ssl.rb
    branches/ruby_1_8_7/version.h

  Log:
    Merge from ruby_1_8.

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/tk/lib/tk/scale.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/test/openssl/test_ssl.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/dln.c?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/tk/lib/tkextlib/blt/unix_dnd.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/tk/lib/tkextlib/blt/ted.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/tk/lib/tk/scrollbar.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/eval.c?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/openssl/lib/openssl/ssl.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ChangeLog?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/tk/sample/ttk_wrapper.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/openssl/ossl_ssl.c?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/NEWS?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/tk/lib/tkextlib/version.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/version.h?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/array.c?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/test/gdbm/test_gdbm.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/lib/net/pop.rb?r1=16193&r2=16192&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ext/tk/lib/tk.rb?r1=16193&r2=16192&diff_format=u

Index: ruby_1_8_7/dln.c
===================================================================
--- ruby_1_8_7/dln.c	(revision 16192)
+++ ruby_1_8_7/dln.c	(revision 16193)
@@ -1781,26 +1781,9 @@
 	}
 	memcpy(bp, fname, i + 1);
 
-#ifndef __MACOS__
-	if (stat(fbuf, &st) == 0) {
-	    if (exe_flag == 0) return fbuf;
-	    /* looking for executable */
-	    if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0)
-		return fbuf;
-	}
-#else
-	if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) {
-	    if (exe_flag == 0) return mac_fullpath;
-	    /* looking for executable */
-	    if (stat(mac_fullpath, &st) == 0) {
-		if (!S_ISDIR(st.st_mode) && eaccess(mac_fullpath, X_OK) == 0)
-		    return mac_fullpath;
-	    }
-	}
-#endif
 #if defined(DOSISH)
 	if (exe_flag) {
-	    static const char *const extension[] = {
+	    static const char extension[][5] = {
 #if defined(MSDOS)
 		".com", ".exe", ".bat",
 #if defined(DJGPP)
@@ -1813,11 +1796,10 @@
 		".r", ".R", ".x", ".X", ".bat", ".BAT",
 /* __human68k__ */
 #endif
-		(char *) NULL
 	    };
 	    int j;
 
-	    for (j = 0; extension[j]; j++) {
+	    for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) {
 		if (fspace < strlen(extension[j])) {
 		    fprintf(stderr, "openpath: pathname too long (ignored)\n");
 		    fprintf(stderr, "\tDirectory \"%.*s\"\n", (int) (bp - fbuf), fbuf);
@@ -1834,9 +1816,28 @@
 
 #endif
 	    }
+	    goto next;
 	}
 #endif /* MSDOS or _WIN32 or __human68k__ or __EMX__ */
 
+#ifndef __MACOS__
+	if (stat(fbuf, &st) == 0) {
+	    if (exe_flag == 0) return fbuf;
+	    /* looking for executable */
+	    if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0)
+		return fbuf;
+	}
+#else
+	if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) {
+	    if (exe_flag == 0) return mac_fullpath;
+	    /* looking for executable */
+	    if (stat(mac_fullpath, &st) == 0) {
+		if (!S_ISDIR(st.st_mode) && eaccess(mac_fullpath, X_OK) == 0)
+		    return mac_fullpath;
+	    }
+	}
+#endif
+
       next:
 	/* if not, and no other alternatives, life is bleak */
 	if (*ep == '\0') {
Index: ruby_1_8_7/array.c
===================================================================
--- ruby_1_8_7/array.c	(revision 16192)
+++ ruby_1_8_7/array.c	(revision 16193)
@@ -3082,7 +3082,7 @@
     st_data_t id;
 
     stack = rb_ary_new();
-    result = rb_ary_new();
+    result = ary_new(rb_class_of(ary), RARRAY_LEN(ary));
     memo = st_init_numtable();
     st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
     *modified = 0;
Index: ruby_1_8_7/ext/tk/sample/ttk_wrapper.rb
===================================================================
--- ruby_1_8_7/ext/tk/sample/ttk_wrapper.rb	(revision 16192)
+++ ruby_1_8_7/ext/tk/sample/ttk_wrapper.rb	(revision 16193)
@@ -4,7 +4,7 @@
 #
 #                       by Hidetoshi NAGAI (nagai@a...)
 #
-version = '0.1'
+version = '0.1.1'
 #
 ##########################################################################
 #  parse commandline arguments
@@ -144,7 +144,7 @@
 ##########################################################################
 #  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
Index: ruby_1_8_7/ext/tk/lib/tk.rb
===================================================================
--- ruby_1_8_7/ext/tk/lib/tk.rb	(revision 16192)
+++ ruby_1_8_7/ext/tk/lib/tk.rb	(revision 16193)
@@ -4799,8 +4799,15 @@
           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 @@
 #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'
Index: ruby_1_8_7/ext/tk/lib/tkextlib/blt/unix_dnd.rb
===================================================================
--- ruby_1_8_7/ext/tk/lib/tkextlib/blt/unix_dnd.rb	(revision 16192)
+++ ruby_1_8_7/ext/tk/lib/tkextlib/blt/unix_dnd.rb	(revision 16193)
@@ -34,7 +34,7 @@
       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 @@
         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)
Index: ruby_1_8_7/ext/tk/lib/tkextlib/blt/ted.rb
===================================================================
--- ruby_1_8_7/ext/tk/lib/tkextlib/blt/ted.rb	(revision 16192)
+++ ruby_1_8_7/ext/tk/lib/tkextlib/blt/ted.rb	(revision 16193)
@@ -34,7 +34,7 @@
       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)
Index: ruby_1_8_7/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb
===================================================================
--- ruby_1_8_7/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb	(revision 16192)
+++ ruby_1_8_7/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb	(revision 16193)
@@ -518,7 +518,8 @@
 
   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 @@
     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)
Index: ruby_1_8_7/ext/tk/lib/tkextlib/version.rb
===================================================================
--- ruby_1_8_7/ext/tk/lib/tkextlib/version.rb	(revision 16192)
+++ ruby_1_8_7/ext/tk/lib/tkextlib/version.rb	(revision 16193)
@@ -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
Index: ruby_1_8_7/ext/tk/lib/tk/scrollbar.rb
===================================================================
--- ruby_1_8_7/ext/tk/lib/tk/scrollbar.rb	(revision 16192)
+++ ruby_1_8_7/ext/tk/lib/tk/scrollbar.rb	(revision 16193)
@@ -31,9 +31,16 @@
           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
Index: ruby_1_8_7/ext/tk/lib/tk/scale.rb
===================================================================
--- ruby_1_8_7/ext/tk/lib/tk/scale.rb	(revision 16192)
+++ ruby_1_8_7/ext/tk/lib/tk/scale.rb	(revision 16193)
@@ -26,9 +26,16 @@
           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
Index: ruby_1_8_7/ext/openssl/ossl_ssl.c
===================================================================
--- ruby_1_8_7/ext/openssl/ossl_ssl.c	(revision 16192)
+++ ruby_1_8_7/ext/openssl/ossl_ssl.c	(revision 16193)
@@ -141,31 +141,14 @@
     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;
+    const char *s;
     int i;
-    const char *s;
 
-    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_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 @@
     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 @@
     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,7 +1318,20 @@
     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 @@
      *
      * 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 @@
     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))
 
Index: ruby_1_8_7/ext/openssl/lib/openssl/ssl.rb
===================================================================
--- ruby_1_8_7/ext/openssl/lib/openssl/ssl.rb	(revision 16192)
+++ ruby_1_8_7/ext/openssl/lib/openssl/ssl.rb	(revision 16193)
@@ -20,6 +20,33 @@
 
 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 @@
       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 @@
         @svr.listen(backlog)
       end
 
+      def shutdown(how=Socket::SHUT_RDWR)
+        @svr.shutdown(how)
+      end
+
       def accept
         sock = @svr.accept
         begin
Index: ruby_1_8_7/NEWS
===================================================================
--- ruby_1_8_7/NEWS	(revision 16192)
+++ ruby_1_8_7/NEWS	(revision 16193)
@@ -73,6 +73,10 @@
 
     New methods.
 
+  * Binding#eval
+
+    New method.
+
   * Dir#each
   * Dir#foreach
 
Index: ruby_1_8_7/ChangeLog
===================================================================
--- ruby_1_8_7/ChangeLog	(revision 16192)
+++ ruby_1_8_7/ChangeLog	(revision 16193)
@@ -1,3 +1,52 @@
+Fri Apr 25 15:46:37 2008  Hidetoshi NAGAI  <nagai@a...>
+
+	* ext/tk/lib/tk.rb, ext/tk/lib/tk/scrollbar.rb, ext/tk/lib/tk/scale.rb:
+	  improve unknonw-option check when create a widget. 
+
+	* ext/tk/lib/tkextlib/blt/unix_dnd.rb, ext/tk/lib/tkextlib/blt/ted.rb,
+	  ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: bug fix on 'cget'.
+
+	* ext/tk/lib/tk/menuspec.rb: option check will fail when 
+	  TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ is true.
+
+	* ext/tk/lib/tk/palette.rb: bug fix.
+
+Fri Apr 25 12:37:54 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* array.c (flatten): returns an instance of same class.
+	  [ruby-core:16554]
+
+Thu Apr 24 23:47:50 2008  Kazuhiro NISHIYAMA  <zn@m...>
+
+	* lib/net/pop.rb: backported from 1.9. bug#19003
+
+	* ext/openssl/lib/openssl/ssl.rb: set_params; backported from 1.9.
+	  bug#19552, [ruby-dev:34402]
+
+	* ext/openssl/ossl_ssl.c: ditto.
+
+	* test/openssl/test_ssl.rb: ditto.
+
+Thu Apr 24 17:06:34 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* eval.c (THREAD_SAVE_CONTEXT): remove unnecessary
+	  FLUSH_REGISTER_WINDOWS before calling setjmp().  [ruby-core:16285]
+
+Thu Apr 24 14:15:11 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* dln.c (dln_find_1): prior files with extensions to files sans
+	  extensions.  [ruby-core:16517]
+
+Wed Apr 23 15:39:31 2008  Akinori MUSHA  <knu@i...>
+
+	* eval.c (bind_eval): Add Binding#eval, a shorthand method for
+	  eval(str, binding, ..); backported from 1.9.
+
+Wed Apr 23 15:28:52 2008  Kazuhiro NISHIYAMA  <zn@m...>
+
+	* test/gdbm/test_gdbm.rb (TestGDBM#test_s_open_no_create): failed
+	  notice moved from comment to assertion message. [ruby-dev:29127]
+
 Wed Apr 23 14:00:05 2008  Akinori MUSHA  <knu@i...>
 
 	* lib/mkmf.rb (create_makefile): Add a missing dependency on the
Index: ruby_1_8_7/version.h
===================================================================
--- ruby_1_8_7/version.h	(revision 16192)
+++ ruby_1_8_7/version.h	(revision 16193)
@@ -1,7 +1,7 @@
 #define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2008-04-23"
+#define RUBY_RELEASE_DATE "2008-04-25"
 #define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20080423
+#define RUBY_RELEASE_CODE 20080425
 #define RUBY_PATCHLEVEL 0
 
 #define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
 #define RUBY_VERSION_TEENY 7
 #define RUBY_RELEASE_YEAR 2008
 #define RUBY_RELEASE_MONTH 4
-#define RUBY_RELEASE_DAY 23
+#define RUBY_RELEASE_DAY 25
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
Index: ruby_1_8_7/lib/net/pop.rb
===================================================================
--- ruby_1_8_7/lib/net/pop.rb	(revision 16192)
+++ ruby_1_8_7/lib/net/pop.rb	(revision 16193)
@@ -1,8 +1,8 @@
 # = net/pop.rb
 #
-# Copyright (c) 1999-2003 Yukihiro Matsumoto.
+# Copyright (c) 1999-2007 Yukihiro Matsumoto.
 #
-# Copyright (c) 1999-2003 Minero Aoki.
+# Copyright (c) 1999-2007 Minero Aoki.
 # 
 # Written & maintained by Minero Aoki <aamine@l...>.
 #
@@ -10,19 +10,25 @@
 # 
 # This program is free software. You can re-distribute and/or
 # modify this program under the same terms as Ruby itself,
-# Ruby Distribute License or GNU General Public License.
+# Ruby Distribute License.
 # 
-# NOTE: You can find Japanese version of this document in
-# the doc/net directory of the standard ruby interpreter package.
+# NOTE: You can find Japanese version of this document at:
+# http://www.ruby-lang.org/ja/man/html/net_pop.html
 # 
 #   $Id$
-#
+# 
 # See Net::POP3 for documentation.
 #
 
 require 'net/protocol'
 require 'digest/md5'
+require 'timeout'
 
+begin
+  require "openssl/ssl"
+rescue LoadError
+end
+
 module Net
 
   # Non-authentication POP3 protocol error
@@ -196,10 +202,19 @@
     # Class Parameters
     #
 
+    def POP3.default_port
+      default_pop3_port()
+    end
+
     # The default port for POP3 connections, port 110
-    def POP3.default_port
+    def POP3.default_pop3_port
       110
     end
+    
+    # The default port for POP3S connections, port 995
+    def POP3.default_pop3s_port
+      995
+    end
 
     def POP3.socket_type   #:nodoc: obsolete
       Net::InternetMessageIO
@@ -220,7 +235,7 @@
     #       ....
     #     end
     #
-    def POP3.APOP( isapop )
+    def POP3.APOP(isapop)
       isapop ? APOP : POP3
     end
 
@@ -244,9 +259,9 @@
     #       m.delete if $DELETE
     #     end
     #
-    def POP3.foreach( address, port = nil,
-                      account = nil, password = nil,
-                      isapop = false, &block )  # :yields: message
+    def POP3.foreach(address, port = nil,
+                     account = nil, password = nil,
+                     isapop = false, &block)  # :yields: message
       start(address, port, account, password, isapop) {|pop|
         pop.each_mail(&block)
       }
@@ -265,9 +280,9 @@
     #       file.write m.pop
     #     end
     #
-    def POP3.delete_all( address, port = nil,
-                         account = nil, password = nil,
-                         isapop = false, &block )
+    def POP3.delete_all(address, port = nil,
+                        account = nil, password = nil,
+                        isapop = false, &block)
       start(address, port, account, password, isapop) {|pop|
         pop.delete_all(&block)
       }
@@ -287,16 +302,16 @@
     #     Net::POP3.auth_only('pop.example.com', 110,
     #                         'YourAccount', 'YourPassword', true)
     #
-    def POP3.auth_only( address, port = nil,
-                        account = nil, password = nil,
-                        isapop = false )
+    def POP3.auth_only(address, port = nil,
+                       account = nil, password = nil,
+                       isapop = false)
       new(address, port, isapop).auth_only account, password
     end
 
     # Starts a pop3 session, attempts authentication, and quits.
     # This method must not be called while POP3 session is opened.
     # This method raises POPAuthenticationError if authentication fails.
-    def auth_only( account, password )
+    def auth_only(account, password)
       raise IOError, 'opening previously opened POP session' if started?
       start(account, password) {
         ;
@@ -304,6 +319,59 @@
     end
 
     #
+    # SSL
+    #
+
+    @ssl_params = nil
+
+    # call-seq:
+    #    Net::POP.enable_ssl(params = {})
+    #
+    # Enable SSL for all new instances.
+    # +params+ is passed to OpenSSL::SSLContext#set_params.
+    def POP3.enable_ssl(*args)
+      @ssl_params = create_ssl_params(*args)
+    end
+
+    def POP3.create_ssl_params(verify_or_params = {}, certs = nil)
+      begin
+        params = verify_or_params.to_hash
+      rescue NoMethodError
+        params = {}
+        params[:verify_mode] = verify_or_params
+        if certs
+          if File.file?(certs)
+            params[:ca_file] = certs
+          elsif File.directory?(certs)
+            params[:ca_path] = certs
+          end
+        end
+      end
+      return params
+    end
+
+    # Disable SSL for all new instances.
+    def POP3.disable_ssl
+      @ssl_params = nil
+    end
+
+    def POP3.ssl_params
+      return @ssl_params
+    end
+
+    def POP3.use_ssl?
+      return !@ssl_params.nil?
+    end
+
+    def POP3.verify
+      return @ssl_params[:verify_mode]
+    end
+
+    def POP3.certs
+      return @ssl_params[:ca_file] || @ssl_params[:ca_path]
+    end
+
+    #
     # Session management
     #
 
@@ -323,27 +391,28 @@
     #      end
     #    end
     #
-    def POP3.start( address, port = nil,
-                    account = nil, password = nil,
-                    isapop = false, &block ) # :yield: pop
+    def POP3.start(address, port = nil,
+                   account = nil, password = nil,
+                   isapop = false, &block)   # :yield: pop
       new(address, port, isapop).start(account, password, &block)
     end
-
+    
     # Creates a new POP3 object.
     #
     # +address+ is the hostname or ip address of your POP3 server.
     #
-    # The optional +port+ is the port to connect to; it defaults to 110.
+    # The optional +port+ is the port to connect to.
     #
     # The optional +isapop+ specifies whether this connection is going
     # to use APOP authentication; it defaults to +false+.
     #
     # This method does *not* open the TCP connection.
-    def initialize( addr, port = nil, isapop = false )
+    def initialize(addr, port = nil, isapop = false)
       @address = addr
-      @port = port || self.class.default_port
+      @ssl_params = POP3.ssl_params
+      @port = port
       @apop = isapop
-
+      
       @command = nil
       @socket = nil
       @started = false
@@ -361,6 +430,32 @@
       @apop
     end
 
+    # does this instance use SSL?
+    def use_ssl?
+      return !@ssl_params.nil?
+    end
+   
+    # call-seq:
+    #    Net::POP#enable_ssl(params = {})
+    #
+    # Enables SSL for this instance.  Must be called before the connection is
+    # established to have any effect.
+    # +params[:port]+ is port to establish the SSL connection on; Defaults to 995.
+    # +params+ (except :port) is passed to OpenSSL::SSLContext#set_params.
+    def enable_ssl(verify_or_params = {}, certs = nil, port = nil)
+      begin
+        @ssl_params = verify_or_params.to_hash.dup
+        @port = @ssl_params.delete(:port) || @port
+      rescue NoMethodError
+        @ssl_params = POP3.create_ssl_params(verify_or_params, certs)
+        @port = port || @port
+      end
+    end
+    
+    def disable_ssl
+      @ssl_params = nil
+    end
+
     # Provide human-readable stringification of class state.
     def inspect
       "#<#{self.class} #{@address}:#{@port} open=#{@started}>"
@@ -379,7 +474,7 @@
     #     ....
     #   end
     #
-    def set_debug_output( arg )
+    def set_debug_output(arg)
       @debug_output = arg
     end
 
@@ -387,7 +482,9 @@
     attr_reader :address
 
     # The port number to connect to.
-    attr_reader :port
+    def port
+      return @port || (use_ssl? ? POP3.default_pop3s_port : POP3.default_pop3_port)
+    end
 
     # Seconds to wait until a connection is opened.
     # If the POP3 object cannot open a connection within this time,
@@ -400,7 +497,7 @@
     attr_reader :read_timeout
 
     # Set the read timeout.
-    def read_timeout=( sec )
+    def read_timeout=(sec)
       @command.socket.read_timeout = sec if @command
       @read_timeout = sec
     end
@@ -418,9 +515,8 @@
     # closes the session after block call finishes.
     #
     # This method raises a POPAuthenticationError if authentication fails.
-    def start( account, password ) # :yield: pop
+    def start(account, password) # :yield: pop
       raise IOError, 'POP session already started' if @started
-
       if block_given?
         begin
           do_start account, password
@@ -434,9 +530,23 @@
       end
     end
 
-    def do_start( account, password )
-      @socket = self.class.socket_type.old_open(@address, @port,
-                                   @open_timeout, @read_timeout, @debug_output)
+    def do_start(account, password)
+      s = timeout(@open_timeout) { TCPSocket.open(@address, port) }
+      if use_ssl?
+        raise 'openssl library not installed' unless defined?(OpenSSL)
+        context = OpenSSL::SSL::SSLContext.new
+        context.set_params(@ssl_params)
+        s = OpenSSL::SSL::SSLSocket.new(s, context)
+        s.sync_close = true
+        s.connect
+        if context.verify_mode != OpenSSL::SSL::VERIFY_NONE
+          s.post_connection_check(@address)
+        end
+      end
+      @socket = InternetMessageIO.new(s)
+      logging "POP session started: #{@address}:#{@port} (#{@apop ? 'APOP' : 'POP'})"
+      @socket.read_timeout = @read_timeout
+      @socket.debug_output = @debug_output
       on_connect
       @command = POP3Command.new(@socket)
       if apop?
@@ -446,7 +556,12 @@
       end
       @started = true
     ensure
-      do_finish if not @started
+      # Authentication failed, clean up connection.
+      unless @started
+        s.close if s and not s.closed?
+        @socket = nil
+        @command = nil
+      end
     end
     private :do_start
 
@@ -526,7 +641,7 @@
     #   end
     #
     # This method raises a POPError if an error occurs.
-    def each_mail( &block )  # :yield: message
+    def each_mail(&block)  # :yield: message
       mails().each(&block)
     end
 
@@ -573,6 +688,10 @@
       end
     end
 
+    def logging(msg)
+      @debug_output << msg + "\n" if @debug_output
+    end
+
   end   # class POP3
 
   # class aliases
@@ -600,7 +719,7 @@
   #
   class POPMail
 
-    def initialize( num, len, pop, cmd )   #:nodoc:
+    def initialize(num, len, pop, cmd)   #:nodoc:
       @number = num
       @length = len
       @pop = pop
@@ -679,7 +798,7 @@
     # The optional +dest+ argument is obsolete.
     #
     # This method raises a POPError if an error occurs.
-    def top( lines, dest = '' )
+    def top(lines, dest = '')
       @command.top(@number, lines) do |chunk|
         dest << chunk
       end
@@ -691,7 +810,7 @@
     # The optional +dest+ argument is obsolete.
     #
     # This method raises a POPError if an error occurs.
-    def header( dest = '' )
+    def header(dest = '')
       top(0, dest)
     end
 
@@ -739,7 +858,7 @@
 
     alias uidl unique_id
 
-    def uid=( uid )   #:nodoc: internal use only (used from POP3#set_all_uids)
+    def uid=(uid)   #:nodoc: internal use only
       @uid = uid
     end
 
@@ -748,7 +867,7 @@
 
   class POP3Command   #:nodoc: internal use only
 
-    def initialize( sock )
+    def initialize(sock)
       @socket = sock
       @error_occured = false
       res = check_response(critical { recv_response() })
@@ -759,14 +878,14 @@
       "#<#{self.class} socket=#{@socket}>"
     end
 
-    def auth( account, password )
+    def auth(account, password)
       check_response_auth(critical {
         check_response_auth(get_response('USER %s', account))
         get_response('PASS %s', password)
       })
     end
 
-    def apop( account, password )
+    def apop(account, password)
       raise POPAuthenticationError, 'not APOP server; cannot login' \
                                                       unless @apop_stamp
       check_response_auth(critical {
@@ -797,28 +916,28 @@
     end
 
     def rset
-      check_response(critical { get_response 'RSET' })
+      check_response(critical { get_response('RSET') })
     end
 
-    def top( num, lines = 0, &block )
+    def top(num, lines = 0, &block)
       critical {
         getok('TOP %d %d', num, lines)
         @socket.each_message_chunk(&block)
       }
     end
 
-    def retr( num, &block )
+    def retr(num, &block)
       critical {
         getok('RETR %d', num)
         @socket.each_message_chunk(&block)
       }
     end
     
-    def dele( num )
+    def dele(num)
       check_response(critical { get_response('DELE %d', num) })
     end
 
-    def uidl( num = nil )
+    def uidl(num = nil)
       if num
         res = check_response(critical { get_response('UIDL %d', num) })
         return res.split(/ /)[1]
@@ -841,12 +960,12 @@
 
     private
 
-    def getok( fmt, *fargs )
+    def getok(fmt, *fargs)
       @socket.writeline sprintf(fmt, *fargs)
       check_response(recv_response())
     end
 
-    def get_response( fmt, *fargs )
+    def get_response(fmt, *fargs)
       @socket.writeline sprintf(fmt, *fargs)
       recv_response()
     end
@@ -855,13 +974,13 @@
       @socket.readline
     end
 
-    def check_response( res )
-      raise POPError, res unless /\A\+OK/i === res
+    def check_response(res)
+      raise POPError, res unless /\A\+OK/i =~ res
       res
     end
 
-    def check_response_auth( res )
-      raise POPAuthenticationError, res unless /\A\+OK/i === res
+    def check_response_auth(res)
+      raise POPAuthenticationError, res unless /\A\+OK/i =~ res
       res
     end
 
@@ -878,4 +997,3 @@
   end   # class POP3Command
 
 end   # module Net
-
Index: ruby_1_8_7/test/openssl/test_ssl.rb
===================================================================
--- ruby_1_8_7/test/openssl/test_ssl.rb	(revision 16192)
+++ ruby_1_8_7/test/openssl/test_ssl.rb	(revision 16193)
@@ -6,14 +6,18 @@
 require "rbconfig"
 require "socket"
 require "test/unit"
+begin
+  loadpath = $:.dup
+  $:.replace($: | [File.expand_path("../ruby", File.dirname(__FILE__))])
+  require 'envutil'
+ensure
+  $:.replace(loadpath)
+end
 
 if defined?(OpenSSL)
 
 class OpenSSL::TestSSL < Test::Unit::TestCase
-  RUBY = ENV["RUBY"] || File.join(
-    ::Config::CONFIG["bindir"],
-    ::Config::CONFIG["ruby_install_name"] + ::Config::CONFIG["EXEEXT"]
-  )
+  RUBY = EnvUtil.rubybin
   SSL_SERVER = File.join(File.dirname(__FILE__), "ssl_server.rb")
   PORT = 20443
   ITERATIONS = ($0 == __FILE__) ? 100 : 10
@@ -54,28 +58,84 @@
     OpenSSL::TestUtils.issue_crl(*arg)
   end
 
-  def start_server(port0, verify_mode, start_immediately, &block)
-    server = nil
+  def readwrite_loop(ctx, ssl)
+    while line = ssl.gets
+      if line =~ /^STARTTLS$/
+        ssl.accept
+        next
+      end
+      ssl.write(line)
+    end
+  rescue OpenSSL::SSL::SSLError
+  rescue IOError
+  ensure
+    ssl.close rescue nil
+  end
+
+  def server_loop(ctx, ssls, server_proc)
+    loop do
+      ssl = nil
+      begin
+        ssl = ssls.accept
+      rescue OpenSSL::SSL::SSLError
+      	retry
+      end
+
+      Thread.start do
+        Thread.current.abort_on_exception = true  
+        server_proc.call(ctx, ssl)
+      end
+    end
+  rescue Errno::EBADF, IOError
+  end
+
+  def start_server(port0, verify_mode, start_immediately, args = {}, &block)
+    ctx_proc = args[:ctx_proc]
+    server_proc = args[:server_proc]
+    server_proc ||= method(:readwrite_loop)
+  
+    store = OpenSSL::X509::Store.new
+    store.add_cert(@ca_cert)
+    store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+    ctx = OpenSSL::SSL::SSLContext.new
+    ctx.cert_store = store
+    #ctx.extra_chain_cert = [ ca_cert ]
+    ctx.cert = @svr_cert
+    ctx.key = @svr_key
+    ctx.verify_mode = verify_mode
+    ctx_proc.call(ctx) if ctx_proc
+
+    Socket.do_not_reverse_lookup = true
+    tcps = nil
+    port = port0
     begin
-      cmd = [RUBY]
-      cmd << "-d" if $DEBUG
-      cmd << SSL_SERVER << port0.to_s << verify_mode.to_s
-      cmd << (start_immediately ? "yes" : "no")
-      server = IO.popen(cmd.join(" "), "w+")
-      server.write(@ca_cert.to_pem)
-      server.write(@svr_cert.to_pem)
-      server.write(@svr_key.to_pem)
-      pid = Integer(server.gets)
-      if port = server.gets
-        if $DEBUG
-          $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, pid, port)
-        end
-        block.call(server, port.to_i)
+      tcps = TCPServer.new("127.0.0.1", port)
+    rescue Errno::EADDRINUSE
+      port += 1
+      retry
+    end
+
+    ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
+    ssls.start_immediately = start_immediately
+
+    begin
+      server = Thread.new do
+        Thread.current.abort_on_exception = true  
+        server_loop(ctx, ssls, server_proc)
       end
+
+      $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, pid, port) if $DEBUG
+
+      block.call(server, port.to_i)
     ensure
-      if server
-        Process.kill(:KILL, pid)
-        server.close
+      tcps.close if (tcps)
+      if (server)
+        server.join(5)
+        if server.alive?
+          server.kill
+          server.join
+          flunk("TCPServer was closed and SSLServer is still alive") unless $!
+        end
       end
     end
   end
@@ -89,16 +149,22 @@
     ssl.connect
   end
 
+  def test_ctx_setup
+    ctx = OpenSSL::SSL::SSLContext.new
+    assert_equal(ctx.setup, true)
+    assert_equal(ctx.setup, nil)
+  end
+
   def test_connect_and_close
-    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
-      sock = TCPSocket.new("127.0.0.1", p)
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock)
       assert(ssl.connect)
       ssl.close
       assert(!sock.closed?)
       sock.close
 
-      sock = TCPSocket.new("127.0.0.1", p)
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock)
       ssl.sync_close = true  # !!
       assert(ssl.connect)
@@ -108,8 +174,8 @@
   end
 
   def test_read_and_write
-    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
-      sock = TCPSocket.new("127.0.0.1", p)
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock)
       ssl.sync_close = true
       ssl.connect
@@ -127,13 +193,6 @@
         assert_equal(str, buf)
       }
 
-      # puts and gets
-      ITERATIONS.times{
-        str = "x" * 100 + "\n"
-        ssl.puts(str)
-        assert_equal(str, ssl.gets)
-      }
-
       # read and write
       ITERATIONS.times{|i|
         str = "x" * 100 + "\n"
@@ -153,9 +212,9 @@
 
   def test_client_auth
     vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
-    start_server(PORT, vflag, true){|s, p|
+    start_server(PORT, vflag, true){|server, port|
       assert_raises(OpenSSL::SSL::SSLError){
-        sock = TCPSocket.new("127.0.0.1", p)
+        sock = TCPSocket.new("127.0.0.1", port)
         ssl = OpenSSL::SSL::SSLSocket.new(sock)
         ssl.connect
       }
@@ -163,7 +222,7 @@
       ctx = OpenSSL::SSL::SSLContext.new
       ctx.key = @cli_key
       ctx.cert = @cli_cert
-      sock = TCPSocket.new("127.0.0.1", p)
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
       ssl.sync_close = true
       ssl.connect
@@ -173,11 +232,11 @@
 
       called = nil
       ctx = OpenSSL::SSL::SSLContext.new
-      ctx.client_cert_cb = Proc.new{|ssl|
+      ctx.client_cert_cb = Proc.new{ |sslconn|
         called = true
         [@cli_cert, @cli_key]
       }
-      sock = TCPSocket.new("127.0.0.1", p)
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
       ssl.sync_close = true
       ssl.connect
@@ -189,8 +248,8 @@
   end
 
   def test_starttls
-    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|s, p|
-      sock = TCPSocket.new("127.0.0.1", p)
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|server, port|
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock)
       ssl.sync_close = true
       str = "x" * 1000 + "\n"
@@ -213,10 +272,10 @@
 
   def test_parallel
     GC.start
-    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
       ssls = []
       10.times{
-        sock = TCPSocket.new("127.0.0.1", p)
+        sock = TCPSocket.new("127.0.0.1", port)
         ssl = OpenSSL::SSL::SSLSocket.new(sock)
         ssl.connect
         ssl.sync_close = true
@@ -233,17 +292,76 @@
     }
   end
 
+  def test_verify_result
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+      sock = TCPSocket.new("127.0.0.1", port)
+      ctx = OpenSSL::SSL::SSLContext.new
+      ctx.set_params
+      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+      assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
+      assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)
+
+      sock = TCPSocket.new("127.0.0.1", port)
+      ctx = OpenSSL::SSL::SSLContext.new
+      ctx.set_params(
+        :verify_callback => Proc.new do |preverify_ok, store_ctx|
+          store_ctx.error = OpenSSL::X509::V_OK
+          true
+        end
+      )
+      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+      ssl.connect
+      assert_equal(OpenSSL::X509::V_OK, ssl.verify_result)
+
+      sock = TCPSocket.new("127.0.0.1", port)
+      ctx = OpenSSL::SSL::SSLContext.new
+      ctx.set_params(
+        :verify_callback => Proc.new do |preverify_ok, store_ctx|
+          store_ctx.error = OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION
+          false
+        end
+      )
+      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+      assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
+      assert_equal(OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION, ssl.verify_result)
+    }
+  end
+
+  def test_sslctx_set_params
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+      sock = TCPSocket.new("127.0.0.1", port)
+      ctx = OpenSSL::SSL::SSLContext.new
+      ctx.set_params
+      assert_equal(OpenSSL::SSL::VERIFY_PEER, ctx.verify_mode)
+      assert_equal(OpenSSL::SSL::OP_ALL, ctx.options)
+      ciphers = ctx.ciphers
+      ciphers_versions = ciphers.collect{|_, v, _, _| v }
+      ciphers_names = ciphers.collect{|v, _, _, _| v }
+      assert(ciphers_names.all?{|v| /ADH/ !~ v })
+      assert(ciphers_versions.all?{|v| /SSLv2/ !~ v })
+      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+      assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
+      assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)
+    }
+  end
+
   def test_post_connection_check
     sslerr = OpenSSL::SSL::SSLError
 
-    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
-      sock = TCPSocket.new("127.0.0.1", p)
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock)
       ssl.connect
       assert_raises(sslerr){ssl.post_connection_check("localhost.localdomain")}
       assert_raises(sslerr){ssl.post_connection_check("127.0.0.1")}
       assert(ssl.post_connection_check("localhost"))
       assert_raises(sslerr){ssl.post_connection_check("foo.example.com")}
+
+      cert = ssl.peer_cert
+      assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
+      assert(!OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
+      assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
+      assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
     }
 
     now = Time.now
@@ -254,14 +372,20 @@
     ]
     @svr_cert = issue_cert(@svr, @svr_key, 4, now, now+1800, exts,
                            @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
-    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
-      sock = TCPSocket.new("127.0.0.1", p)
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock)
       ssl.connect
       assert(ssl.post_connection_check("localhost.localdomain"))
       assert(ssl.post_connection_check("127.0.0.1"))
       assert_raises(sslerr){ssl.post_connection_check("localhost")}
       assert_raises(sslerr){ssl.post_connection_check("foo.example.com")}
+
+      cert = ssl.peer_cert
+      assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
+      assert(OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
+      assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
+      assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
     }
 
     now = Time.now
@@ -271,16 +395,135 @@
     ]
     @svr_cert = issue_cert(@svr, @svr_key, 5, now, now+1800, exts,
                            @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
-    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
-      sock = TCPSocket.new("127.0.0.1", p)
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+      sock = TCPSocket.new("127.0.0.1", port)
       ssl = OpenSSL::SSL::SSLSocket.new(sock)
       ssl.connect
       assert(ssl.post_connection_check("localhost.localdomain"))
       assert_raises(sslerr){ssl.post_connection_check("127.0.0.1")}
       assert_raises(sslerr){ssl.post_connection_check("localhost")}
       assert_raises(sslerr){ssl.post_connection_check("foo.example.com")}
+      cert = ssl.peer_cert
+      assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
+      assert(!OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
+      assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
+      assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
     }
   end
+
+  def test_client_session
+    last_session = nil
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port|
+      2.times do
+        sock = TCPSocket.new("127.0.0.1", port)
+        ssl = OpenSSL::SSL::SSLSocket.new(sock)
+        ssl.sync_close = true
+        ssl.session = last_session if last_session
+        ssl.connect
+
+        session = ssl.session
+        if last_session
+          assert(ssl.session_reused?)
+
+          if session.respond_to?(:id)
+            assert_equal(session.id, last_session.id)
+          end
+          assert_equal(session.to_pem, last_session.to_pem)
+          assert_equal(session.to_der, last_session.to_der)
+          # Older version of OpenSSL may not be consistent.  Look up which versions later.
+          assert_equal(session.to_text, last_session.to_text)
+        else
+          assert(!ssl.session_reused?)
+        end
+        last_session = session
+
+        str = "x" * 100 + "\n"
+        ssl.puts(str)
+        assert_equal(str, ssl.gets)
+
+        ssl.close
+      end
+    end
+  end
+
+  def test_server_session
+    connections = 0
+    saved_session = nil
+
+    ctx_proc = Proc.new do |ctx, ssl|
+# add test for session callbacks here
+    end
+
+    server_proc = Proc.new do |ctx, ssl|
+      session = ssl.session
+      stats = ctx.session_cache_stats
+
+      case connections
+      when 0
+        assert_equal(stats[:cache_num], 1)
+        assert_equal(stats[:cache_hits], 0)
+        assert_equal(stats[:cache_misses], 0)
+        assert(!ssl.session_reused?)
+      when 1
+        assert_equal(stats[:cache_num], 1)
+        assert_equal(stats[:cache_hits], 1)
+        assert_equal(stats[:cache_misses], 0)
+        assert(ssl.session_reused?)
+        ctx.session_remove(session)
+        saved_session = session
+      when 2
+        assert_equal(stats[:cache_num], 1)
+        assert_equal(stats[:cache_hits], 1)
+        assert_equal(stats[:cache_misses], 1)
+        assert(!ssl.session_reused?)
+        ctx.session_add(saved_session)
+      when 3
+        assert_equal(stats[:cache_num], 2)
+        assert_equal(stats[:cache_hits], 2)
+        assert_equal(stats[:cache_misses], 1)
+        assert(ssl.session_reused?)
+        ctx.flush_sessions(Time.now + 5000)
+      when 4
+        assert_equal(stats[:cache_num], 1)
+        assert_equal(stats[:cache_hits], 2)
+        assert_equal(stats[:cache_misses], 2)
+        assert(!ssl.session_reused?)
+        ctx.session_add(saved_session)
+      end
+      connections += 1
+      
+      readwrite_loop(ctx, ssl)
+    end
+
+    first_session = nil
+    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc, :server_proc => server_proc) do |server, port|
+      10.times do |i|
+        sock = TCPSocket.new("127.0.0.1", port)
+        ssl = OpenSSL::SSL::SSLSocket.new(sock)
+        ssl.sync_close = true
+        ssl.session = first_session if first_session
+        ssl.connect
+
+        session = ssl.session
+        if first_session
+          case i
+          when 1; assert(ssl.session_reused?)
+          when 2; assert(!ssl.session_reused?)
+          when 3; assert(ssl.session_reused?)
+          when 4; assert(!ssl.session_reused?)
+          when 5..10; assert(ssl.session_reused?)
+          end
+        end
+        first_session ||= session
+
+        str = "x" * 100 + "\n"
+        ssl.puts(str)
+        assert_equal(str, ssl.gets)
+
+        ssl.close
+      end
+    end
+  end
 end
 
 end
Index: ruby_1_8_7/test/gdbm/test_gdbm.rb
===================================================================
--- ruby_1_8_7/test/gdbm/test_gdbm.rb	(revision 16192)
+++ ruby_1_8_7/test/gdbm/test_gdbm.rb	(revision 16193)
@@ -90,8 +90,8 @@
       end
     end
     def test_s_open_no_create
-      # this test is failed on libgdbm 1.8.0
-      assert_nil(gdbm = GDBM.open("tmptest_gdbm", nil))
+      assert_nil(gdbm = GDBM.open("tmptest_gdbm", nil),
+                 "this test is failed on libgdbm 1.8.0")
     ensure
       gdbm.close if gdbm
     end
Index: ruby_1_8_7/eval.c
===================================================================
--- ruby_1_8_7/eval.c	(revision 16192)
+++ ruby_1_8_7/eval.c	(revision 16193)
@@ -8471,6 +8471,35 @@
     return bind;
 }
 
+/*
+ *  call-seq:
+ *     binding.eval(string [, filename [,lineno]])  => obj
+ *
+ *  Evaluates the Ruby expression(s) in <em>string</em>, in the
+ *  <em>binding</em>'s context.  If the optional <em>filename</em> and
+ *  <em>lineno</em> parameters are present, they will be used when
+ *  reporting syntax errors.
+ *
+ *     def getBinding(param)
+ *       return binding
+ *     end
+ *     b = getBinding("hello")
+ *     b.eval("param")   #=> "hello"
+ */
+
+static VALUE
+bind_eval(argc, argv, bindval)
+    int argc;
+    VALUE *argv;
+    VALUE bindval;
+{
+    VALUE args[4];
+
+    rb_scan_args(argc, argv, "12", &args[0], &args[2], &args[3]);
+    args[1] = bindval;
+    return rb_f_eval(argc+1, args, Qnil /* self will be searched in eval */);
+}
+
 #define PROC_TSHIFT (FL_USHIFT+1)
 #define PROC_TMASK  (FL_USER1|FL_USER2|FL_USER3)
 #define PROC_TMAX   (PROC_TMASK >> PROC_TSHIFT)
@@ -9899,6 +9928,7 @@
     rb_undef_method(CLASS_OF(rb_cBinding), "new");
     rb_define_method(rb_cBinding, "clone", proc_clone, 0);
     rb_define_method(rb_cBinding, "dup", proc_dup, 0);
+    rb_define_method(rb_cBinding, "eval", bind_eval, -1);
     rb_define_global_function("binding", rb_f_binding, 0);
 }
 
@@ -10441,7 +10471,7 @@
 }
 
 #define THREAD_SAVE_CONTEXT(th) \
-    (rb_thread_switch((FLUSH_REGISTER_WINDOWS, ruby_setjmp(rb_thread_save_context(th), (th)->context))))
+    (rb_thread_switch(ruby_setjmp(rb_thread_save_context(th), (th)->context)))
 
 NORETURN(static void rb_thread_restore_context _((rb_thread_t,int)));
 NORETURN(NOINLINE(static void rb_thread_restore_context_0(rb_thread_t,int,void*)));

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]