~ubuntu-branches/ubuntu/trusty/ruby1.9/trusty

« back to all changes in this revision

Viewing changes to lib/net/imap.rb

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2008-01-24 11:42:29 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20080124114229-jw2f87rdxlq6gp11
Tags: 1.9.0.0-2ubuntu1
* Merge from debian unstable, remaining changes:
  - Robustify check for target_os, fixing build failure on lpia.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
require "digest/md5"
19
19
require "strscan"
20
20
begin
21
 
  require "openssl"
 
21
  require "openssl/ssl"
22
22
rescue LoadError
23
23
end
24
24
 
330
330
    end
331
331
 
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"
336
 
      end
 
333
    def starttls(options = {}, verify = true)
337
334
      send_command("STARTTLS") do |resp|
338
335
        if resp.kind_of?(TaggedResponse) && resp.name == "OK"
339
 
          if ctx
340
 
            @sock = OpenSSL::SSL::SSLSocket.new(@sock, ctx)
341
 
          else
342
 
            @sock = OpenSSL::SSL::SSLSocket.new(@sock)
 
336
          begin
 
337
            # for backward compatibility
 
338
            certs = options.to_str
 
339
            options = create_ssl_params(certs, verify)
 
340
          rescue NoMethodError
343
341
          end
344
 
          @sock.sync_close = true
345
 
          @sock.connect
 
342
          start_tls_session(options)
346
343
        end
347
344
      end
348
345
    end
855
852
          end
856
853
          base64.unpack("m")[0].unpack("n*").pack("U*")
857
854
        end
858
 
      }
 
855
      }.force_encoding("UTF-8")
859
856
    end
860
857
 
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|
864
861
        if $1
865
862
          "&-"
866
863
        else
867
864
          base64 = [x.unpack("U*").pack("n*")].pack("m")
868
865
          "&" + base64.delete("=\n").tr("/", ",") + "-"
869
866
        end
870
 
      }
 
867
      }.force_encoding("ASCII-8BIT")
871
868
    end
872
869
 
873
870
    private
874
871
 
875
872
    CRLF = "\r\n"      # :nodoc:
876
873
    PORT = 143         # :nodoc:
 
874
    SSL_PORT = 993   # :nodoc:
877
875
 
878
876
    @@debug = false
879
877
    @@authenticators = {}
880
878
 
 
879
    # call-seq:
 
880
    #    Net::IMAP.new(host, options = {})
 
881
    #
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.
 
883
    # +host+.
 
884
    #
 
885
    # +options+ is an option hash, each key of which is a symbol.
 
886
    #
 
887
    # The available options are:
 
888
    #
 
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
 
893
    #         be installed.
 
894
    #         if options[:ssl] is a hash, it's passed to 
 
895
    #         OpenSSL::SSL::SSLContext#set_params as parameters.
889
896
    #
890
897
    # The most common errors are:
891
898
    #
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)
901
909
      super()
902
910
      @host = host
903
 
      @port = port
 
911
      begin
 
912
        options = port_or_options.to_hash
 
913
      rescue NoMethodError
 
914
        # for backward compatibility
 
915
        options = {}
 
916
        options[:port] = port_or_options
 
917
        if usessl
 
918
          options[:ssl] = create_ssl_params(certs, verify)
 
919
        end
 
920
      end
 
921
      @port = options[:port] || (options[:ssl] ? SSL_PORT : PORT)
904
922
      @tag_prefix = "RUBY"
905
923
      @tagno = 0
906
924
      @parser = ResponseParser.new
907
 
      @sock = TCPSocket.open(host, port)
908
 
      if usessl
909
 
        unless defined?(OpenSSL)
910
 
          raise "SSL extension not installed"
911
 
        end
 
925
      @sock = TCPSocket.open(@host, @port)
 
926
      if options[:ssl]
 
927
        start_tls_session(options[:ssl])
912
928
        @usessl = true
913
 
 
914
 
        # verify the server.
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 
921
 
        end
922
 
        @sock = SSLSocket.new(@sock, context)
923
 
        @sock.connect   # start ssl session.
924
929
      else
925
930
        @usessl = false
926
931
      end
1229
1234
      end
1230
1235
    end
1231
1236
 
 
1237
    def create_ssl_params(certs = nil, verify = true)
 
1238
      params = {}
 
1239
      if certs
 
1240
        if File.file?(certs)
 
1241
          params[:ca_file] = certs
 
1242
        elsif File.directory?(certs)
 
1243
          params[:ca_path] = certs
 
1244
        end
 
1245
      end
 
1246
      if verify
 
1247
        params[:verify_mode] = VERIFY_PEER
 
1248
      else
 
1249
        params[:verify_mode] = VERIFY_NONE
 
1250
      end
 
1251
      return params
 
1252
    end
 
1253
 
 
1254
    def start_tls_session(params = {})
 
1255
      unless defined?(OpenSSL)
 
1256
        raise "SSL extension not installed"
 
1257
      end
 
1258
      if @sock.kind_of?(OpenSSL::SSL::SSLSocket)
 
1259
        raise RuntimeError, "already using SSL"
 
1260
      end
 
1261
      begin
 
1262
        params = params.to_hash
 
1263
      rescue NoMethodError
 
1264
        params = {}
 
1265
      end
 
1266
      context = SSLContext.new
 
1267
      context.set_params(params)
 
1268
      if defined?(VerifyCallbackProc)
 
1269
        context.verify_callback = VerifyCallbackProc 
 
1270
      end
 
1271
      @sock = SSLSocket.new(@sock, context)
 
1272
      @sock.sync_close = true
 
1273
      @sock.connect
 
1274
      if context.verify_mode != VERIFY_NONE
 
1275
        @sock.post_connection_check(@host)
 
1276
      end
 
1277
    end
 
1278
 
1232
1279
    class RawData # :nodoc:
1233
1280
      def send_data(imap)
1234
 
        imap.send!(:put_string, @data)
 
1281
        imap.send(:put_string, @data)
1235
1282
      end
1236
1283
 
1237
1284
      private
1243
1290
 
1244
1291
    class Atom # :nodoc:
1245
1292
      def send_data(imap)
1246
 
        imap.send!(:put_string, @data)
 
1293
        imap.send(:put_string, @data)
1247
1294
      end
1248
1295
 
1249
1296
      private
1255
1302
 
1256
1303
    class QuotedString # :nodoc:
1257
1304
      def send_data(imap)
1258
 
        imap.send!(:send_quoted_string, @data)
 
1305
        imap.send(:send_quoted_string, @data)
1259
1306
      end
1260
1307
 
1261
1308
      private
1267
1314
 
1268
1315
    class Literal # :nodoc:
1269
1316
      def send_data(imap)
1270
 
        imap.send!(:send_literal, @data)
 
1317
        imap.send(:send_literal, @data)
1271
1318
      end
1272
1319
 
1273
1320
      private
1279
1326
 
1280
1327
    class MessageSet # :nodoc:
1281
1328
      def send_data(imap)
1282
 
        imap.send!(:put_string, format_internal(@data))
 
1329
        imap.send(:put_string, format_internal(@data))
1283
1330
      end
1284
1331
 
1285
1332
      private
2993
3040
            parse_error("unknown token - %s", $&.dump)
2994
3041
          end
2995
3042
        else
2996
 
          parse_error("illegal @lex_state - %s", @lex_state.inspect)
 
3043
          parse_error("invalid @lex_state - %s", @lex_state.inspect)
2997
3044
        end
2998
3045
      end
2999
3046
 
3300
3347
    usage
3301
3348
    exit(1)
3302
3349
  end
3303
 
  $port ||= $ssl ? 993 : 143
3304
3350
    
3305
 
  imap = Net::IMAP.new($host, $port, $ssl)
 
3351
  imap = Net::IMAP.new($host, :port => $port, :ssl => $ssl)
3306
3352
  begin
3307
3353
    password = get_password
3308
3354
    imap.authenticate($auth, $user, password)