ipaccess 0.0.4 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- checksums.yaml.gz.sig +1 -0
- data.tar.gz.sig +0 -0
- data/.gemtest +0 -0
- data/.rspec +1 -0
- data/.yardopts +12 -0
- data/ChangeLog +1495 -0
- data/{docs/LGPL-LICENSE → LGPL-LICENSE} +0 -0
- data/Manifest.txt +76 -0
- data/README.md +96 -0
- data/Rakefile +65 -42
- data/docs/COPYING +41 -45
- data/docs/FAQ +12 -0
- data/docs/HISTORY +17 -0
- data/docs/LEGAL +1 -1
- data/docs/LGPL +166 -0
- data/docs/TODO +150 -7
- data/docs/images/ipaccess.png +0 -0
- data/docs/images/ipaccess_ac_for_args.png +0 -0
- data/docs/images/ipaccess_ac_for_socket.png +0 -0
- data/docs/images/ipaccess_logo.png +0 -0
- data/docs/images/ipaccess_relations.png +0 -0
- data/docs/images/ipaccess_setup_origin.png +0 -0
- data/docs/images/ipaccess_setup_origin_tab.png +0 -0
- data/docs/images/ipaccess_view.png +0 -0
- data/docs/rdoc.css +22 -0
- data/examples/ftp.rb +62 -0
- data/examples/http.rb +81 -0
- data/examples/imap.rb +37 -0
- data/examples/pop.rb +31 -0
- data/examples/smtp.rb +26 -0
- data/examples/tcp_server.rb +32 -0
- data/examples/tcp_socket.rb +7 -3
- data/examples/telnet.rb +32 -0
- data/examples/text_message.rb +45 -0
- data/lib/ipaccess.rb +557 -7
- data/lib/ipaccess/arm_sockets.rb +7 -4
- data/lib/ipaccess/ghost_doc/ghost_doc.rb +23 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_acl.rb +54 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_net_ftp.rb +213 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_net_http.rb +272 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_net_smtp.rb +186 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_net_telnet.rb +227 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_p_blacklist.rb +36 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_p_blacklist_e.rb +7 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_p_unblacklist.rb +36 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_p_unblacklist_e.rb +7 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_p_unwhitelist.rb +36 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_p_unwhitelist_e.rb +7 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_p_whitelist.rb +36 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_p_whitelist_e.rb +7 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_patched_usage.rb +64 -0
- data/lib/ipaccess/ghost_doc/ghost_doc_sockets.rb +571 -0
- data/lib/ipaccess/ip_access_check.rb +508 -0
- data/lib/ipaccess/ip_access_errors.rb +186 -40
- data/lib/ipaccess/ip_access_list.rb +955 -1122
- data/lib/ipaccess/ip_access_set.rb +212 -0
- data/lib/ipaccess/net/ftp.rb +39 -0
- data/lib/ipaccess/net/http.rb +39 -0
- data/lib/ipaccess/net/https.rb +30 -0
- data/lib/ipaccess/net/imap.rb +39 -0
- data/lib/ipaccess/net/pop.rb +46 -0
- data/lib/ipaccess/net/smtp.rb +39 -0
- data/lib/ipaccess/net/telnet.rb +38 -0
- data/lib/ipaccess/patches/generic.rb +807 -0
- data/lib/ipaccess/patches/net_ftp.rb +165 -0
- data/lib/ipaccess/patches/net_http.rb +175 -0
- data/lib/ipaccess/patches/net_https.rb +29 -0
- data/lib/ipaccess/patches/net_imap.rb +117 -0
- data/lib/ipaccess/patches/net_pop.rb +171 -0
- data/lib/ipaccess/patches/net_smtp.rb +130 -0
- data/lib/ipaccess/patches/net_telnet.rb +103 -0
- data/lib/ipaccess/{netaddr_patch.rb → patches/netaddr.rb} +20 -11
- data/lib/ipaccess/patches/sockets.rb +586 -0
- data/lib/ipaccess/socket.rb +52 -1
- data/lib/ipaccess/sockets.rb +4 -30
- data/spec/ip_access_list_spec.rb +33 -21
- data/spec/spec.opts +2 -2
- metadata +289 -63
- metadata.gz.sig +0 -0
- data/docs/DOWNLOAD +0 -17
- data/docs/README +0 -95
- data/docs/WELCOME +0 -8
- data/lib/ipaccess/ghost_doc.rb +0 -206
- data/lib/ipaccess/ghost_doc_acl.rb +0 -31
- data/lib/ipaccess/ip_access.rb +0 -456
- data/lib/ipaccess/ip_access_patches.rb +0 -431
- data/spec/core_spec.rb +0 -5
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
|
4
|
+
# Copyright:: Copyright (c) 2009-2014 by Paweł Wilk
|
|
5
|
+
# License:: This program is licensed under the terms of {GNU Lesser General Public License}[link:docs/LGPL.html] or {Ruby License}[link:docs/COPYING.html].
|
|
6
|
+
#
|
|
7
|
+
# Modules contained in this file are meant for
|
|
8
|
+
# patching Ruby's Net::FTP class in order to add
|
|
9
|
+
# IP access control to it. It is also used
|
|
10
|
+
# to create variant of Net::FTP class
|
|
11
|
+
# with IP access control.
|
|
12
|
+
#
|
|
13
|
+
#--
|
|
14
|
+
#
|
|
15
|
+
# Copyright (C) 2009 by Paweł Wilk. All Rights Reserved.
|
|
16
|
+
#
|
|
17
|
+
# This program is free software; you can redistribute it and/or modify
|
|
18
|
+
# it under the terms of either: 1) the GNU Lesser General Public License
|
|
19
|
+
# as published by the Free Software Foundation; either version 3 of the
|
|
20
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
|
21
|
+
#
|
|
22
|
+
# See the file COPYING for complete licensing information.
|
|
23
|
+
#
|
|
24
|
+
#++
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
require 'socket'
|
|
28
|
+
require 'net/ftp'
|
|
29
|
+
require 'ipaccess/ip_access_errors'
|
|
30
|
+
require 'ipaccess/patches/generic'
|
|
31
|
+
require 'ipaccess/patches/sockets'
|
|
32
|
+
|
|
33
|
+
# :stopdoc:
|
|
34
|
+
|
|
35
|
+
module IPAccess::Patches::Net
|
|
36
|
+
|
|
37
|
+
###################################################################
|
|
38
|
+
# Net::FTP class with IP access control.
|
|
39
|
+
# It uses output and occasionally input access lists.
|
|
40
|
+
|
|
41
|
+
module FTP
|
|
42
|
+
|
|
43
|
+
include IPAccess::Patches::ACL
|
|
44
|
+
|
|
45
|
+
def self.included(base)
|
|
46
|
+
|
|
47
|
+
marker = (base.name =~ /IPAccess/) ? base.superclass : base
|
|
48
|
+
return if marker.instance_variable_defined?(:@uses_ipaccess)
|
|
49
|
+
base.instance_variable_set(:@uses_ipaccess, true)
|
|
50
|
+
|
|
51
|
+
base.class_eval do
|
|
52
|
+
|
|
53
|
+
# CLASS METHODS
|
|
54
|
+
unless (base.name.nil? && base.class.name == "Class")
|
|
55
|
+
(class << self; self; end).class_eval do
|
|
56
|
+
|
|
57
|
+
# overwrite FTP.open()
|
|
58
|
+
define_method :__ipacall__open do |block, host, *args|
|
|
59
|
+
late_opened_on_deny = false
|
|
60
|
+
args.each { |x| late_opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
|
|
61
|
+
args.unshift host
|
|
62
|
+
if block.is_a?(Proc)
|
|
63
|
+
if late_opened_on_deny
|
|
64
|
+
raise ArgumentError, "The :opened_on_deny flag cannot be used when passing a block to FTP.open"
|
|
65
|
+
end
|
|
66
|
+
ftp = new(*args)
|
|
67
|
+
begin
|
|
68
|
+
block.call(ftp)
|
|
69
|
+
ensure
|
|
70
|
+
ftp.close
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
new(*args)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# block passing wrapper for Ruby 1.8
|
|
78
|
+
def open(*args, &block)
|
|
79
|
+
__ipacall__open(block, *args)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end # class methods
|
|
85
|
+
|
|
86
|
+
orig_initialize = self.instance_method :initialize
|
|
87
|
+
orig_open_socket = self.instance_method :open_socket
|
|
88
|
+
#orig_sendcmd = self.instance_method :sendcmd
|
|
89
|
+
orig_set_socket = self.instance_method :set_socket
|
|
90
|
+
orig_makeport = self.instance_method :makeport
|
|
91
|
+
|
|
92
|
+
# initialize on steroids.
|
|
93
|
+
define_method :__ipacall__initialize do |block, *args|
|
|
94
|
+
@opened_on_deny = false
|
|
95
|
+
args.delete_if { |x| @opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
|
|
96
|
+
args.pop if args.last.nil?
|
|
97
|
+
self.acl = IPAccess.valid_acl?(args.last) ? args.pop : :global
|
|
98
|
+
orig_initialize.bind(self).call(*args, &block)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# block passing wrapper for Ruby 1.8
|
|
102
|
+
def initialize(*args, &block)
|
|
103
|
+
__ipacall__initialize(block, *args)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# open_socket on steroids.
|
|
107
|
+
define_method :open_socket do |host, port|
|
|
108
|
+
unless @opened_on_deny
|
|
109
|
+
host = ::TCPSocket.getaddress(host)
|
|
110
|
+
real_acl.output.check_ipstring(host, self)
|
|
111
|
+
end
|
|
112
|
+
try_arm_and_check_socket( orig_open_socket.bind(self).call(host, port) )
|
|
113
|
+
end
|
|
114
|
+
private :open_socket
|
|
115
|
+
|
|
116
|
+
# set_socket on steroids.
|
|
117
|
+
define_method :set_socket do |sock, *args|
|
|
118
|
+
ret = orig_set_socket.bind(self).call(sock, args.first)
|
|
119
|
+
try_arm_and_check_socket(@sock, self)
|
|
120
|
+
return ret
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# sendcmd on steroids.
|
|
124
|
+
#define_method :sendcmd do |*args|
|
|
125
|
+
# acl_recheck
|
|
126
|
+
# orig_sendcmd.bind(self).call(*args)
|
|
127
|
+
#end
|
|
128
|
+
|
|
129
|
+
# makeport on steroids.
|
|
130
|
+
define_method :makeport do
|
|
131
|
+
late_sock = orig_makeport.bind(self).call
|
|
132
|
+
begin
|
|
133
|
+
try_arm_and_check_socket late_sock
|
|
134
|
+
rescue IOError
|
|
135
|
+
end
|
|
136
|
+
return late_sock
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# This method returns default access list indicator
|
|
140
|
+
# used by protected object; in this case it's +:output+.
|
|
141
|
+
define_method :default_list do
|
|
142
|
+
:output
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# this hook will be called each time @acl is reassigned
|
|
146
|
+
define_method :acl_recheck do
|
|
147
|
+
try_arm_and_check_socket @sock
|
|
148
|
+
nil
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# this hook terminates connection
|
|
152
|
+
define_method :terminate do
|
|
153
|
+
self.close unless self.closed?
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end # base.class_eval
|
|
157
|
+
|
|
158
|
+
end # self.included
|
|
159
|
+
|
|
160
|
+
end # module FTP
|
|
161
|
+
|
|
162
|
+
end # module IPAccess::Patches
|
|
163
|
+
|
|
164
|
+
# :startdoc:
|
|
165
|
+
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
|
4
|
+
# Copyright:: Copyright (c) 2009-2014 by Paweł Wilk
|
|
5
|
+
# License:: This program is licensed under the terms of {GNU Lesser General Public License}[link:docs/LGPL.html] or {Ruby License}[link:docs/COPYING.html].
|
|
6
|
+
#
|
|
7
|
+
# Modules contained in this file are meant for
|
|
8
|
+
# patching Ruby's Net::HTTP class in order to add
|
|
9
|
+
# IP access control to it. It is also used
|
|
10
|
+
# to create variant of Net::HTTP class
|
|
11
|
+
# with IP access control.
|
|
12
|
+
#
|
|
13
|
+
#--
|
|
14
|
+
#
|
|
15
|
+
# Copyright (C) 2009 by Paweł Wilk. All Rights Reserved.
|
|
16
|
+
#
|
|
17
|
+
# This program is free software; you can redistribute it and/or modify
|
|
18
|
+
# it under the terms of either: 1) the GNU Lesser General Public License
|
|
19
|
+
# as published by the Free Software Foundation; either version 3 of the
|
|
20
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
|
21
|
+
#
|
|
22
|
+
# See the file COPYING for complete licensing information.
|
|
23
|
+
#
|
|
24
|
+
#++
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
require 'socket'
|
|
28
|
+
require 'net/http'
|
|
29
|
+
require 'ipaccess/ip_access_errors'
|
|
30
|
+
require 'ipaccess/patches/generic'
|
|
31
|
+
require 'ipaccess/patches/sockets'
|
|
32
|
+
|
|
33
|
+
# :stopdoc:
|
|
34
|
+
|
|
35
|
+
module IPAccess::Patches::Net
|
|
36
|
+
|
|
37
|
+
###################################################################
|
|
38
|
+
# Net::HTTP class with IP access control.
|
|
39
|
+
# It uses output access lists.
|
|
40
|
+
|
|
41
|
+
module HTTP
|
|
42
|
+
|
|
43
|
+
include IPAccess::Patches::ACL
|
|
44
|
+
|
|
45
|
+
def self.included(base)
|
|
46
|
+
|
|
47
|
+
marker = (base.name =~ /IPAccess/) ? base.superclass : base
|
|
48
|
+
return if marker.instance_variable_defined?(:@uses_ipaccess)
|
|
49
|
+
base.instance_variable_set(:@uses_ipaccess, true)
|
|
50
|
+
|
|
51
|
+
base.class_eval do
|
|
52
|
+
|
|
53
|
+
# CLASS METHODS
|
|
54
|
+
unless (base.name.nil? && base.class.name == "Class")
|
|
55
|
+
(class << self; self; end).class_eval do
|
|
56
|
+
|
|
57
|
+
alias :__ipac__orig_new :new
|
|
58
|
+
|
|
59
|
+
# overload HTTP.new() since it's not usual.
|
|
60
|
+
define_method :new do |address, *args|
|
|
61
|
+
late_opened_on_deny = false
|
|
62
|
+
args.delete_if { |x| late_opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
|
|
63
|
+
args.pop if args.last.nil?
|
|
64
|
+
late_acl = IPAccess.valid_acl?(args.last) ? args.pop : :global
|
|
65
|
+
obj = __ipac__orig_new(address, *args)
|
|
66
|
+
obj.acl = late_acl unless obj.acl == late_acl
|
|
67
|
+
obj.opened_on_deny = late_opened_on_deny
|
|
68
|
+
return obj
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# overwrite HTTP.start()
|
|
72
|
+
define_method :__ipacall__start do |block, address, *args|
|
|
73
|
+
late_on_deny = nil
|
|
74
|
+
args.delete_if { |x| late_on_deny = x if (x.is_a?(Symbol) && x == :opened_on_deny) }
|
|
75
|
+
args.pop if args.last.nil?
|
|
76
|
+
acl = IPAccess.valid_acl?(args.last) ? args.pop : :global
|
|
77
|
+
port, p_addr, p_port, p_user, p_pass = *args
|
|
78
|
+
new(address, port, p_addr, p_port, p_user, p_pass, acl, late_on_deny).start(&block)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# block passing wrapper for Ruby 1.8
|
|
82
|
+
def start(*args, &block)
|
|
83
|
+
__ipacall__start(block, *args)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# overwrite HTTP.get_response()
|
|
87
|
+
define_method :__ipacall__get_response do |block, uri_or_host, *args|
|
|
88
|
+
late_on_deny = nil
|
|
89
|
+
args.delete_if { |x| late_on_deny = x if (x.is_a?(Symbol) && x == :opened_on_deny) }
|
|
90
|
+
args.pop if args.last.nil?
|
|
91
|
+
late_acl = IPAccess.valid_acl?(args.last) ? args.pop : :global
|
|
92
|
+
path, port = *args
|
|
93
|
+
if path
|
|
94
|
+
host = uri_or_host
|
|
95
|
+
new(host, (port || Net::HTTP.default_port), late_acl, late_on_deny).start { |http|
|
|
96
|
+
return http.request_get(path, &block)
|
|
97
|
+
}
|
|
98
|
+
else
|
|
99
|
+
uri = uri_or_host
|
|
100
|
+
new(uri.host, uri.port, late_acl, late_on_deny).start { |http|
|
|
101
|
+
return http.request_get(uri.request_uri, &block)
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# block passing wrapper for Ruby 1.8
|
|
107
|
+
def get_response(*args, &block)
|
|
108
|
+
__ipacall__get_response(block, *args)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end # class methods
|
|
114
|
+
|
|
115
|
+
orig_initialize = self.instance_method :initialize
|
|
116
|
+
orig_conn_address = self.instance_method :conn_address
|
|
117
|
+
orig_on_connect = self.instance_method :on_connect
|
|
118
|
+
|
|
119
|
+
# initialize on steroids.
|
|
120
|
+
define_method :__ipacall__initialize do |block, *args|
|
|
121
|
+
@opened_on_deny = false
|
|
122
|
+
args.delete_if { |x| @opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
|
|
123
|
+
args.pop if args.last.nil?
|
|
124
|
+
self.acl = IPAccess.valid_acl?(args.last) ? args.pop : :global
|
|
125
|
+
orig_initialize.bind(self).call(*args, &block)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# block passing wrapper for Ruby 1.8
|
|
129
|
+
def initialize(*args, &block)
|
|
130
|
+
__ipacall__initialize(block, *args)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# on_connect on steroids.
|
|
134
|
+
define_method :on_connect do
|
|
135
|
+
acl_recheck # check address form socket to be sure
|
|
136
|
+
orig_on_connect.bind(self).call
|
|
137
|
+
end
|
|
138
|
+
private :on_connect
|
|
139
|
+
|
|
140
|
+
# conn_address on steroids.
|
|
141
|
+
define_method :conn_address do
|
|
142
|
+
addr = orig_conn_address.bind(self).call
|
|
143
|
+
ipaddr = ::TCPSocket.getaddress(addr)
|
|
144
|
+
real_acl.output.check_ipstring(ipaddr, self)
|
|
145
|
+
return ipaddr
|
|
146
|
+
end
|
|
147
|
+
private :conn_address
|
|
148
|
+
|
|
149
|
+
# This method returns default access list indicator
|
|
150
|
+
# used by protected object; in this case it's +:output+.
|
|
151
|
+
define_method :default_list do
|
|
152
|
+
:output
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# this hook will be called each time @acl is reassigned
|
|
156
|
+
define_method :acl_recheck do
|
|
157
|
+
try_arm_and_check_socket @socket
|
|
158
|
+
nil
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# this hook terminates connection
|
|
162
|
+
define_method :terminate do
|
|
163
|
+
self.finish if self.started?
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
end # base.class_eval
|
|
167
|
+
|
|
168
|
+
end # self.included
|
|
169
|
+
|
|
170
|
+
end # module HTTP
|
|
171
|
+
|
|
172
|
+
end # module IPAccess::Patches
|
|
173
|
+
|
|
174
|
+
# :startdoc:
|
|
175
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
|
4
|
+
# Copyright:: Copyright (c) 2009-2014 by Paweł Wilk
|
|
5
|
+
# License:: This program is licensed under the terms of {GNU Lesser General Public License}[link:docs/LGPL.html] or {Ruby License}[link:docs/COPYING.html].
|
|
6
|
+
#
|
|
7
|
+
# Modules contained in this file are meant for
|
|
8
|
+
# patching Ruby's Net::HTTP class in order to add
|
|
9
|
+
# IP access control to it. It is also used
|
|
10
|
+
# to create variant of Net::HTTP class
|
|
11
|
+
# with IP access control.
|
|
12
|
+
#
|
|
13
|
+
#--
|
|
14
|
+
#
|
|
15
|
+
# Copyright (C) 2009 by Paweł Wilk. All Rights Reserved.
|
|
16
|
+
#
|
|
17
|
+
# This program is free software; you can redistribute it and/or modify
|
|
18
|
+
# it under the terms of either: 1) the GNU Lesser General Public License
|
|
19
|
+
# as published by the Free Software Foundation; either version 3 of the
|
|
20
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
|
21
|
+
#
|
|
22
|
+
# See the file COPYING for complete licensing information.
|
|
23
|
+
#
|
|
24
|
+
#++
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
require 'net/https'
|
|
28
|
+
require 'ipaccess/patches/net/http'
|
|
29
|
+
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
|
4
|
+
# Copyright:: Copyright (c) 2009-2014 by Paweł Wilk
|
|
5
|
+
# License:: This program is licensed under the terms of {GNU Lesser General Public License}[link:docs/LGPL.html] or {Ruby License}[link:docs/COPYING.html].
|
|
6
|
+
#
|
|
7
|
+
# Modules contained in this file are meant for
|
|
8
|
+
# patching Ruby's Net::IMAP class in order to add
|
|
9
|
+
# IP access control to it. It is also used
|
|
10
|
+
# to create variant of Net::IMAP class
|
|
11
|
+
# with IP access control.
|
|
12
|
+
#
|
|
13
|
+
#--
|
|
14
|
+
#
|
|
15
|
+
# Copyright (C) 2009 by Paweł Wilk. All Rights Reserved.
|
|
16
|
+
#
|
|
17
|
+
# This program is free software; you can redistribute it and/or modify
|
|
18
|
+
# it under the terms of either: 1) the GNU Lesser General Public License
|
|
19
|
+
# as published by the Free Software Foundation; either version 3 of the
|
|
20
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
|
21
|
+
#
|
|
22
|
+
# See the file COPYING for complete licensing information.
|
|
23
|
+
#
|
|
24
|
+
#++
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
require 'socket'
|
|
28
|
+
require 'net/imap'
|
|
29
|
+
require 'ipaccess/ip_access_errors'
|
|
30
|
+
require 'ipaccess/patches/generic'
|
|
31
|
+
require 'ipaccess/patches/sockets'
|
|
32
|
+
|
|
33
|
+
# :stopdoc:
|
|
34
|
+
|
|
35
|
+
module IPAccess::Patches::Net
|
|
36
|
+
|
|
37
|
+
###################################################################
|
|
38
|
+
# Net::IMAP class with IP access control.
|
|
39
|
+
# It uses output access lists.
|
|
40
|
+
|
|
41
|
+
module IMAP
|
|
42
|
+
|
|
43
|
+
include IPAccess::Patches::ACL
|
|
44
|
+
|
|
45
|
+
def self.included(base)
|
|
46
|
+
|
|
47
|
+
marker = (base.name =~ /IPAccess/) ? base.superclass : base
|
|
48
|
+
return if marker.instance_variable_defined?(:@uses_ipaccess)
|
|
49
|
+
base.instance_variable_set(:@uses_ipaccess, true)
|
|
50
|
+
|
|
51
|
+
base.class_eval do
|
|
52
|
+
|
|
53
|
+
orig_initialize = self.instance_method :initialize
|
|
54
|
+
orig_authenticate = self.instance_method :authenticate
|
|
55
|
+
orig_start_tls_session= self.instance_method :start_tls_session if self.method_defined?(:start_tls_session)
|
|
56
|
+
|
|
57
|
+
# initialize on steroids.
|
|
58
|
+
define_method :__ipacall__initialize do |block, host, *args|
|
|
59
|
+
@opened_on_deny = false
|
|
60
|
+
args.delete_if { |x| @opened_on_deny = true if (x.is_a?(Symbol) && x == :opened_on_deny) }
|
|
61
|
+
args.pop if args.last.nil?
|
|
62
|
+
self.acl = IPAccess.valid_acl?(args.last) ? args.pop : :global
|
|
63
|
+
ipaddr = ::TCPSocket.getaddress(host)
|
|
64
|
+
real_acl.output.check_ipstring(ipaddr, :none)
|
|
65
|
+
obj = orig_initialize.bind(self).call(ipaddr, *args, &block)
|
|
66
|
+
@host = host
|
|
67
|
+
self.acl_recheck
|
|
68
|
+
return obj
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# authenticate on steroids.
|
|
72
|
+
define_method :authenticate do |auth_type, *args|
|
|
73
|
+
self.acl_recheck
|
|
74
|
+
orig_authenticate.bind(self).call(auth_type, *args)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# block passing wrapper for Ruby 1.8
|
|
78
|
+
def initialize(host, *args, &block)
|
|
79
|
+
__ipacall__initialize(block, host, *args)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# start_tls_session on steroids.
|
|
83
|
+
if self.method_defined?(:start_tls_session)
|
|
84
|
+
define_method :start_tls_session do |params|
|
|
85
|
+
ret = orig_start_tls_session.bind(self).call(params)
|
|
86
|
+
self.acl_recheck
|
|
87
|
+
return ret
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# This method returns default access list indicator
|
|
92
|
+
# used by protected object; in this case it's +:output+.
|
|
93
|
+
define_method :default_list do
|
|
94
|
+
:output
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# this hook will be called each time @acl is reassigned
|
|
98
|
+
define_method :acl_recheck do
|
|
99
|
+
try_arm_and_check_socket @sock
|
|
100
|
+
nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# this hook terminates connection
|
|
104
|
+
define_method :terminate do
|
|
105
|
+
self.disconnect unless disconnected?
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
end # base.class_eval
|
|
109
|
+
|
|
110
|
+
end # self.included
|
|
111
|
+
|
|
112
|
+
end # module IMAP
|
|
113
|
+
|
|
114
|
+
end # module IPAccess::Patches
|
|
115
|
+
|
|
116
|
+
# :startdoc:
|
|
117
|
+
|