rgrove-larch 1.0.0.6 → 1.0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY CHANGED
@@ -2,8 +2,10 @@ Larch History
2
2
  ================================================================================
3
3
 
4
4
  Version 1.0.1 (?)
5
+ * Ruby 1.9.1 support.
5
6
  * Much more robust handling of unexpected server disconnects and dropped
6
7
  connections.
8
+ * Option to verify server SSL certificates.
7
9
  * Fix excessive post-scan processing times for very large mailboxes.
8
10
  * Fetch message headers in blocks of up to 1024 at a time rather than all at
9
11
  once, to prevent potential problems with certain servers when a mailbox
data/bin/larch CHANGED
@@ -22,18 +22,21 @@ EOS
22
22
  opt :from, "URI of the source IMAP server.", :short => '-f', :type => :string, :required => true
23
23
  opt :to, "URI of the destination IMAP server.", :short => '-t', :type => :string, :required => true
24
24
 
25
- text "\nOptions:"
26
-
27
- # opt :dry_run, "Don't actually do anything.", :short => '-n'
28
- opt :fast_scan, "Use a faster (but less accurate) method to scan mailboxes. This may result in messages being re-copied.", :short => :none
25
+ text "\nCopy Options:"
29
26
  opt :from_folder, "Source folder to copy from", :short => :none, :default => 'INBOX'
30
27
  opt :from_pass, "Source server password (Default: prompt)", :short => :none, :type => :string
31
28
  opt :from_user, "Source server username (Default: prompt)", :short => :none, :type => :string
32
- opt :max_retries, "Maximum number of times to retry after a recoverable error", :short => :none, :default => 3
33
- opt :no_create_folder, "Don't create destination folders that don't already exist", :short => :none
34
29
  opt :to_folder, "Destination folder to copy to", :short => :none, :default => 'INBOX'
35
30
  opt :to_pass, "Destination server password (Default: prompt)", :short => :none, :type => :string
36
31
  opt :to_user, "Destination server username (Default: prompt)", :short => :none, :type => :string
32
+
33
+ text "\nGeneral Options:"
34
+ # opt :dry_run, "Don't actually do anything.", :short => '-n'
35
+ opt :fast_scan, "Use a faster (but less accurate) method to scan mailboxes. This may result in messages being re-copied.", :short => :none
36
+ opt :max_retries, "Maximum number of times to retry after a recoverable error", :short => :none, :default => 3
37
+ opt :no_create_folder, "Don't create destination folders that don't already exist", :short => :none
38
+ opt :ssl_certs, "Path to a trusted certificate bundle to use to verify server SSL certificates", :short => :none
39
+ opt :ssl_verify, "Verify server SSL certificates", :short => :none
37
40
  opt :verbosity, "Output verbosity: debug, info, warn, error, or fatal", :short => '-V', :default => 'info'
38
41
  end
39
42
 
@@ -78,17 +81,21 @@ EOS
78
81
 
79
82
  source = IMAP.new(options[:from], options[:from_user], options[:from_pass],
80
83
  :fast_scan => options[:fast_scan],
81
- :max_retries => options[:max_retries])
84
+ :max_retries => options[:max_retries],
85
+ :ssl_certs => options[:ssl_certs] || nil,
86
+ :ssl_verify => options[:ssl_verify])
82
87
 
83
88
  dest = IMAP.new(options[:to], options[:to_user], options[:to_pass],
84
89
  :create_mailbox => !options[:no_create_folder],
85
90
  :fast_scan => options[:fast_scan],
86
- :max_retries => options[:max_retries])
91
+ :max_retries => options[:max_retries],
92
+ :ssl_certs => options[:ssl_certs] || nil,
93
+ :ssl_verify => options[:ssl_verify])
87
94
 
88
95
  unless RUBY_PLATFORM =~ /mswin|mingw|bccwin|wince|java/
89
96
  begin
90
97
  for sig in [:SIGINT, :SIGQUIT, :SIGTERM]
91
- trap(sig) { @log.fatal "Interrupted (#{sig})"; exit }
98
+ trap(sig) { @log.fatal "Interrupted (#{sig})"; Kernel.exit }
92
99
  end
93
100
  rescue => e
94
101
  end
data/lib/larch/imap.rb CHANGED
@@ -47,6 +47,17 @@ class IMAP
47
47
  # After a recoverable error occurs, retry the operation up to this many
48
48
  # times. Default is 3.
49
49
  #
50
+ # [:ssl_certs]
51
+ # Path to a trusted certificate bundle to use to verify server SSL
52
+ # certificates. You can download a bundle of certificate authority root
53
+ # certs at http://curl.haxx.se/ca/cacert.pem (it's up to you to verify that
54
+ # this bundle hasn't been tampered with, however; don't trust it blindly).
55
+ #
56
+ # [:ssl_verify]
57
+ # If +true+, server SSL certificates will be verified against the trusted
58
+ # certificate bundle specified in +ssl_certs+. By default, server SSL
59
+ # certificates are not verified.
60
+ #
50
61
  def initialize(uri, username, password, options = {})
51
62
  raise ArgumentError, "not an IMAP URI: #{uri}" unless uri.is_a?(URI) || uri =~ REGEX_URI
52
63
  raise ArgumentError, "must provide a username and password" unless username && password
@@ -55,7 +66,7 @@ class IMAP
55
66
  @uri = uri.is_a?(URI) ? uri : URI(uri)
56
67
  @username = username
57
68
  @password = password
58
- @options = {:max_retries => 3}.merge(options)
69
+ @options = {:max_retries => 3, :ssl_verify => false}.merge(options)
59
70
 
60
71
  @ids = {}
61
72
  @imap = nil
@@ -383,6 +394,11 @@ class IMAP
383
394
  OpenSSL::SSL::SSLError => e
384
395
 
385
396
  raise unless (retries += 1) <= @options[:max_retries]
397
+
398
+ # Special check to ensure that we don't retry on OpenSSL certificate
399
+ # verification errors.
400
+ raise if e.is_a?(OpenSSL::SSL::SSLError) && e.message =~ /certificate verify failed/
401
+
386
402
  info "#{e.class.name}: #{e.message} (will retry)"
387
403
 
388
404
  reset
@@ -449,7 +465,9 @@ class IMAP
449
465
 
450
466
  Thread.new do
451
467
  begin
452
- @imap = Net::IMAP.new(host, port, ssl?)
468
+ @imap = Net::IMAP.new(host, port, ssl?,
469
+ ssl? && @options[:ssl_verify] ? @options[:ssl_certs] : nil,
470
+ @options[:ssl_verify])
453
471
 
454
472
  info "connected on port #{port}" << (ssl? ? ' using SSL' : '')
455
473
 
@@ -483,7 +501,6 @@ class IMAP
483
501
 
484
502
  rescue => e
485
503
  exception = e
486
- error e.message
487
504
  end
488
505
  end.join
489
506
 
data/lib/larch/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Larch
2
2
  APP_NAME = 'Larch'
3
- APP_VERSION = '1.0.0.6'
3
+ APP_VERSION = '1.0.0.7'
4
4
  APP_AUTHOR = 'Ryan Grove'
5
5
  APP_EMAIL = 'ryan@wonko.com'
6
6
  APP_URL = 'http://github.com/rgrove/larch/'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgrove-larch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.6
4
+ version: 1.0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Grove