[#2529] concerns about Proc,lambda,block — "David A. Black" <dblack@...>

Hi --

39 messages 2004/03/01
[#2531] Re: concerns about Proc,lambda,block — ts <decoux@...> 2004/03/01

>>>>> "D" == David A Black <dblack@wobblini.net> writes:

[#2533] Re: concerns about Proc,lambda,block — "David A. Black" <dblack@...> 2004/03/01

Hi --

[#2537] Re: concerns about Proc,lambda,block — matz@... (Yukihiro Matsumoto) 2004/03/01

Hi,

[#2542] Re: concerns about Proc,lambda,block — Mathieu Bouchard <matju@...> 2004/03/02

[#2545] Re: concerns about Proc,lambda,block — matz@... (Yukihiro Matsumoto) 2004/03/02

Hi,

[#2550] Re: concerns about Proc,lambda,block — Mauricio Fern疣dez <batsman.geo@...> 2004/03/03

On Wed, Mar 03, 2004 at 07:51:10AM +0900, Yukihiro Matsumoto wrote:

[#2703] Proposed patch to add SSL support to net/pop.rb — Daniel Hobe <daniel@...>

This patch adds support to Net::POP for doing POP over SSL. Modeled on how

19 messages 2004/03/27
[#2704] Re: Proposed patch to add SSL support to net/pop.rb — Daniel Hobe <daniel@...> 2004/03/27

This is v2 of the patch. Cleaned up a bit and added some more docs.

[#2707] Re: Proposed patch to add SSL support to net/pop.rb — Daniel Hobe <daniel@...> 2004/03/28

v3 of the patch:

[#2721] Re: Proposed patch to add SSL support to net/pop.rb — Minero Aoki <aamine@...> 2004/03/30

Hi,

Re: Proposed patch to add SSL support to net/pop.rb

From: Daniel Hobe <daniel@...>
Date: 2004-03-27 21:40:21 UTC
List: ruby-core #2704
This is v2 of the patch.  Cleaned up a bit and added some more docs.

On Friday 26 March 2004 09:41 pm, Daniel Hobe wrote:
>This patch adds support to Net::POP for doing POP over SSL.  Modeled on how 
>net/imap.rb handles SSL.

>The main change is this:
>def initialize( addr, port = nil, isapop = false )

> def initialize( addr, port = nil, isapop = false, 
>                usessl = false, certs = nil, verify = nil)

How does this look?
-- 
Daniel Hobe <daniel@nightrunner.com>
http://www.nightrunner.com

Attachments (1)

pop.patch_v2 (7.43 KB, text/x-diff)
--- pop.rb	2004-03-25 19:38:12.000000000 -0800
+++ /home/hobe/bin/ruby/lib/ruby/1.9/net/pop.rb	2004-03-27 13:15:38.000000000 -0800
@@ -141,10 +141,25 @@
 # 
 #     # Use APOP authentication if $isapop == true
 #     pop = Net::POP3.APOP($is_apop).new('apop.example.com', 110)
-#     pop.start(YourAccount', 'YourPassword') {|pop|
+#     pop.start('YourAccount', 'YourPassword') {|pop|
 #       # Rest code is same.
 #     }
-# 
+#
+# === Using SSL
+# The net/pop library supports POP3 over SSL.
+# See documentaion of Net::POP3.new() for argument descriptions
+# To use SSL:
+#
+#     require 'net/pop'
+#     
+#     
+#     pop = Net::POP3.start('pop.example.com', 995,
+#                           'YourAccount', 'YourPassword',false,true,
+#                           '/etc/ssl/certs',OpenSSL::SSL::VERIFY_PEER) {|pop|
+#       # Rest code is same.
+#     }
+#
+#
 # === Fetch Only Selected Mail Using `UIDL' POP Command
 # 
 # If your POP server provides UIDL functionality,
@@ -170,6 +185,11 @@
 require 'digest/md5'
 require 'timeout'
 
+begin
+  require "openssl"
+rescue LoadError
+end
+
 module Net
 
   # Non-authentication POP3 protocol error
@@ -200,6 +220,12 @@
     def POP3.default_port
       110
     end
+    
+    # The default port for POP3S connections, port 995
+    def POP3.default_ssl_port
+      995
+    end
+
 
     def POP3.socket_type   #:nodoc: obsolete
       Net::InternetMessageIO
@@ -228,7 +254,8 @@
     # yielding it to the +block+.
     # This method is equivalent to:
     #
-    #     Net::POP3.start(address, port, account, password) {|pop|
+    #     Net::POP3.start(address, port, account, password,
+    #                     isapop, usessl, certs, verify) {|pop|
     #       pop.each_mail do |m|
     #         yield m
     #       end
@@ -245,8 +272,10 @@
     #
     def POP3.foreach( address, port = nil,
                       account = nil, password = nil,
-                      isapop = false, &block )  # :yields: message
-      start(address, port, account, password, isapop) {|pop|
+                      isapop = false, usessl = false, certs = nil, 
+                      verify = nil, &block )  # :yields: message
+      start(address, port, account, password, isapop, usessl, certs, verify) {
+        |pop|
         pop.each_mail(&block)
       }
     end
@@ -265,8 +294,10 @@
     #
     def POP3.delete_all( address, port = nil,
                          account = nil, password = nil,
-                         isapop = false, &block )
-      start(address, port, account, password, isapop) {|pop|
+                         isapop = false, usessl = false, certs = nil, 
+                         verify = nil, &block )
+      start(address, port, account, password, isapop, usessl, certs, verify) {
+        |pop|
         pop.delete_all(&block)
       }
     end
@@ -282,11 +313,18 @@
     #     # Example 2: APOP
     #     Net::POP3.auth_only('pop.example.com', 110,
     #                         'YourAccount', 'YourPassword', true)
-    #
+    #     
+    #     # Example 3: POP over SSL
+    #     Net::POP3.auth_only('pop.example.com', 995,
+    #                         'YourAccount', 'YourPassword',false,true,
+    #                         '/etc/ssl/certs',OpenSSL::SSL::VERIFY_PEER)
+    #                         
     def POP3.auth_only( address, port = nil,
                         account = nil, password = nil,
-                        isapop = false )
-      new(address, port, isapop).auth_only account, password
+                        isapop = false, usessl = false, certs = nil, 
+                        verify = nil)
+      new(address, port, isapop, usessl, certs, verify).auth_only(
+                                                            account, password)
     end
 
     # Starts a pop3 session, attempts authentication, and quits.
@@ -294,7 +332,7 @@
     # This method raises POPAuthenticationError if authentication fails.
     def auth_only( account, password )
       raise IOError, 'opening already opened POP session' if started?
-      start(account, password) {
+      start(account, password, usessl, certs, verify) {
         ;
       }
     end
@@ -304,7 +342,7 @@
     #
 
     # Creates a new POP3 object and open the connection.  Equivalent to 
-    # Net::POP3.new(address, port, isapop).start(account, password)
+    # Net::POP3.new(address, port, isapop, usessl, certs, verify).start(account, password)
     #
     # If +block+ is provided, yields the newly-opened POP3 object to it,
     # and automatically closes it at the end of the session.
@@ -320,21 +358,37 @@
     #
     def POP3.start( address, port = nil,
                     account = nil, password = nil,
-                    isapop = false, &block ) # :yield: pop
-      new(address, port, isapop).start(account, password, &block)
+                    isapop = false, usessl = false, certs = nil, 
+                    verify = nil, &block ) # :yield: pop
+      new(address, port, isapop, usessl, certs, verify).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.
+    # +addr+ is the hostname or ip address of your POP3 server.
+    # The optional +port+ is the port to connect to; it defaults to 110 or 995
+    # if +usessl+ = +true+.
     # The optional +isapop+ specifies whether this connection is going
     # to use APOP authentication; it defaults to +false+.
+    # The optional +usessl+ specifies whether to use ssl to connect to the
+    # POP3 server; it defaults to +false+.
+    # The optional +certs+ indicates the path or file containing the CA 
+    # cert of the server; it defaults to +nil+.
+    # The optional +verify+ parameter determines what kind of verification to 
+    # perform on the server certificate; it defaults to 
+    # OpenSSL::SSL::VERIFY_PEER.
     # This method does *not* open the TCP connection.
-    def initialize( addr, port = nil, isapop = false )
+    def initialize( addr, port = nil, isapop = false, 
+                    usessl = false, certs = nil, verify = nil)
+                    
       @address = addr
-      @port = port || self.class.default_port
+      @usessl = usessl      
+      @port = port || @usessl ? self.class.default_ssl_port : self.class.default_port
       @apop = isapop
-
+      
+      @certs = certs
+      @verify = verify
+      
       @command = nil
       @socket = nil
       @started = false
@@ -425,9 +479,23 @@
     end
 
     def do_start( account, password )
-      @socket = InternetMessageIO.new(timeout(@open_timeout) {
-                  TCPSocket.open(@address, @port)
-                })
+      s = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
+      if @usessl
+        unless defined?(OpenSSL)
+          raise "SSL extension not installed"
+        end
+        sslctx = OpenSSL::SSL::SSLContext.new
+        @verify = OpenSSL::SSL::VERIFY_PEER if @verify.nil?
+        sslctx.verify_mode = @verify
+        sslctx.ca_file = @certs if @certs && FileTest::file?(@certs)
+        sslctx.ca_path = @certs if @certs && FileTest::directory?(@certs)
+        s = OpenSSL::SSL::SSLSocket.new(s, sslctx)
+        s.sync_close = true
+        s.connect
+      end
+      
+      @socket = InternetMessageIO.new(s)
+      
       logging "POP session started: #{@address}:#{@port} (#{@apop ? 'APOP' : 'POP'})"
       @socket.read_timeout = @read_timeout
       @socket.debug_output = @debug_output

In This Thread