--Boundary-00 QRZAHn85ZLATsE
Content-Type: Multipart/Mixed;
boundaryoundary-00 QRZAHn85ZLATsE"
--Boundary-00 QRZAHn85ZLATsE
Content-Type: text/plain;
charset s-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-00 QRZAHn85ZLATsE
Content-Type: text/x-diff;
charset s-ascii";
name op.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename op.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-00 QRZAHn85ZLATsE--
--Boundary-00 QRZAHn85ZLATsE--