utm-plc 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.mkd +7 -0
  2. data/bin/plc +2 -1
  3. data/lib/utm-plc.rb +226 -147
  4. metadata +40 -25
  5. data/bin/plc.rb +0 -227
data/README.mkd CHANGED
@@ -39,6 +39,13 @@ Here is a general overview of how it works.
39
39
  -) If the action doesn't log both accessed and logged pages, add to the list of results
40
40
  5) Print results.
41
41
 
42
+ ### Does it have to have root? ###
43
+
44
+ Sadly yes. One would hope that you could have read-only access to `cc` as `loginuser` but trying
45
+ this simply results in a "Permission denied" error and `cc` fails to open. As an interface with
46
+ WebAdmin is not yet available, root access is required to access the information from the
47
+ back-end.
48
+
42
49
  ### What does it look like? ###
43
50
 
44
51
  Here, let me show you. In this configuration, the main web filter (under Web Protection -> Web Filter)
data/bin/plc CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env ruby1.9.1
2
2
  require 'fileutils'
3
3
  #Add the library from the source tree if exists, this allows
4
4
  #testing without installing the gem first
@@ -6,5 +6,6 @@ if File.exist? File.join('lib', 'utm-plc.rb')
6
6
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
7
7
  end
8
8
  require 'utm-plc'
9
+ $logging=true
9
10
 
10
11
  run
data/lib/utm-plc.rb CHANGED
@@ -22,216 +22,295 @@ require 'pty'
22
22
  require 'timeout'
23
23
  require 'pp'
24
24
 
25
- def _host; prompt('Which host?: ') end
26
- def _port; prompt('What port?: ') end
27
- def _lu_password; prompt('What is the password for loginuser?: ', true) end
28
- def _ru_password; prompt('What is the password for root?: ', true) end
25
+ def _host; prompt('Which host?: ') end
26
+ def _port; prompt('What port?: ') end
27
+ def _lu_password; prompt('What is the password for loginuser?: ', true) end
28
+ def _ru_password; prompt('What is the password for root?: ', true) end
29
29
 
30
30
  $logging=false
31
31
  $debugging=false
32
32
 
33
+ def fingerprint_prompt? string
34
+ !string[/\(yes\/no\)\?/].nil?
35
+ end
36
+
37
+ def wrong_password? buffer, regexp
38
+ !buffer[ Regexp.new( regexp ) ].nil?
39
+ end
40
+
41
+ def err_check buffer
42
+ if fingerprint_prompt?(buffer)
43
+ printf "SSH Fingerprint prompt detected.\nPlease SSH to this system at least once before using this program to verify the SSH fingerprint manually, then run this program again.\n\n"
44
+ exit
45
+ end
46
+
47
+ if wrong_password?(buffer, 'Permission denied')
48
+ printf "Permission denied! Get off my lawn!\n"
49
+ exit
50
+ end
51
+
52
+ if wrong_password?(buffer, 'incorrect password')
53
+ printf "Bad root password! Go away!\n"
54
+ exit
55
+ end
56
+ end
57
+
58
+ def until_prompt( prompt, alt=false )
59
+ buffer= ""
60
+ begin
61
+ Timeout.timeout( 60 ) {
62
+ loop do
63
+ buffer << $out.getc.chr
64
+ err_check( buffer )
65
+ break if buffer =~ Regexp.new(prompt)
66
+ end
67
+ }
68
+ return buffer
69
+ rescue Timeout::Error => error
70
+ printf "Error - Timed out waiting for \"#{prompt.gsub('"','\"') }\", printing stacktrace...\n "
71
+ printf error.backtrace.join("\n") + "\n"
72
+ printf "Dumping buffer...\n"
73
+ pp buffer
74
+ printf "-------\n\n"
75
+ end
76
+ end
77
+
33
78
  def disable_echo &block
34
- system('stty -echo')
35
- x=yield
36
- system('stty echo')
37
- #so that the next line doesn't start on the same line as the password prompt
38
- log
39
- x
79
+ system('stty -echo')
80
+ x=yield
81
+ system('stty echo')
82
+ #so that the next line doesn't start on the same line as the password prompt
83
+ log
84
+ x
40
85
  end
41
86
 
42
87
  def add_nl s
43
- #append a "\n" (newline) to a string if it doesn't already end with one.
44
- (s[/\\n$/].nil? ? s+"\n" : s)
88
+ #append a "\n" (newline) to a string if it doesn't already end with one.
89
+ (s[/\\n$/].nil? ? s+"\n" : s)
45
90
  end
46
91
 
47
92
  def log string=String.new
48
- if $logging==true
49
- printf add_nl(string)
50
- end
51
- string
93
+ if $logging==true
94
+ printf add_nl(string)
95
+ end
96
+ string
52
97
  end
53
98
 
54
99
  def debug string
55
- if $logging and $debugging
56
- printf add_nl(string)
57
- end
58
- string
100
+ if $logging and $debugging
101
+ printf add_nl(string)
102
+ end
103
+ string
59
104
  end
60
105
 
61
106
  def login
62
- log "Logging in as loginuser..."
63
- $in.printf( _lu_password + "\n" )
64
- debug until_prompt( '/home/login >' )
107
+ log "Logging in as loginuser..."
108
+ $in.printf( _lu_password + "\n" )
109
+ debug until_prompt( '/home/login >', :check_badpass )
65
110
  end
66
111
 
67
112
  def become_root
68
- log "Using su to become root..."
69
- $in.printf( "su\n" )
70
- debug until_prompt( 'Password:' )
71
- $in.printf( "#{_ru_password}\n" )
72
- debug until_prompt( '/home/login #' )
73
- log "Am now root."
113
+ log "Using su to become root..."
114
+ $in.printf( "su\n" )
115
+ debug until_prompt( 'Password:' )
116
+ $in.printf( "#{_ru_password}\n" )
117
+ debug until_prompt( '/home/login #', :check_badpass )
118
+ log "Am now root."
74
119
  end
75
120
 
76
121
  def extract_profiles http
77
- debug "Extracting profiles from 'http'="
78
- profiles=http[/'profiles' => \[[^\]]*/].gsub( "'profiles' => \[",'' ).split(',').collect {|p|
79
- p.strip.gsub(/^'/,'').gsub(/'$/,'')
80
- }
81
- log "Found #{profiles.size} profiles:"
82
- profiles.each {|p|
83
- log " -- "+p
84
- }
122
+ debug "Extracting profiles from 'http'="
123
+ profiles=http[/'profiles' => \[[^\]]*/].gsub( "'profiles' => \[",'' ).split(',').collect {|p|
124
+ p.strip.gsub(/^'/,'').gsub(/'$/,'')
125
+ }
126
+ debug "Found #{profiles.size} profiles:"
127
+ profiles.each {|p|
128
+ debug " -- "+p
129
+ }
130
+ end
131
+
132
+ def extract_exceptions http
133
+ exceptions=http[/'exceptions' => \[[^\]]*/].gsub("'exceptions' => \[",'').split(',').collect {|l|
134
+ l.gsub(/'/,'').strip
135
+ }
136
+ debug "Found #{exceptions.size} exceptions:"
137
+ exceptions.each {|e| debug " -- "+e }
85
138
  end
86
139
 
87
140
  def extract_cff_profiles raw_proxy_profile
88
- log "Found cff_profiles: "
89
- cff_p=raw_proxy_profile[/'cff_profiles' => \[[^\]]*/].gsub( "'cff_profiles' => \[",'' ).
90
- strip.gsub(',','').strip.gsub(/^'/,'').gsub(/'$/,'').strip.gsub(/^'/,'').gsub(/'$/,'')
91
- log " -- "+cff_p
92
- cff_p
141
+ debug "Found cff_profiles: "
142
+ cff_p=raw_proxy_profile[/'cff_profiles' => \[[^\]]*/].gsub( "'cff_profiles' => \[",'' ).
143
+ strip.gsub(',','').strip.gsub(/^'/,'').gsub(/'$/,'').strip.gsub(/^'/,'').gsub(/'$/,'')
144
+ debug " -- "+cff_p
145
+ cff_p
93
146
  end
94
147
 
95
148
  def extract_action raw_assignment
96
- raw_assignment[/'action' => '[^']*/].gsub(/'action' => '/,'').strip
149
+ raw_assignment[/'action' => '[^']*/].gsub(/'action' => '/,'').strip
150
+ end
151
+
152
+ def search_exceptions exceptions
153
+ if exceptions.class!=Array
154
+ raise ArgumentError "search_exceptions(exceptions): 'exceptions' must be an array but it's something else, possibly a cheeseburger..."
155
+ elsif exceptions.empty?
156
+ raise ArgumentError "search_exceptions(exceptions): 'exceptions' must be a non-empty array! What have you done?!?"
157
+ end
158
+
159
+ results={:exceptions=>[]}
160
+ exceptions.each {|exception|
161
+ debug raw_exception=get_object(exception)
162
+ log "Checking exception: #{get_name(raw_exception)}"
163
+ if _e_log_accessed?(raw_exception)
164
+ results[:exceptions] << exception
165
+ elsif _e_log_blocked?(raw_exception)
166
+ results[:exceptions] << exception
167
+ end
168
+ }
169
+ results
97
170
  end
98
171
 
99
172
  def search_profiles profiles
100
- if profiles.class!=Array
101
- raise ArgumentError "search_profiles(profiles): 'profiles' must be an array but it's something else, possibly a cheeseburger..."
102
- elsif profiles.empty?
103
- raise ArgumentError "search_profiles(profiles): 'profiles' must be a non-empty array! What have you done?!?"
104
- end
105
- results=[]
106
- profiles.each {|profile|
107
- debug raw_proxy_profile=get_object(profile)
108
- log "\nChecking profile: #{get_name(raw_proxy_profile)}"
109
- debug raw_assignment=get_object( extract_cff_profiles(raw_proxy_profile) )
110
- log "Got the assignment for that profile..."
111
- action= get_action(raw_assignment)
112
- raw_action= get_object( extract_action(raw_assignment) )
113
- log "Got the action for that assignment..."
114
-
115
- if !log_accessed?(raw_action) || !log_blocked?(raw_action)
116
- log "Found an action that isn't logging everything: #{get_name(raw_action)}"
117
- results << raw_action
118
- end
119
- }
120
- results
121
- end
122
-
123
- def log_accessed? action
124
- if action[/'log_access' => \d/].nil?
125
- raise ArgumentError "log_accessed?(action): action doesn't contain a 'log_access' attribute?"
126
- end
127
- action[/'log_access' => \d/].gsub(/'log_access' => /,'')=='1'
128
- end
129
-
130
- def log_blocked? action
131
- if action[/'log_blocked' => \d/].nil?
132
- raise ArgumentError "log_blocked?(action): action doesn't contain a 'log_blocked' attribute?"
133
- end
134
- action[/'log_blocked' => \d/].gsub(/'log_blocked' => /,'')=='1'
173
+ if profiles.class!=Array
174
+ raise ArgumentError "search_profiles(profiles): 'profiles' must be an array but it's something else, possibly a cheeseburger..."
175
+ elsif profiles.empty?
176
+ raise ArgumentError "search_profiles(profiles): 'profiles' must be a non-empty array! What have you done?!?"
177
+ end
178
+ results={:profiles=>[]}
179
+ profiles.each {|profile|
180
+ debug raw_proxy_profile=get_object(profile)
181
+ log "Checking profile: #{get_name(raw_proxy_profile)}"
182
+ debug raw_assignment=get_object( extract_cff_profiles(raw_proxy_profile) )
183
+ log "Got the assignment for that profile..."
184
+ action= get_action(raw_assignment)
185
+ raw_action= get_object( extract_action(raw_assignment) )
186
+ log "Got the action for that assignment..."
187
+
188
+ if !_p_log_accessed?(raw_action) || !_p_log_blocked?(raw_action)
189
+ log "Found an action that isn't logging everything: #{get_name(raw_action)}"
190
+ results[:profiles] << raw_action
191
+ end
192
+ }
193
+ results
194
+ end
195
+
196
+ def _p_log_accessed? action
197
+ if action[/'log_access' => \d/].nil?
198
+ raise ArgumentError "_p_log_accessed?(action): action doesn't contain a 'log_access' attribute?"
199
+ end
200
+ action[/'log_access' => \d/].gsub(/'log_access' => /,'')=='1'
201
+ end
202
+
203
+ def _p_log_blocked? action
204
+ if action[/'log_blocked' => \d/].nil?
205
+ raise ArgumentError "_p_log_blocked?(action): action doesn't contain a 'log_blocked' attribute?"
206
+ end
207
+ action[/'log_blocked' => \d/].gsub(/'log_blocked' => /,'')=='1'
208
+ end
209
+
210
+ def _e_log_accessed? raw_exception
211
+ raw_exception[/'skiplist' => \[[^\]]*/].gsub("'skiplist' => \[",'').split(',').collect {|l|
212
+ l.gsub(/'/,'').strip
213
+ }.include? 'log_access'
214
+ end
215
+
216
+ def _e_log_blocked? raw_exception
217
+ raw_exception[/'skiplist' => \[[^\]]*/].gsub("'skiplist' => \[",'').split(',').collect {|l|
218
+ l.gsub(/'/,'').strip
219
+ }.include? 'log_blocked'
135
220
  end
136
221
 
137
222
  def print_results results
138
- log "\n\nPrinting results:"
139
- results.each {|action|
140
- if !log_accessed?(action)
141
- log "Please activate the 'Log Accessed Pages' option for the Web Filter Action named: #{get_name(action)}"
142
- elsif !log_blocked?(action)
143
- log "Please activate the 'Log Blocked Pages' option for the Web Filter Action named: #{get_name(action)}"
144
- end
145
- }
223
+ log "\n\nPrinting results:"
224
+ results.each {|x,y|
225
+ if x==:profiles
226
+ y.each {|z|
227
+ if !_p_log_accessed?(z)
228
+ log "Please activate the 'Log Accessed Pages' option for the Web Filter Action named: #{get_name(z)}"
229
+ end
230
+ if !_p_log_blocked?(z)
231
+ log "Please activate the 'Log Blocked Pages' option for the Web Filter Action named: #{get_name(z)}"
232
+ end
233
+ }
234
+ elsif x==:exceptions
235
+ y.each {|z|
236
+ if _e_log_accessed?(get_object(z))
237
+ log "Please deactivate the option to skip logging of accessed pages for the Exception named: #{get_name(get_object(z))}"
238
+ end
239
+ if _e_log_blocked?(get_object(z))
240
+ log "Please deactivate the option to skip logging of blocked pages for the Exception named: #{get_name(get_object(z))}"
241
+ end
242
+ }
243
+ end
244
+ }
146
245
  end
147
246
 
148
247
  def get x, command='get'
149
- debug "Running: 'cc #{command} #{x}'..."
150
- $in.printf("cc #{command} #{x}\n")
151
- debug until_prompt(':/home/login #')
248
+ debug "Running: 'cc #{command} #{x}'..."
249
+ $in.printf("cc #{command} #{x}\n")
250
+ debug until_prompt(':/home/login #')
152
251
  end
153
252
 
154
253
  def print_raction raw_action
155
- log "Name: #{get_name(raw_action)}"
156
- log "Comment: #{get_comment(raw_action)}"
254
+ log "Name: #{get_name(raw_action)}"
255
+ log "Comment: #{get_comment(raw_action)}"
157
256
  end
158
257
 
159
258
  def get_name raw
160
- raw[/'name' => '[^']*/].gsub(/'name' => '/,'')
259
+ raw[/'name' => '[^']*/].gsub(/'name' => '/,'')
161
260
  end
162
261
 
163
262
  def get_comment raw
164
- raw[/'comment' => '[^']*/].gsub(/'comment' => '/,'')
263
+ raw[/'comment' => '[^']*/].gsub(/'comment' => '/,'')
165
264
  end
166
265
 
167
266
  def get_action raw_assignment
168
- raw_assignment[/'action' => '[^']*/].gsub(/'action' => '/,'').strip
267
+ raw_assignment[/'action' => '[^']*/].gsub(/'action' => '/,'').strip
169
268
  end
170
269
 
171
270
  def get_object x
172
- get x, 'get_object'
271
+ get x, 'get_object'
173
272
  end
174
273
 
175
- def fingerprint_prompt? string
176
- !string[/\(yes\/no\)\?/].nil?
177
- end
178
-
179
- def until_prompt( prompt )
180
- buffer= ""
181
- begin
182
- Timeout.timeout( 5 ) {
183
- loop do
184
- buffer << $out.getc.chr
185
- if fingerprint_prompt?(buffer)
186
- printf "SSH Fingerprint prompt detected.\nPlease SSH to this system at least once before using this program to verify the SSH fingerprint manually, then run this program again.\n\n"
187
- exit
188
- end
189
- break if buffer =~ Regexp.new(prompt)
190
- end
191
- }
192
- buffer
193
- rescue Timeout::Error => error
194
- printf "Error - Timed out waiting for \"#{prompt.gsub('"','\"') }\", printing stacktrace...\n "
195
- printf error.backtrace.join("\n") + "\n"
196
- printf "Dumping buffer...\n"
197
- pp buffer
198
- printf "-------\n\n"
199
- end
200
- end
274
+
201
275
 
202
276
  def prompt question, password=false
203
- printf question
204
- if password==true
205
- disable_echo {
206
- (s=gets.strip).empty? ? prompt(question) : s
207
- }
208
- else
209
- (s=gets.strip).empty? ? prompt(question) : s
210
- end
277
+ printf question
278
+ if password==true
279
+ disable_echo {
280
+ (s=gets.strip).empty? ? prompt(question) : s
281
+ }
282
+ else
283
+ (s=gets.strip).empty? ? prompt(question) : s
284
+ end
211
285
  end
212
286
 
213
287
  def run
214
- PTY.spawn("ssh -p #{_port} loginuser@#{_host}") {|stdout,stdin,pid|
215
- old_out=$out; $out=stdout
216
- old_in=$in; $in =stdin
217
- $logging=true
288
+ PTY.spawn("ssh -p #{_port} loginuser@#{_host}") {|stdout,stdin,pid|
289
+ begin
290
+ old_out=$out; $out=stdout
291
+ old_in=$in; $in =stdin
218
292
 
219
- debug( until_prompt('password:') )
220
- login
221
- become_root
293
+ debug( until_prompt('password:') )
294
+ login
295
+ become_root
222
296
 
223
- #Because the main Web Filter is treated as a profile, this
224
- #will operate on all Web Filters and proxy profiles.
225
- results= search_profiles( extract_profiles( get('http') ) )
297
+ #Because the main Web Filter is treated as a profile, this
298
+ #will operate on all Web Filters and proxy profiles.
299
+ results= search_profiles( extract_profiles( http=get('http') ) )
300
+ results.merge!( search_exceptions( extract_exceptions( http ) ) )
226
301
 
227
- print_results( results )
302
+ print_results( results )
228
303
 
229
- stdin.printf( "exit\n" )
230
- until_prompt( ":/home/login >" )
231
- stdin.printf( "exit\n" )
304
+ stdin.printf( "exit\n" )
305
+ until_prompt( ":/home/login >" )
306
+ stdin.printf( "exit\n" )
232
307
 
233
- $out=old_out
234
- $in=old_in
235
- }
236
- log 'Done'
308
+ $out=old_out
309
+ $in=old_in
310
+ rescue Errno::EIO
311
+ printf "SSH Connection failed. Are you able to ssh in from this machine? If not, start troubleshooting from here.\n"
312
+ exit
313
+ end
314
+ }
315
+ log 'Done'
237
316
  end
metadata CHANGED
@@ -1,53 +1,68 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: utm-plc
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.5
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
6
10
  platform: ruby
7
- authors:
11
+ authors:
8
12
  - Jeff Welling
9
13
  autorequire:
10
14
  bindir: bin
11
15
  cert_chain: []
12
- date: 2013-05-22 00:00:00.000000000 Z
16
+
17
+ date: 2013-06-10 23:37:19 -07:00
18
+ default_executable:
13
19
  dependencies: []
14
- description: This tool logs in to your UTM and interacts with 'cc' to check the configuration
15
- of every web filter configuration in use and list the ones that are not configured
16
- to log accessed and blocked pages.
17
- email:
20
+
21
+ description: This tool logs in to your UTM and interacts with 'cc' to check the configuration of every web filter configuration in use and list the ones that are not configured to log accessed and blocked pages.
22
+ email:
18
23
  - jeff.welling@gmail.com
19
- executables:
24
+ executables:
20
25
  - plc
21
26
  extensions: []
27
+
22
28
  extra_rdoc_files: []
23
- files:
29
+
30
+ files:
24
31
  - bin/plc
25
- - bin/plc.rb
26
32
  - lib/utm-plc.rb
27
33
  - LICENSE
28
34
  - README.mkd
35
+ has_rdoc: true
29
36
  homepage: https://github.com/jeffWelling/UTM-plc
30
37
  licenses: []
38
+
31
39
  post_install_message:
32
40
  rdoc_options: []
33
- require_paths:
41
+
42
+ require_paths:
34
43
  - lib
35
- required_ruby_version: !ruby/object:Gem::Requirement
44
+ required_ruby_version: !ruby/object:Gem::Requirement
36
45
  none: false
37
- requirements:
38
- - - ! '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ segments:
50
+ - 0
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
53
  none: false
43
- requirements:
44
- - - ! '>='
45
- - !ruby/object:Gem::Version
46
- version: '0'
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 0
59
+ version: "0"
47
60
  requirements: []
61
+
48
62
  rubyforge_project:
49
- rubygems_version: 1.8.23
63
+ rubygems_version: 1.3.7
50
64
  signing_key:
51
65
  specification_version: 3
52
66
  summary: Tool to check if your UTM's Web Filter is logging
53
67
  test_files: []
68
+
data/bin/plc.rb DELETED
@@ -1,227 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # This file is part of UTM_plc.
3
- # Copyright 2013 Jeff Welling (jeff.welling@gmail.com)
4
- #
5
- # UTM_plc is free software: you can redistribute it and/or modify
6
- # it under the terms of the GNU General Public License as published by
7
- # the Free Software Foundation, either version 3 of the License, or
8
- # (at your option) any later version.
9
- #
10
- # UTM_plc is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- # GNU General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU General Public License
16
- # along with tget. If not, see <http://www.gnu.org/licenses/>.
17
- #
18
- # Add the library from the source tree to the front of the load path.
19
- # This allows tget to run without first installing the tget gem, which is
20
- # important when testing multiple branches of development.
21
- require 'pty'
22
- require 'timeout'
23
- require 'pp'
24
-
25
- def _host; prompt('Which host?: ') end
26
- def _port; prompt('What port?: ') end
27
- def _lu_password; disable_echo {prompt('What is the password for loginuser?: ')} end
28
- def _ru_password; disable_echo {prompt('What is the password for root?: ')} end
29
-
30
- $logging=false
31
- $debugging=false
32
-
33
- def disable_echo &block
34
- system('stty -echo')
35
- x=yield
36
- system('stty echo')
37
- #so that the next line doesn't start on the same line as the password prompt
38
- log
39
- x
40
- end
41
-
42
- def add_nl s
43
- #append a "\n" (newline) to a string if it doesn't already end with one.
44
- (s[/\\n$/].nil? ? s+"\n" : s)
45
- end
46
-
47
- def log string=String.new
48
- if $logging==true
49
- printf add_nl(string)
50
- end
51
- string
52
- end
53
-
54
- def debug string
55
- if $logging and $debugging
56
- printf add_nl(string)
57
- end
58
- string
59
- end
60
-
61
- def login
62
- log "Logging in as loginuser..."
63
- $in.printf( _lu_password + "\n" )
64
- debug until_prompt( '/home/login >' )
65
- end
66
-
67
- def become_root
68
- log "Using su to become root..."
69
- $in.printf( "su\n" )
70
- debug until_prompt( 'Password:' )
71
- $in.printf( "#{_ru_password}\n" )
72
- debug until_prompt( '/home/login #' )
73
- log "Am now root."
74
- end
75
-
76
- def extract_profiles http
77
- debug "Extracting profiles from 'http'="
78
- profiles=http[/'profiles' => \[[^\]]*/].gsub( "'profiles' => \[",'' ).split(',').collect {|p|
79
- p.strip.gsub(/^'/,'').gsub(/'$/,'')
80
- }
81
- log "Found #{profiles.size} profiles:"
82
- profiles.each {|p|
83
- log " -- "+p
84
- }
85
- end
86
-
87
- def extract_cff_profiles raw_proxy_profile
88
- log "Found cff_profiles: "
89
- cff_p=raw_proxy_profile[/'cff_profiles' => \[[^\]]*/].gsub( "'cff_profiles' => \[",'' ).
90
- strip.gsub(',','').strip.gsub(/^'/,'').gsub(/'$/,'').strip.gsub(/^'/,'').gsub(/'$/,'')
91
- log " -- "+cff_p
92
- cff_p
93
- end
94
-
95
- def extract_action raw_assignment
96
- raw_assignment[/'action' => '[^']*/].gsub(/'action' => '/,'').strip
97
- end
98
-
99
- def search_profiles profiles
100
- if profiles.class!=Array
101
- raise ArgumentError "search_profiles(profiles): 'profiles' must be an array but it's something else, possibly a cheeseburger..."
102
- elsif profiles.empty?
103
- raise ArgumentError "search_profiles(profiles): 'profiles' must be a non-empty array! What have you done?!?"
104
- end
105
- results=[]
106
- profiles.each {|profile|
107
- debug raw_proxy_profile=get_object(profile)
108
- log "\nChecking profile: #{get_name(raw_proxy_profile)}"
109
- debug raw_assignment=get_object( extract_cff_profiles(raw_proxy_profile) )
110
- log "Got the assignment for that profile..."
111
- action= get_action(raw_assignment)
112
- raw_action= get_object( extract_action(raw_assignment) )
113
- log "Got the action for that assignment..."
114
-
115
- if !log_accessed?(raw_action) || !log_blocked?(raw_action)
116
- log "Found an action that isn't logging everything: #{get_name(raw_action)}"
117
- results << raw_action
118
- end
119
- }
120
- results
121
- end
122
-
123
- def log_accessed? action
124
- if action[/'log_access' => \d/].nil?
125
- raise ArgumentError "log_accessed?(action): action doesn't contain a 'log_access' attribute?"
126
- end
127
- action[/'log_access' => \d/].gsub(/'log_access' => /,'')=='1'
128
- end
129
-
130
- def log_blocked? action
131
- if action[/'log_blocked' => \d/].nil?
132
- raise ArgumentError "log_blocked?(action): action doesn't contain a 'log_blocked' attribute?"
133
- end
134
- action[/'log_blocked' => \d/].gsub(/'log_blocked' => /,'')=='1'
135
- end
136
-
137
- def print_results results
138
- log "\n\nPrinting results:"
139
- results.each {|action|
140
- if !log_accessed?(action)
141
- log "Please activate the 'Log Accessed Pages' option for the Web Filter Action named: #{get_name(action)}"
142
- elsif !log_blocked?(action)
143
- log "Please activate the 'Log Blocked Pages' option for the Web Filter Action named: #{get_name(action)}"
144
- end
145
- }
146
- end
147
-
148
- def get x, command='get'
149
- debug "Running: 'cc #{command} #{x}'..."
150
- $in.printf("cc #{command} #{x}\n")
151
- debug until_prompt(':/home/login #')
152
- end
153
-
154
- def print_raction raw_action
155
- log "Name: #{get_name(raw_action)}"
156
- log "Comment: #{get_comment(raw_action)}"
157
- end
158
-
159
- def get_name raw
160
- raw[/'name' => '[^']*/].gsub(/'name' => '/,'')
161
- end
162
-
163
- def get_comment raw
164
- raw[/'comment' => '[^']*/].gsub(/'comment' => '/,'')
165
- end
166
-
167
- def get_action raw_assignment
168
- raw_assignment[/'action' => '[^']*/].gsub(/'action' => '/,'').strip
169
- end
170
-
171
- def get_object x
172
- get x, 'get_object'
173
- end
174
-
175
- def until_prompt( prompt )
176
- buffer= ""
177
- begin
178
- Timeout.timeout( 30 ) {
179
- loop do
180
- buffer << $out.getc.chr
181
- break if buffer =~ Regexp.new(prompt)
182
- end
183
- }
184
- buffer
185
- rescue Timeout::Error => error
186
- printf "Error - Timed out waiting for \"#{prompt.gsub('"','\"') }\", printing stacktrace...\n "
187
- printf error.backtrace.join("\n") + "\n"
188
- printf "Dumping buffer...\n"
189
- pp buffer
190
- printf "-------\n\n"
191
- end
192
- end
193
-
194
- def prompt *question
195
- printf *question
196
- (s=gets.strip).empty? ? prompt(*question) : s
197
- end
198
-
199
- def run
200
- PTY.spawn("ssh -p #{_port} loginuser@#{_host}") {|stdout,stdin,pid|
201
- old_out=$out; $out=stdout
202
- old_in=$in; $in =stdin
203
- $logging=true
204
-
205
- debug( until_prompt('password:') )
206
- login
207
- become_root
208
-
209
- #Because the main Web Filter is treated as a profile, this
210
- #will operate on all Web Filters and proxy profiles.
211
- results= search_profiles( extract_profiles( get('http') ) )
212
-
213
- print_results( results )
214
-
215
- stdin.printf( "exit\n" )
216
- until_prompt( ":/home/login >" )
217
- stdin.printf( "exit\n" )
218
-
219
- $out=old_out
220
- $in=old_in
221
- }
222
- log 'Done'
223
- end
224
-
225
- if __FILE__ == './plc.rb'
226
- run
227
- end