--Boundary-00QRZAHn85ZLATsE
Content-Type: Multipart/Mixed;
  boundaryoundary-00QRZAHn85ZLATsE"


--Boundary-00QRZAHn85ZLATsE
Content-Type: text/plain;
  charsets-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

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  il, isapop  alse )

def initialize( addr, port  il, isapop  alse, 
                usessl  alse, certs  il, verify  il)

How does this look?

-- 
Daniel Hobe <daniel / nightrunner.com>
http://www.nightrunner.com

--Boundary-00QRZAHn85ZLATsE
Content-Type: text/x-diff;
  charsets-ascii";
  nameop.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filenameop.patch"

--- pop.rb	2004-03-25 19:38:12.000000000 -0800
+++ /home/hobe/bin/ruby/lib/ruby/1.9/net/pop.rb	2004-03-25 22:20:37.000000000 -0800
@@ -141,10 +141,25 @@
 # 
 #     # Use APOP authentication if $isapop true
 #     pop  et::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  et::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  il,
                       account  il, password  il,
-                      isapop  alse, &block )  # :yields: message
-      start(address, port, account, password, isapop) {|pop|
+                      isapop  alse, usessl  alse, certs  il, 
+                      verify  il, &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  il,
                          account  il, password  il,
-                         isapop  alse, &block )
-      start(address, port, account, password, isapop) {|pop|
+                         isapop  alse, usessl  alse, certs  il, 
+                         verify  il, &block )
+      start(address, port, account, password, isapop, usessl, certs, verify) {
+        |pop|
         pop.delete_all(&block)
       }
     end
@@ -282,19 +313,27 @@
     #     # 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  il,
                         account  il, password  il,
-                        isapop  alse )
-      new(address, port, isapop).auth_only account, password
+                        isapop  alse, usessl  alse, certs  il, 
+                        verify  il)
+      new(address, port, isapop, usessl, certs, verify).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, usessl  alse, 
+                   certs  il, verify  il)
       raise IOError, 'opening already opened POP session' if started?
-      start(account, password) {
+      start(account, password, usessl, certs, verify) {
         ;
       }
     end
@@ -304,7 +343,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 +359,36 @@
     #
     def POP3.start( address, port  il,
                     account  il, password  il,
-                    isapop  alse, &block ) # :yield: pop
-      new(address, port, isapop).start(account, password, &block)
+                    isapop  alse, usessl  alse, certs  il, 
+                    verify  il, &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.
+    # 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.  Defaults to +false+.
+    # The optional +certs+ indicates the path or file containing the CA 
+    # cert of the server.  Defaults to +nil+.
+    # The optional +verify+ parameter determines what kind of verification to 
+    # perform on the server certificate. Defaults to OpenSSL::SSL::VERIFY_PEER
     # This method does *not* open the TCP connection.
-    def initialize( addr, port  il, isapop  alse )
+    def initialize( addr, port  il, isapop  alse, 
+                    usessl  alse, certs  il, verify  il)
+                    
       @address  ddr
-      @port  ort || self.class.default_port
+      @usessl  sessl      
+      @port  ort || @usessl ? self.class.default_ssl_port : self.class.default_port
       @apop  sapop
-
+      
+      @certs  erts
+      @verify  erify
+      
       @command  il
       @socket  il
       @started  alse
@@ -408,7 +462,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, usessl  alse, 
+               certs  il, verify  il) # :yield: pop
       raise IOError, 'POP session already started' if @started
 
       if block_given?
@@ -425,9 +480,23 @@
     end
 
     def do_start( account, password )
-      @socket  nternetMessageIO.new(timeout(@open_timeout) {
-                  TCPSocket.open(@address, @port)
-                })
+      s  imeout(@open_timeout) { TCPSocket.open(@address, @port) }
+      if @usessl
+        unless defined?(OpenSSL)
+          raise "SSL extension not installed"
+        end
+        sslctx  penSSL::SSL::SSLContext.new
+        @verify  penSSL::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  penSSL::SSL::SSLSocket.new(s, sslctx)
+        s.sync_close  rue
+        s.connect
+      end
+      
+      @socket  nternetMessageIO.new(s)
+      
       logging "POP session started: #{@address}:#{@port} (#{@apop ? 'APOP' : 'POP'})"
       @socket.read_timeout  read_timeout
       @socket.debug_output  debug_output

--Boundary-00QRZAHn85ZLATsE--
--Boundary-00QRZAHn85ZLATsE--