332
332
# Sends a STARTTLS command to start TLS session.
333
def starttls(ctx = nil)
334
if @sock.kind_of?(OpenSSL::SSL::SSLSocket)
335
raise RuntimeError, "already using SSL"
333
def starttls(options = {}, verify = true)
337
334
send_command("STARTTLS") do |resp|
338
335
if resp.kind_of?(TaggedResponse) && resp.name == "OK"
340
@sock = OpenSSL::SSL::SSLSocket.new(@sock, ctx)
342
@sock = OpenSSL::SSL::SSLSocket.new(@sock)
337
# for backward compatibility
338
certs = options.to_str
339
options = create_ssl_params(certs, verify)
344
@sock.sync_close = true
342
start_tls_session(options)
856
853
base64.unpack("m")[0].unpack("n*").pack("U*")
855
}.force_encoding("UTF-8")
861
858
# Encode a string from UTF-8 format to modified UTF-7.
862
859
def self.encode_utf7(s)
863
return s.gsub(/(&)|([^\x20-\x25\x27-\x7e]+)/n) { |x|
860
return s.gsub(/(&)|([^\x20-\x25\x27-\x7e]+)/u) { |x|
867
864
base64 = [x.unpack("U*").pack("n*")].pack("m")
868
865
"&" + base64.delete("=\n").tr("/", ",") + "-"
867
}.force_encoding("ASCII-8BIT")
875
872
CRLF = "\r\n" # :nodoc:
876
873
PORT = 143 # :nodoc:
874
SSL_PORT = 993 # :nodoc:
879
877
@@authenticators = {}
880
# Net::IMAP.new(host, options = {})
881
882
# Creates a new Net::IMAP object and connects it to the specified
882
# +port+ (143 by default) on the named +host+. If +usessl+ is true,
883
# then an attempt will
884
# be made to use SSL (now TLS) to connect to the server. For this
885
# to work OpenSSL [OSSL] and the Ruby OpenSSL [RSSL]
886
# extensions need to be installed. The +certs+ parameter indicates
887
# the path or file containing the CA cert of the server, and the
888
# +verify+ parameter is for the OpenSSL verification callback.
885
# +options+ is an option hash, each key of which is a symbol.
887
# The available options are:
889
# port:: port number (default value is 143 for imap, or 993 for imaps)
890
# ssl:: if options[:ssl] is true, then an attempt will be made
891
# to use SSL (now TLS) to connect to the server. For this to work
892
# OpenSSL [OSSL] and the Ruby OpenSSL [RSSL] extensions need to
894
# if options[:ssl] is a hash, it's passed to
895
# OpenSSL::SSL::SSLContext#set_params as parameters.
890
897
# The most common errors are:
897
904
# SocketError:: hostname not known or other socket error.
898
905
# Net::IMAP::ByeResponseError:: we connected to the host, but they
899
906
# immediately said goodbye to us.
900
def initialize(host, port = PORT, usessl = false, certs = nil, verify = false)
907
def initialize(host, port_or_options = {},
908
usessl = false, certs = nil, verify = true)
912
options = port_or_options.to_hash
914
# for backward compatibility
916
options[:port] = port_or_options
918
options[:ssl] = create_ssl_params(certs, verify)
921
@port = options[:port] || (options[:ssl] ? SSL_PORT : PORT)
904
922
@tag_prefix = "RUBY"
906
924
@parser = ResponseParser.new
907
@sock = TCPSocket.open(host, port)
909
unless defined?(OpenSSL)
910
raise "SSL extension not installed"
925
@sock = TCPSocket.open(@host, @port)
927
start_tls_session(options[:ssl])
915
context = SSLContext::new()
916
context.ca_file = certs if certs && FileTest::file?(certs)
917
context.ca_path = certs if certs && FileTest::directory?(certs)
918
context.verify_mode = VERIFY_PEER if verify
919
if defined?(VerifyCallbackProc)
920
context.verify_callback = VerifyCallbackProc
922
@sock = SSLSocket.new(@sock, context)
923
@sock.connect # start ssl session.
1237
def create_ssl_params(certs = nil, verify = true)
1240
if File.file?(certs)
1241
params[:ca_file] = certs
1242
elsif File.directory?(certs)
1243
params[:ca_path] = certs
1247
params[:verify_mode] = VERIFY_PEER
1249
params[:verify_mode] = VERIFY_NONE
1254
def start_tls_session(params = {})
1255
unless defined?(OpenSSL)
1256
raise "SSL extension not installed"
1258
if @sock.kind_of?(OpenSSL::SSL::SSLSocket)
1259
raise RuntimeError, "already using SSL"
1262
params = params.to_hash
1263
rescue NoMethodError
1266
context = SSLContext.new
1267
context.set_params(params)
1268
if defined?(VerifyCallbackProc)
1269
context.verify_callback = VerifyCallbackProc
1271
@sock = SSLSocket.new(@sock, context)
1272
@sock.sync_close = true
1274
if context.verify_mode != VERIFY_NONE
1275
@sock.post_connection_check(@host)
1232
1279
class RawData # :nodoc:
1233
1280
def send_data(imap)
1234
imap.send!(:put_string, @data)
1281
imap.send(:put_string, @data)
2993
3040
parse_error("unknown token - %s", $&.dump)
2996
parse_error("illegal @lex_state - %s", @lex_state.inspect)
3043
parse_error("invalid @lex_state - %s", @lex_state.inspect)
3303
$port ||= $ssl ? 993 : 143
3305
imap = Net::IMAP.new($host, $port, $ssl)
3351
imap = Net::IMAP.new($host, :port => $port, :ssl => $ssl)
3307
3353
password = get_password
3308
3354
imap.authenticate($auth, $user, password)