sslsmart 1.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.
- data/LICENSE.txt +45 -0
- data/README +5 -0
- data/bin/fs_icon_32.ico +0 -0
- data/bin/resultcontainer.rb +11 -0
- data/bin/rootcerts.pem +3509 -0
- data/bin/sslsmartconfig.rb +177 -0
- data/bin/sslsmartcontroller.rb +351 -0
- data/bin/sslsmartdb.rb +151 -0
- data/bin/sslsmartgui.rb +888 -0
- data/bin/sslsmartlib.rb +287 -0
- data/bin/sslsmartlog.rb +35 -0
- data/bin/sslsmartmisc.rb +50 -0
- data/sample.rb +19 -0
- data/sslsmart.gemspec +20 -0
- metadata +110 -0
data/bin/sslsmartdb.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
# Gursev Singh Kalra @ Foundstone(McAfee)
|
2
|
+
# Please see LICENSE.txt for licensing information
|
3
|
+
|
4
|
+
# require 'sslsmartlib'
|
5
|
+
# require 'singleton'
|
6
|
+
# require 'uri'
|
7
|
+
require 'resultcontainer'
|
8
|
+
require 'sslsmartconfig'
|
9
|
+
|
10
|
+
$conf = SSLSmartConfig.instance
|
11
|
+
|
12
|
+
class UrlResults
|
13
|
+
def initialize()
|
14
|
+
@cert = nil
|
15
|
+
@cert_validity = nil
|
16
|
+
@progress = 0
|
17
|
+
@cipher_response_array = []
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def add_cipher_response(index, response)
|
22
|
+
@cipher_response_array[index] = response
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def update_progress
|
27
|
+
@progress = (@cipher_response_array.compact.length*100)/$conf.count_to_test if(@cipher_response_array)
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :cert, :cert_validity, :cipher_response_array, :progress
|
31
|
+
end
|
32
|
+
|
33
|
+
class SSLSmartDB
|
34
|
+
|
35
|
+
def initialize()
|
36
|
+
@db = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def add_url(url)
|
41
|
+
return if(url == "" || url == nil)
|
42
|
+
@db[url.to_sym] = UrlResults.new
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def add_cert(url, cert, cert_validity)
|
47
|
+
return if(url == "" || url == nil)
|
48
|
+
return unless(@db[url.to_sym])
|
49
|
+
@db[url.to_sym].cert = cert
|
50
|
+
@db[url.to_sym].cert_validity = cert_validity
|
51
|
+
@db[url.to_sym].progress = ($conf.count_to_test == 0)?100:1
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def add_cipher_response(url, index, response)
|
56
|
+
return if(url == "" || url == nil)
|
57
|
+
@db[url.to_sym].add_cipher_response(index, response)
|
58
|
+
@db[url.to_sym].update_progress()
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def cert_valid?(url)
|
63
|
+
return nil if(url == "" || url == nil)
|
64
|
+
return nil unless(@db[url.to_sym])
|
65
|
+
@db[url.to_sym].cert_validity
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def get_cert(url)
|
70
|
+
return nil if(url == "" || url == nil)
|
71
|
+
return nil unless(@db[url.to_sym])
|
72
|
+
@db[url.to_sym].cert
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def get_response(url, index)
|
77
|
+
return nil if(url == "" || url == nil)
|
78
|
+
return nil unless(@db[url.to_sym])
|
79
|
+
response = @db[url.to_sym].cipher_response_array[index]
|
80
|
+
return nil unless(response)
|
81
|
+
#return nil unless(response.data)
|
82
|
+
response
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def get_html_response(url, index)
|
87
|
+
return nil if(url == "" || url == nil)
|
88
|
+
response = get_response(url, index)
|
89
|
+
return nil unless(response)
|
90
|
+
return nil unless(response.status)
|
91
|
+
if(response.data)
|
92
|
+
return response.data.body
|
93
|
+
else
|
94
|
+
return ""
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
def get_text_response(url, index)
|
100
|
+
return nil if(url == "" || url == nil)
|
101
|
+
response = get_response(url, index)
|
102
|
+
return nil unless(response)
|
103
|
+
return nil unless(response.status)
|
104
|
+
|
105
|
+
return "" unless(response.data)
|
106
|
+
response = response.data
|
107
|
+
|
108
|
+
text = ""
|
109
|
+
text = "HTTP\/#{response.http_version} #{response.code} #{response.msg}\n"
|
110
|
+
response.each do |header, body|
|
111
|
+
text << "#{header}: #{body}\n"
|
112
|
+
end
|
113
|
+
text << "\n\n"
|
114
|
+
text << response.body
|
115
|
+
text
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
def get_response_code(url, index)
|
120
|
+
return nil if(url == "" || url == nil)
|
121
|
+
response = get_response(url, index)
|
122
|
+
# REVIEW HERE
|
123
|
+
return nil unless(response)
|
124
|
+
return "" unless(response.data)
|
125
|
+
|
126
|
+
retval = response.data
|
127
|
+
case response.status
|
128
|
+
when true
|
129
|
+
return "HTTP\/#{retval.http_version} #{retval.code} #{retval.msg}"
|
130
|
+
when false
|
131
|
+
return retval.message
|
132
|
+
else
|
133
|
+
return nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def get_all_cipher_results(url)
|
139
|
+
return nil if(url == "" || url == nil)
|
140
|
+
return nil unless(@db[url.to_sym])
|
141
|
+
@db[url.to_sym].cipher_response_array
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
def get_progress(url)
|
146
|
+
return 0 if(url == "" || url == nil)
|
147
|
+
return 0 unless(@db[url.to_sym])
|
148
|
+
@db[url.to_sym].progress
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
data/bin/sslsmartgui.rb
ADDED
@@ -0,0 +1,888 @@
|
|
1
|
+
# Gursev Singh Kalra @ Foundstone(McAfee)
|
2
|
+
# Please see LICENSE.txt for licensing information
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'cgi'
|
6
|
+
require 'net/https'
|
7
|
+
require 'sslsmartlog'
|
8
|
+
require 'sslsmartlib'
|
9
|
+
require 'sslsmartconfig'
|
10
|
+
require 'sslsmartmisc'
|
11
|
+
require 'sslsmartcontroller'
|
12
|
+
rescue LoadError => ex
|
13
|
+
raise ex
|
14
|
+
end
|
15
|
+
|
16
|
+
begin
|
17
|
+
require 'rubygems'
|
18
|
+
rescue LoadError
|
19
|
+
end
|
20
|
+
|
21
|
+
$log = SSLSmartLog.instance
|
22
|
+
$conf = SSLSmartConfig.instance
|
23
|
+
|
24
|
+
|
25
|
+
require 'wx'
|
26
|
+
|
27
|
+
# IDentifiers for GUI controls
|
28
|
+
ID_SSLSMART_XML = 111
|
29
|
+
ID_SSLSMART_XML_VERBOSE = 112
|
30
|
+
ID_SSLSMART_HTML = 113
|
31
|
+
ID_SSLSMART_HTML_VERBOSE = 114
|
32
|
+
ID_SSLSMART_TEXT = 115
|
33
|
+
ID_SSLSMART_TEXT_VERBOSE = 116
|
34
|
+
|
35
|
+
ID_SSLSMART_EXIT = 117
|
36
|
+
ID_SSLSMART_CLOSE = 119
|
37
|
+
ID_SSLSMART_HELP = 121
|
38
|
+
|
39
|
+
|
40
|
+
HOST_BUTTON_SIZE = [100,25]
|
41
|
+
BUTTON_SIZE = [100,25]
|
42
|
+
HOST_CONTROL_SPACING = 5
|
43
|
+
HOST_BOX_HEIGHT = 100
|
44
|
+
HOST_BOX_WIDTH = 775
|
45
|
+
CIPHER_GRID_WIDTH = 775
|
46
|
+
CIPHER_GRID_HEIGHT = 200
|
47
|
+
HOSTS_PROPORTION = 1
|
48
|
+
CIPHER_PROPORTION = 3
|
49
|
+
HTML_PROPORTION = 4
|
50
|
+
CERT_PROPORTION = 2
|
51
|
+
|
52
|
+
SHOW_HTML = 0
|
53
|
+
SHOW_TEXT = 1
|
54
|
+
|
55
|
+
GRID_COLS = 6
|
56
|
+
TEST_COL = 0
|
57
|
+
VERSION_COL = 1
|
58
|
+
NAME_COL = 2
|
59
|
+
BITS_COL = 3
|
60
|
+
SUPPORTED_COL = 4
|
61
|
+
HTTP_COL = 5
|
62
|
+
|
63
|
+
|
64
|
+
class SSLSmartFrame < Wx::Frame
|
65
|
+
|
66
|
+
include SSLSmartMisc
|
67
|
+
|
68
|
+
###########################################################
|
69
|
+
##+ Start creation of Menu Bar and corresponding functions
|
70
|
+
###########################################################
|
71
|
+
|
72
|
+
def create_menu_bar
|
73
|
+
menu_bar = Wx::MenuBar.new
|
74
|
+
|
75
|
+
# The "file" menu
|
76
|
+
menu_file = Wx::Menu.new
|
77
|
+
menu_file.append(ID_SSLSMART_HTML , "Export HTML Report\tCtrl-1" , "Export HTML Report")
|
78
|
+
menu_file.append(ID_SSLSMART_HTML_VERBOSE , "Export Verbose HTML Report\tCtrl-2" , "Export HTML Report")
|
79
|
+
menu_file.append(ID_SSLSMART_XML , "Export XML Report\tCtrl-3" , "Export XML Report")
|
80
|
+
menu_file.append(ID_SSLSMART_XML_VERBOSE , "Export Verbose XML Report\tCtrl-4" , "Export XML Report")
|
81
|
+
menu_file.append(ID_SSLSMART_TEXT , "Export TEXT Report\tCtrl-5" , "Export Text Report")
|
82
|
+
menu_file.append(ID_SSLSMART_TEXT_VERBOSE , "Export Verbose TEXT Report\tCtrl-6" , "Export Text Report")
|
83
|
+
menu_file.append_separator()
|
84
|
+
menu_file.append(Wx::ID_EXIT, "E&xit\tAlt-X", "Quit this program")
|
85
|
+
menu_bar.append(menu_file, "&File")
|
86
|
+
|
87
|
+
# The "help" menu
|
88
|
+
menu_help = Wx::Menu.new
|
89
|
+
menu_help.append(ID_SSLSMART_HELP, "SSLSmart Help\tF1", "")
|
90
|
+
menu_help.append(Wx::ID_ABOUT, "About........\tF2", "Show about dialog")
|
91
|
+
menu_bar.append(menu_help, "&Help")
|
92
|
+
|
93
|
+
self.menu_bar = menu_bar
|
94
|
+
|
95
|
+
# Set it up to handle menu events using the relevant methods.
|
96
|
+
evt_menu(Wx::ID_EXIT , :on_my_close)
|
97
|
+
evt_menu(Wx::ID_ABOUT , :on_about)
|
98
|
+
evt_menu(ID_SSLSMART_HTML) {|event| create_report(event, :html)}
|
99
|
+
evt_menu(ID_SSLSMART_HTML_VERBOSE) {|event| create_report(event, :htmlv)}# , :create_verbose_html_report)
|
100
|
+
evt_menu(ID_SSLSMART_XML) {|event| create_report(event, :xml)}
|
101
|
+
evt_menu(ID_SSLSMART_XML_VERBOSE) {|event| create_report(event, :xmlv)}
|
102
|
+
evt_menu(ID_SSLSMART_TEXT) {|event| create_report(event, :text)}
|
103
|
+
evt_menu(ID_SSLSMART_TEXT_VERBOSE) {|event| create_report(event, :textv)}
|
104
|
+
evt_menu(ID_SSLSMART_HELP, :show_help)
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
###########################################################
|
110
|
+
##- END Menu Bar and corresponding functions
|
111
|
+
###########################################################
|
112
|
+
|
113
|
+
|
114
|
+
def write_results_to_file(content, filetype)
|
115
|
+
case filetype
|
116
|
+
when :html
|
117
|
+
append = ".html"
|
118
|
+
when :htmlv
|
119
|
+
filetype = :html
|
120
|
+
append = "_Verbose.html"
|
121
|
+
when :text
|
122
|
+
append = ".txt"
|
123
|
+
when :textv
|
124
|
+
filetype = :txt
|
125
|
+
append = "_Verbose.txt"
|
126
|
+
when :xml
|
127
|
+
append = ".xml"
|
128
|
+
when :xmlv
|
129
|
+
filetype = :xml
|
130
|
+
append = "_Verbose.xml"
|
131
|
+
end
|
132
|
+
|
133
|
+
file_dialog = Wx::FileDialog.new(self, "Export #{filetype.to_s.upcase} Results As", "", "SSLSmart#{append}", "*.*", Wx::FD_SAVE| Wx::FD_OVERWRITE_PROMPT)
|
134
|
+
file_dialog.show_modal
|
135
|
+
path = file_dialog.get_path
|
136
|
+
return if(path == nil || path == "")
|
137
|
+
begin
|
138
|
+
File.open(path, 'w') do |f|
|
139
|
+
f.puts content
|
140
|
+
end
|
141
|
+
rescue => ex
|
142
|
+
$log.error(ex.message)
|
143
|
+
Wx::MessageDialog.new(nil, "Error Occured!!\nPlease see log files for more details", "", Wx::OK ).show_modal()
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
def create_report(event, type)
|
149
|
+
return unless(@controller)
|
150
|
+
report_content = @controller.create_report(type)
|
151
|
+
write_results_to_file(report_content, type) if(report_content)
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
def show_help()
|
156
|
+
Wx::MessageDialog.new(nil, "Visit Foundstone website to download SSLSmart white paper", "SSLSmart Help", Wx::OK).show_modal
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def on_my_close()
|
161
|
+
rval = Wx::MessageDialog.new(nil, "Are you sure you want to exit?","Exit Confirmation", Wx::ICON_QUESTION|Wx::YES_NO).show_modal
|
162
|
+
return if(rval == Wx::ID_NO)
|
163
|
+
$log.debug("Exiting SSLSmart")
|
164
|
+
destroy
|
165
|
+
exit
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
def on_about()
|
170
|
+
Wx::about_box(:name => self.title,
|
171
|
+
:version => "1.0",
|
172
|
+
:description => "For Smart SSL Cipher Enumeration",
|
173
|
+
:developers => ['Gursev Kalra @ Foundstone'] )
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
def on_changing_page(event)
|
178
|
+
event.veto if(@test_running)
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
##+ Creating the two tabs to host all GUI elements
|
183
|
+
def create_workspace_and_options_tabs()
|
184
|
+
new_notebook = Wx::Notebook.new(self)
|
185
|
+
|
186
|
+
@ws_tab = Wx::Panel.new(new_notebook) # Add workspace tab
|
187
|
+
@ws_mvsizer = Wx::BoxSizer.new(Wx::VERTICAL)
|
188
|
+
@ws_tab.set_sizer(@ws_mvsizer)
|
189
|
+
|
190
|
+
@options_tab = Wx::Panel.new(new_notebook) # Add options tab
|
191
|
+
@options_mvsizer = Wx::BoxSizer.new(Wx::VERTICAL)
|
192
|
+
@options_tab.set_sizer(@options_mvsizer)
|
193
|
+
|
194
|
+
|
195
|
+
new_notebook.add_page(@ws_tab , "Workspace")
|
196
|
+
new_notebook.add_page(@options_tab , "Options")
|
197
|
+
evt_notebook_page_changing(new_notebook.get_id()) {|event| on_changing_page(event) }
|
198
|
+
end
|
199
|
+
|
200
|
+
##- End of tab creation
|
201
|
+
def clear_gui_and_results()
|
202
|
+
$log.debug("Clearing GUI and Results")
|
203
|
+
return if(@test_running)
|
204
|
+
@controller = nil
|
205
|
+
ws_clear_results_from_grid()
|
206
|
+
$conf.urls.each_index do |i|
|
207
|
+
@hosts_listbox.check(i, false)
|
208
|
+
end
|
209
|
+
@pbar.set_value(0)
|
210
|
+
@response_html.set_page("")
|
211
|
+
@response_text.set_value("")
|
212
|
+
@cert_info.set_value("")
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
###########################################################
|
217
|
+
##+ Begin creating all GUI elements and related functionalities for WorkSheet Tab
|
218
|
+
###########################################################
|
219
|
+
|
220
|
+
def ws_sync_from_conf()
|
221
|
+
$log.debug("Synchronizing configuration to GUI")
|
222
|
+
choices = {true => "1", false => ""}
|
223
|
+
rows = @ws_cipher_grid.get_number_rows
|
224
|
+
0.upto(rows - 1) do |row|
|
225
|
+
@ws_cipher_grid.set_cell_value(row, TEST_COL, choices[$conf.cipher_suites[row].test])
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
def ws_sync_to_conf()
|
231
|
+
$log.debug("Synchronizing GUI to configuration")
|
232
|
+
choices = {"" => false, "1" => true}
|
233
|
+
rows = @ws_cipher_grid.get_number_rows
|
234
|
+
0.upto(rows - 1) do |row|
|
235
|
+
cell_val = @ws_cipher_grid.get_cell_value(row, TEST_COL)
|
236
|
+
$conf.cipher_suites[row].test = choices[cell_val]
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
def ws_start_test(event)
|
242
|
+
return if(@test_running || $conf.urls == [])
|
243
|
+
$log.debug("Starting Test")
|
244
|
+
@stop_test = false
|
245
|
+
ws_sync_to_conf()
|
246
|
+
clear_gui_and_results()
|
247
|
+
@test_running = true
|
248
|
+
|
249
|
+
@controller = SSLSmartController.new
|
250
|
+
x = Thread.new do
|
251
|
+
$log.debug "Starting test thread"
|
252
|
+
begin
|
253
|
+
@controller.start_test do |url, url_index, suite_index|
|
254
|
+
|
255
|
+
progress = @controller.get_progress(url).to_i
|
256
|
+
if(@hosts_listbox.get_string_selection == url)
|
257
|
+
ws_populate_one_cipher_result(suite_index, @controller.get_response(url, suite_index)) if(suite_index)
|
258
|
+
ws_populate_cert_info(url)
|
259
|
+
@pbar.set_value(progress)
|
260
|
+
end
|
261
|
+
@hosts_listbox.check(url_index) if(progress == 100)
|
262
|
+
if(@stop_test)
|
263
|
+
@test_running = false
|
264
|
+
$log.warn("Forcibly killed thread")
|
265
|
+
Thread.kill(x)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
@test_running = false
|
269
|
+
#@controller.show_results
|
270
|
+
rescue => ex
|
271
|
+
$log.fatal(ex.message)
|
272
|
+
$log.fatal(ex.backtrace)
|
273
|
+
ensure
|
274
|
+
@test_running = false
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
#event.skip
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
def ws_refresh_hosts_listbox(event)
|
283
|
+
@hosts_listbox.set($conf.urls)
|
284
|
+
event.skip
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
def ws_add_single_host(event)
|
289
|
+
$log.debug("Adding a single host")
|
290
|
+
host_entry_box = Wx::TextEntryDialog.new(@ws_mpanel,"", "Add URL/Host to Test")
|
291
|
+
retval = host_entry_box.show_modal
|
292
|
+
if(retval == Wx::ID_OK)
|
293
|
+
#url = SSLMisc.convert_to_url(host_entry_box.get_value)
|
294
|
+
url = convert_to_url(host_entry_box.get_value)
|
295
|
+
$conf.update_config({:urls => $conf.urls | [url]}) if(url)
|
296
|
+
ws_refresh_hosts_listbox(event)
|
297
|
+
end
|
298
|
+
event.skip
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
def ws_import_hosts(event)
|
303
|
+
$log.debug("Adding a multiple hosts")
|
304
|
+
file_control = Wx::FileDialog.new(@ws_mpanel, "Input File containing host entries (one per line)", "", "", "Text Files (*.txt)|*.txt", Wx::FD_MULTIPLE)
|
305
|
+
file_control.show_modal
|
306
|
+
file_names = file_control.get_paths
|
307
|
+
file_names.each do |x|
|
308
|
+
if(File.file?(x))
|
309
|
+
#urls = SSLMisc.get_urls_from_file(x)
|
310
|
+
urls = get_urls_from_file(x)
|
311
|
+
$conf.update_config({:urls => $conf.urls | urls})
|
312
|
+
ws_refresh_hosts_listbox(event)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
event.skip
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
def ws_rem_hosts(event)
|
320
|
+
$log.debug("Removing hosts")
|
321
|
+
|
322
|
+
return if(@test_running)
|
323
|
+
arr = @hosts_listbox.get_selections
|
324
|
+
arr += @hosts_listbox.get_checked_items
|
325
|
+
keep = (0...$conf.urls.length).to_a - arr
|
326
|
+
$conf.update_config({:urls => $conf.urls.values_at(*keep)})
|
327
|
+
ws_refresh_hosts_listbox(event)
|
328
|
+
event.skip
|
329
|
+
end
|
330
|
+
|
331
|
+
|
332
|
+
def ws_rem_all_hosts(event)
|
333
|
+
$log.debug("Removing all hosts")
|
334
|
+
return if(@test_running)
|
335
|
+
clear_gui_and_results()
|
336
|
+
$conf.update_config({:urls => []})
|
337
|
+
ws_refresh_hosts_listbox(event)
|
338
|
+
event.skip
|
339
|
+
end
|
340
|
+
|
341
|
+
def ws_stop_test(event)
|
342
|
+
$log.info("Attempt to stop test")
|
343
|
+
@stop_test = true
|
344
|
+
end
|
345
|
+
|
346
|
+
|
347
|
+
def ws_clear_results(event)
|
348
|
+
$log.debug("Clearing all results")
|
349
|
+
clear_gui_and_results()
|
350
|
+
event.skip
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
def ws_create_buttons(parent_panel, sizer)
|
355
|
+
ws_hosts_button_hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL) # sizer for hosts button controls
|
356
|
+
|
357
|
+
ws_start_test = Wx::Button.new(parent_panel, Wx::ID_ANY, "Start Test" , Wx::DEFAULT_POSITION, HOST_BUTTON_SIZE)
|
358
|
+
# Threads should come here
|
359
|
+
evt_button(ws_start_test.get_id()) { |event| ws_start_test(event) }
|
360
|
+
|
361
|
+
# Add URL/Host Button and Corresponding event handlers
|
362
|
+
ws_add_host = Wx::Button.new(parent_panel, Wx::ID_ANY, "Add URL/Host" , Wx::DEFAULT_POSITION, HOST_BUTTON_SIZE)
|
363
|
+
evt_button(ws_add_host.get_id()) { |event| ws_add_single_host(event)}
|
364
|
+
|
365
|
+
# Import URL's/Hosts
|
366
|
+
ws_import_hosts = Wx::Button.new(parent_panel, Wx::ID_ANY, "Import URLs/Hosts" , Wx::DEFAULT_POSITION, HOST_BUTTON_SIZE)
|
367
|
+
evt_button(ws_import_hosts.get_id()) { |event| ws_import_hosts(event)}
|
368
|
+
|
369
|
+
# Remove one host
|
370
|
+
ws_rem_host = Wx::Button.new(parent_panel, Wx::ID_ANY, "Remove" , Wx::DEFAULT_POSITION, HOST_BUTTON_SIZE)
|
371
|
+
evt_button(ws_rem_host.get_id()) { |event| ws_rem_hosts(event)}
|
372
|
+
|
373
|
+
# Remove one host
|
374
|
+
ws_rem_all_hosts = Wx::Button.new(parent_panel, Wx::ID_ANY, "Remove All" , Wx::DEFAULT_POSITION, HOST_BUTTON_SIZE)
|
375
|
+
evt_button(ws_rem_all_hosts.get_id()) { |event| ws_rem_all_hosts(event)}
|
376
|
+
|
377
|
+
ws_clear_results = Wx::Button.new(parent_panel, Wx::ID_ANY, "Clear Results" , Wx::DEFAULT_POSITION, HOST_BUTTON_SIZE)
|
378
|
+
evt_button(ws_clear_results.get_id()) { |event| ws_clear_results(event)}
|
379
|
+
|
380
|
+
ws_stop_test = Wx::Button.new(parent_panel, Wx::ID_ANY, "Stop Test" , Wx::DEFAULT_POSITION, HOST_BUTTON_SIZE)
|
381
|
+
evt_button(ws_stop_test.get_id()) { |event| ws_stop_test(event)}
|
382
|
+
|
383
|
+
ws_hosts_button_hsizer.add_item(ws_start_test , -1, 0, Wx::ALL, HOST_CONTROL_SPACING)
|
384
|
+
ws_hosts_button_hsizer.add_item(ws_add_host , -1, 0, Wx::ALL, HOST_CONTROL_SPACING)
|
385
|
+
ws_hosts_button_hsizer.add_item(ws_import_hosts , -1, 0, Wx::ALL, HOST_CONTROL_SPACING)
|
386
|
+
ws_hosts_button_hsizer.add_item(ws_rem_host , -1, 0, Wx::ALL, HOST_CONTROL_SPACING)
|
387
|
+
ws_hosts_button_hsizer.add_item(ws_rem_all_hosts , -1, 0, Wx::ALL, HOST_CONTROL_SPACING)
|
388
|
+
ws_hosts_button_hsizer.add_item(ws_clear_results , -1, 0, Wx::ALL, HOST_CONTROL_SPACING)
|
389
|
+
ws_hosts_button_hsizer.add_item(ws_stop_test , -1, 0, Wx::ALL, HOST_CONTROL_SPACING)
|
390
|
+
|
391
|
+
sizer.add_item(ws_hosts_button_hsizer , -1, 0, Wx::EXPAND|Wx::ALL)
|
392
|
+
|
393
|
+
end
|
394
|
+
|
395
|
+
|
396
|
+
def ws_populate_cipher_result(event)
|
397
|
+
@response_html.set_page("")
|
398
|
+
@response_text.set_value("")
|
399
|
+
return unless(@controller)
|
400
|
+
|
401
|
+
@selected_grid_row = event.get_row
|
402
|
+
url = @hosts_listbox.get_string_selection
|
403
|
+
if(url != "")
|
404
|
+
html_response = @controller.get_html_response(url, @selected_grid_row)
|
405
|
+
text_response = @controller.get_text_response(url, @selected_grid_row)
|
406
|
+
|
407
|
+
@response_html.set_page(html_response) if(html_response)
|
408
|
+
@response_text.set_value(text_response) if(text_response)
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
|
413
|
+
def ws_populate_cipher_result_for_url(url)
|
414
|
+
@response_html.set_page("")
|
415
|
+
@response_text.set_value("")
|
416
|
+
return unless(@controller)
|
417
|
+
|
418
|
+
if(url != "")
|
419
|
+
html_response = @controller.get_html_response(url, @selected_grid_row)
|
420
|
+
text_response = @controller.get_text_response(url, @selected_grid_row)
|
421
|
+
|
422
|
+
@response_html.set_page(html_response) if(html_response)
|
423
|
+
@response_text.set_value(text_response) if(text_response)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
|
428
|
+
def ws_create_cipher_grid(parent_panel, sizer)
|
429
|
+
# TEST_COL = 0
|
430
|
+
# VERSION_COL = 1
|
431
|
+
# NAME_COL = 2
|
432
|
+
# BITS_COL = 3
|
433
|
+
# SUPPORTED_COL = 4
|
434
|
+
# HTTP_COL = 5
|
435
|
+
|
436
|
+
read_only = Wx::GridCellAttr.new
|
437
|
+
#read_only.set_read_only
|
438
|
+
# Starting the Cipher Grid GUI Code Here
|
439
|
+
cipher_hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL) # sizer for ciphers grid
|
440
|
+
|
441
|
+
# @ws_cipher_grid is instance variable because it is going to be needed across functions and entire functionality
|
442
|
+
@ws_cipher_grid = Wx::Grid.new(parent_panel, -1, Wx::DEFAULT_POSITION, [CIPHER_GRID_WIDTH , CIPHER_GRID_HEIGHT])
|
443
|
+
#@ws_cipher_grid.auto_size
|
444
|
+
|
445
|
+
@ws_cipher_grid.create_grid($conf.cipher_suites.length, GRID_COLS)
|
446
|
+
#@ws_cipher_grid.enable_editing(false)
|
447
|
+
#@ws_cipher_grid.disable_cell_edit_control
|
448
|
+
@ws_cipher_grid.set_col_label_size(25)
|
449
|
+
@ws_cipher_grid.set_row_label_size(25)
|
450
|
+
@ws_cipher_grid.set_col_label_value( TEST_COL, "Test?" )
|
451
|
+
@ws_cipher_grid.set_col_size( TEST_COL, 35 )
|
452
|
+
|
453
|
+
@ws_cipher_grid.set_col_label_value( VERSION_COL, "SSL Version" )
|
454
|
+
@ws_cipher_grid.set_col_attr(VERSION_COL, read_only)
|
455
|
+
|
456
|
+
@ws_cipher_grid.set_col_label_value( NAME_COL, "Cipher Name" )
|
457
|
+
@ws_cipher_grid.set_col_size( NAME_COL, 200 )
|
458
|
+
@ws_cipher_grid.set_col_attr(NAME_COL, read_only)
|
459
|
+
|
460
|
+
@ws_cipher_grid.set_col_label_value( BITS_COL, "Key Length (bits)" )
|
461
|
+
@ws_cipher_grid.set_col_size( BITS_COL, 125 )
|
462
|
+
@ws_cipher_grid.set_col_attr(BITS_COL, read_only)
|
463
|
+
|
464
|
+
@ws_cipher_grid.set_col_label_value( SUPPORTED_COL, "Supported?" )
|
465
|
+
@ws_cipher_grid.set_col_attr(SUPPORTED_COL, read_only)
|
466
|
+
|
467
|
+
@ws_cipher_grid.set_col_label_value( HTTP_COL, "Response Code" )
|
468
|
+
@ws_cipher_grid.set_col_size( HTTP_COL, 180 )
|
469
|
+
@ws_cipher_grid.set_col_attr(HTTP_COL, read_only)
|
470
|
+
evt_grid_select_cell() {|event| ws_populate_cipher_result(event); event.skip}
|
471
|
+
#@ws_cipher_grid.set_selection_mode(Wx::Grid::GridSelectRows)
|
472
|
+
#@ws_cipher_grid.can_enable_cell_control
|
473
|
+
#populate_grid
|
474
|
+
|
475
|
+
# The below code was needs to be uncommented. ONLY ONE LINE
|
476
|
+
#evt_grid_select_cell() {|event| populate_cipher_result_in_html_box(event); event.skip}
|
477
|
+
#evt_grid_range_select() {|event| selected(event)}
|
478
|
+
|
479
|
+
cipher_hsizer.add_item(@ws_cipher_grid, -1, 0, Wx::EXPAND|Wx::ALL)
|
480
|
+
|
481
|
+
sizer.add_item(cipher_hsizer, -1, CIPHER_PROPORTION, Wx::EXPAND|Wx::ALL, HOST_CONTROL_SPACING)
|
482
|
+
# Ending the Cipher Grid GUI Code Here
|
483
|
+
|
484
|
+
end
|
485
|
+
|
486
|
+
|
487
|
+
def ws_create_progress_bar(parent_panel, sizer)
|
488
|
+
pbar_hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL) # sizer for ciphers grid
|
489
|
+
@pbar = Wx::Gauge.new(parent_panel, -1, 100, Wx::DEFAULT_POSITION, [775,20])
|
490
|
+
pbar_hsizer.add_item(@pbar, -1, 0, Wx::EXPAND|Wx::ALL)
|
491
|
+
sizer.add_item(pbar_hsizer, -1, 0, Wx::EXPAND|Wx::ALL)
|
492
|
+
end
|
493
|
+
|
494
|
+
def ws_html_click(event)
|
495
|
+
return
|
496
|
+
end
|
497
|
+
|
498
|
+
def ws_create_response_display(parent_panel, sizer)
|
499
|
+
new_notebook = Wx::Notebook.new(parent_panel)
|
500
|
+
|
501
|
+
html_tab = Wx::Panel.new(new_notebook) # Add HTML display
|
502
|
+
html_sizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
503
|
+
html_tab.set_sizer(html_sizer)
|
504
|
+
@response_html = Wx::HtmlWindow.new(html_tab, -1, Wx::DEFAULT_POSITION, [CIPHER_GRID_WIDTH - 15, CIPHER_GRID_HEIGHT], Wx::HW_DEFAULT_STYLE, "HtmlWindow")
|
505
|
+
html_sizer.add_item(@response_html, -1, 0, Wx::EXPAND|Wx::ALL, HOST_CONTROL_SPACING)
|
506
|
+
evt_html_link_clicked(@response_html.get_id()) { | event | ws_html_click(event) }
|
507
|
+
evt_html_cell_clicked(@response_html.get_id()) { | event | ws_html_click(event) }
|
508
|
+
|
509
|
+
text_tab = Wx::Panel.new(new_notebook) # Add HTML display
|
510
|
+
text_sizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
511
|
+
text_tab.set_sizer(text_sizer)
|
512
|
+
@response_text = Wx::TextCtrl.new(text_tab, -1, "", Wx::DEFAULT_POSITION, [CIPHER_GRID_WIDTH - 15, CIPHER_GRID_HEIGHT], Wx::TE_READONLY|Wx::TE_MULTILINE, Wx::DEFAULT_VALIDATOR, "TextWindow")
|
513
|
+
text_sizer.add_item(@response_text, -1, 0, Wx::EXPAND|Wx::ALL, HOST_CONTROL_SPACING)
|
514
|
+
|
515
|
+
new_notebook.add_page(html_tab , "HTML")
|
516
|
+
new_notebook.add_page(text_tab , "Text")
|
517
|
+
sizer.add_item(new_notebook, -1, HTML_PROPORTION, Wx::EXPAND|Wx::ALL, HOST_CONTROL_SPACING)
|
518
|
+
end
|
519
|
+
|
520
|
+
|
521
|
+
def ws_create_cert_display(parent_panel, sizer)
|
522
|
+
#@cert_info = Wx::TextCtrl.new(parent_panel, -1, "", Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::TE_READONLY|Wx::TE_MULTILINE|Wx::TE_RICH|Wx::TE_RICH2)
|
523
|
+
hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
524
|
+
@cert_info = Wx::TextCtrl.new(parent_panel, -1, "", Wx::DEFAULT_POSITION, [CIPHER_GRID_WIDTH, CIPHER_GRID_HEIGHT], Wx::TE_READONLY|Wx::TE_MULTILINE|Wx::TE_RICH|Wx::TE_RICH2)
|
525
|
+
hsizer.add_item(@cert_info, -1, 0, Wx::EXPAND|Wx::ALL)
|
526
|
+
sizer.add_item(hsizer, -1, CERT_PROPORTION, Wx::EXPAND|Wx::ALL, HOST_CONTROL_SPACING)
|
527
|
+
|
528
|
+
end
|
529
|
+
|
530
|
+
|
531
|
+
def ws_populate_cert_info(url)
|
532
|
+
$log.debug("Populating certificate information")
|
533
|
+
@cert_info.set_value("")
|
534
|
+
return unless(@controller)
|
535
|
+
cert = @controller.get_cert(url)
|
536
|
+
return unless(cert)
|
537
|
+
txtattr = Wx::TextAttr.new(Wx::BLACK)
|
538
|
+
cert_validity = @controller.cert_valid?(url)
|
539
|
+
|
540
|
+
case cert_validity.status
|
541
|
+
when true
|
542
|
+
txtattr.set_background_colour(Wx::GREEN)
|
543
|
+
@cert_info.set_default_style(txtattr)
|
544
|
+
@cert_info.append_text("[+] Valid Digital Certificate\n")
|
545
|
+
when false
|
546
|
+
txtattr.set_background_colour(Wx::RED)
|
547
|
+
@cert_info.set_default_style(txtattr)
|
548
|
+
@cert_info.append_text("[-] Invalid Digital Certificate. #{cert_validity.data}\n")
|
549
|
+
end
|
550
|
+
|
551
|
+
if(cert.data.class == OpenSSL::X509::Certificate)
|
552
|
+
@cert_info.append_text(cert.data.to_text)
|
553
|
+
else
|
554
|
+
@cert_info.append_text(cert.data)
|
555
|
+
end
|
556
|
+
@cert_info.set_insertion_point(0)
|
557
|
+
end
|
558
|
+
|
559
|
+
|
560
|
+
def ws_clear_results_from_grid()
|
561
|
+
$log.debug("Clearing all results from cipher grid")
|
562
|
+
cipher_count = $conf.cipher_suites.length
|
563
|
+
0.upto(cipher_count - 1) do |index|
|
564
|
+
@ws_cipher_grid.set_cell_value(index, SUPPORTED_COL, "")
|
565
|
+
@ws_cipher_grid.set_cell_value(index, HTTP_COL, "")
|
566
|
+
@ws_cipher_grid.set_cell_background_colour(index, SUPPORTED_COL, Wx::NULL_COLOUR)
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
# To be used inside SSLController.start_test
|
571
|
+
def ws_populate_one_cipher_result(suite_index, result)
|
572
|
+
return unless(result)
|
573
|
+
case result.status
|
574
|
+
when true
|
575
|
+
@ws_cipher_grid.set_cell_value(suite_index, SUPPORTED_COL, "Yes")
|
576
|
+
@ws_cipher_grid.set_cell_background_colour(suite_index, SUPPORTED_COL, Wx::GREEN)
|
577
|
+
@ws_cipher_grid.set_cell_value(suite_index, HTTP_COL, "HTTP\/#{result.data.http_version} #{result.data.code} #{result.data.msg}") if(result.data)
|
578
|
+
when false
|
579
|
+
@ws_cipher_grid.set_cell_value(suite_index, SUPPORTED_COL, "No")
|
580
|
+
@ws_cipher_grid.set_cell_background_colour(suite_index, SUPPORTED_COL, Wx::RED)
|
581
|
+
@ws_cipher_grid.set_cell_value(suite_index, HTTP_COL, "#{result.data}") if(result.data)
|
582
|
+
end # end of case
|
583
|
+
end
|
584
|
+
|
585
|
+
|
586
|
+
def ws_populate_host_results(url)
|
587
|
+
ws_clear_results_from_grid()
|
588
|
+
return unless(@controller)
|
589
|
+
cipher_results = @controller.get_all_cipher_results(url)
|
590
|
+
return if(cipher_results == nil || cipher_results == [])
|
591
|
+
|
592
|
+
cipher_results.each_with_index do |result, index|
|
593
|
+
ws_populate_one_cipher_result(index, result)
|
594
|
+
# case result.status
|
595
|
+
# when true
|
596
|
+
# @ws_cipher_grid.set_cell_value(index, SUPPORTED_COL, "Yes")
|
597
|
+
# @ws_cipher_grid.set_cell_background_colour(index, SUPPORTED_COL, Wx::GREEN)
|
598
|
+
# @ws_cipher_grid.set_cell_value(index, HTTP_COL, "HTTP\/#{result.data.http_version} #{result.data.code} #{result.data.msg}") if(result.data)
|
599
|
+
# when false
|
600
|
+
# @ws_cipher_grid.set_cell_value(index, SUPPORTED_COL, "No")
|
601
|
+
# @ws_cipher_grid.set_cell_background_colour(index, SUPPORTED_COL, Wx::RED)
|
602
|
+
# #@cipher_grid.set_cell_value(index, HTTP_COL, "#{result.data.message}") if(result.data)
|
603
|
+
# @ws_cipher_grid.set_cell_value(index, HTTP_COL, "#{result.data}") if(result.data)
|
604
|
+
# end # end of case
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
|
609
|
+
def ws_populate_progress(url)
|
610
|
+
return unless(@controller)
|
611
|
+
@pbar.set_value(@controller.get_progress(url).to_i)
|
612
|
+
end
|
613
|
+
|
614
|
+
|
615
|
+
def ws_populate_cert_info_and_test_results(url)
|
616
|
+
@response_html.set_page("")
|
617
|
+
@response_text.set_value("")
|
618
|
+
ws_populate_progress(url)
|
619
|
+
ws_populate_cipher_result_for_url(url)
|
620
|
+
ws_populate_cert_info(url)
|
621
|
+
ws_populate_host_results(url)
|
622
|
+
end
|
623
|
+
|
624
|
+
|
625
|
+
def ws_create_hosts_control(parent_panel, sizer)
|
626
|
+
hosts_hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL) # sizer for hosts controls
|
627
|
+
@hosts_listbox = Wx::CheckListBox.new(parent_panel, -1, [10,10], [HOST_BOX_WIDTH,HOST_BOX_HEIGHT])#, ["1","3","4","5"], Wx::TE_READONLY)
|
628
|
+
|
629
|
+
#Uncomment the line below to make it working
|
630
|
+
evt_listbox(@hosts_listbox.get_id()) {|event| ws_populate_cert_info_and_test_results(@hosts_listbox.get_string_selection) }
|
631
|
+
|
632
|
+
hosts_hsizer.add_item(@hosts_listbox, -1, 0, Wx::EXPAND|Wx::ALL, HOST_CONTROL_SPACING)
|
633
|
+
sizer.add_item(hosts_hsizer , -1, HOSTS_PROPORTION, Wx::EXPAND|Wx::ALL)
|
634
|
+
end
|
635
|
+
|
636
|
+
|
637
|
+
def ws_create_gui(parent_panel, sizer)
|
638
|
+
$log.info("Creating WorkSpace GUI Tab")
|
639
|
+
ws_create_buttons(parent_panel, sizer)
|
640
|
+
ws_create_hosts_control(parent_panel, sizer)
|
641
|
+
ws_create_cipher_grid(parent_panel, sizer)
|
642
|
+
ws_create_progress_bar(parent_panel, sizer)
|
643
|
+
ws_create_response_display(parent_panel, sizer)
|
644
|
+
ws_create_cert_display(parent_panel, sizer)
|
645
|
+
end
|
646
|
+
|
647
|
+
###########################################################
|
648
|
+
##+ End of all GUI elements for WorkSheet Tab
|
649
|
+
###########################################################
|
650
|
+
|
651
|
+
###########################################################
|
652
|
+
##+ Begin creating all GUI elements for Options Tab
|
653
|
+
###########################################################
|
654
|
+
|
655
|
+
def options_update_config(event, hash)
|
656
|
+
return if(@test_running)
|
657
|
+
$conf.update_config(hash)
|
658
|
+
clear_gui_and_results() if(hash.has_key?(:scan_mode) || hash.has_key?(:scan_type) )
|
659
|
+
ws_sync_from_conf() if(hash.has_key?(:sslv2) || hash.has_key?(:tlsv1)|| hash.has_key?(:sslv3) )
|
660
|
+
event.skip
|
661
|
+
end
|
662
|
+
|
663
|
+
|
664
|
+
def options_create_cipher_checkbox(parent_panel, sizer)
|
665
|
+
sslv2 = "SSLv2"
|
666
|
+
sslv3 = "SSLv3"
|
667
|
+
tlsv1 = "TLSv1"
|
668
|
+
ssl_hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
669
|
+
ssl_static_box = Wx::StaticBox.new(parent_panel, -1, "SSL Cipher Versions To Test")
|
670
|
+
ssl_vsizer = Wx::StaticBoxSizer.new(ssl_static_box, Wx::VERTICAL)
|
671
|
+
|
672
|
+
|
673
|
+
# IT IS NOT MANDATORY TO HAVE @sslv2, @sslv3 and @tlsv1 as instance variables.
|
674
|
+
# LOOK Into possibility of changing these to local variables
|
675
|
+
|
676
|
+
@sslv2 = Wx::CheckBox.new(parent_panel, -1, sslv2)
|
677
|
+
@sslv2.set_value($conf.sslv2)
|
678
|
+
evt_checkbox(@sslv2.get_id()) { |event| options_update_config(event, {:sslv2 => @sslv2.get_value}) }
|
679
|
+
|
680
|
+
@sslv3 = Wx::CheckBox.new(parent_panel, -1, sslv3)
|
681
|
+
@sslv3.set_value($conf.sslv3)
|
682
|
+
evt_checkbox(@sslv3.get_id()) { |event| options_update_config(event, {:sslv3 => @sslv3.get_value}) }
|
683
|
+
|
684
|
+
@tlsv1 = Wx::CheckBox.new(parent_panel, -1, tlsv1)
|
685
|
+
@tlsv1.set_value($conf.tlsv1)
|
686
|
+
evt_checkbox(@tlsv1.get_id()) { |event| options_update_config(event, {:tlsv1 => @tlsv1.get_value}) }
|
687
|
+
|
688
|
+
ssl_vsizer.add_item(@sslv2, -1, 0)
|
689
|
+
ssl_vsizer.add_item(@sslv3, -1, 0)
|
690
|
+
ssl_vsizer.add_item(@tlsv1, -1, 0)
|
691
|
+
#@ws_mvsizer.add_item(@hosts_button_hsizer , -1, 0, Wx::EXPAND|Wx::ALL)
|
692
|
+
|
693
|
+
ssl_hsizer.add_item(ssl_vsizer, -1, 1, Wx::EXPAND|Wx::ALL)
|
694
|
+
sizer.add_item(ssl_hsizer, -1, 0, Wx::EXPAND|Wx::ALL, 10)
|
695
|
+
|
696
|
+
end
|
697
|
+
|
698
|
+
|
699
|
+
def options_content_connect_radio(parent_panel, sizer)
|
700
|
+
choices = SSLSmartConfig::SCAN_TYPES
|
701
|
+
hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
702
|
+
@content_connect = Wx::RadioBox.new(parent_panel, -1, "Perform Content or Connect Test", Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, choices)
|
703
|
+
evt_radiobox(@content_connect.get_id()) {|event| options_update_config(event, {:scan_type => @content_connect.get_selection})}
|
704
|
+
@content_connect.set_string_selection("#{$conf.scan_type}")
|
705
|
+
hsizer.add_item(@content_connect, -1, 1, Wx::EXPAND|Wx::ALL)
|
706
|
+
sizer.add_item(hsizer, -1, 0, Wx::EXPAND|Wx::ALL, 10)
|
707
|
+
end
|
708
|
+
|
709
|
+
|
710
|
+
def options_suite_version_radio(parent_panel, sizer)
|
711
|
+
choices = SSLSmartConfig::SCAN_MODES
|
712
|
+
hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
713
|
+
@scan_mode = Wx::RadioBox.new(parent_panel, -1, "Select Test Option", Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, choices)
|
714
|
+
evt_radiobox(@scan_mode.get_id()) {|event| options_update_config(event, {:scan_mode => @scan_mode.get_selection}); options_apply_filter(@filter_combo.get_value())}
|
715
|
+
#evt_radiobox(@scan_mode.get_id()) {|event| options_update_config(event, {:scan_mode => @scan_mode.get_selection})}
|
716
|
+
@scan_mode.set_string_selection("#{$conf.scan_mode}")
|
717
|
+
hsizer.add_item(@scan_mode, -1, 1, Wx::EXPAND|Wx::ALL)
|
718
|
+
sizer.add_item(hsizer, -1, 0, Wx::EXPAND|Wx::ALL, 10)
|
719
|
+
end
|
720
|
+
|
721
|
+
|
722
|
+
def options_proxy_config(parent_panel, sizer)
|
723
|
+
proxy_input = Wx::StaticBox.new(parent_panel, -1, "Proxy Configuration (Must be a Transparent Proxy)")
|
724
|
+
proxy_vsizer = Wx::StaticBoxSizer.new(proxy_input, Wx::VERTICAL)
|
725
|
+
|
726
|
+
proxy_add_hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
727
|
+
proxy_port_hsizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
728
|
+
|
729
|
+
proxy_add_tag = Wx::StaticText.new(parent_panel, -1, "Proxy Address", Wx::DEFAULT_POSITION, [100,25])
|
730
|
+
@proxy_add = Wx::TextCtrl.new(parent_panel, -1, "", Wx::DEFAULT_POSITION, [150,25])
|
731
|
+
evt_text(@proxy_add.get_id()) {|event| options_update_config(event, {:proxy_add => @proxy_add.get_value})}
|
732
|
+
proxy_add_hsizer.add_item(proxy_add_tag)
|
733
|
+
proxy_add_hsizer.add_item(@proxy_add)
|
734
|
+
|
735
|
+
proxy_port_tag = Wx::StaticText.new(parent_panel, -1, "Proxy Port", Wx::DEFAULT_POSITION, [100,25])
|
736
|
+
@proxy_port = Wx::TextCtrl.new(parent_panel, -1, "", Wx::DEFAULT_POSITION, [150,25])
|
737
|
+
evt_text(@proxy_port.get_id()) {|event| options_update_config(event, {:proxy_port => @proxy_port.get_value})}
|
738
|
+
proxy_port_hsizer.add_item(proxy_port_tag)
|
739
|
+
proxy_port_hsizer.add_item(@proxy_port)
|
740
|
+
|
741
|
+
proxy_vsizer.add_item(proxy_add_hsizer)
|
742
|
+
proxy_vsizer.add_item(proxy_port_hsizer)
|
743
|
+
|
744
|
+
sizer.add_item(proxy_vsizer, -1, 0, Wx::EXPAND|Wx::ALL, 10)
|
745
|
+
end
|
746
|
+
|
747
|
+
|
748
|
+
def options_lookup_pem_file(parent_panel, event)
|
749
|
+
$log.debug("Looking up pem file")
|
750
|
+
return if(@test_running)
|
751
|
+
pem_file_control = Wx::FileDialog.new(parent_panel, "Choose Pem File with Root CA Certificates", "", "", "Pem Files (*.pem)|*.pem")
|
752
|
+
pem_file_control.show_modal
|
753
|
+
file_names = pem_file_control.get_paths
|
754
|
+
file_names.each do |x|
|
755
|
+
if(File.file?(x))
|
756
|
+
@pem_path.set_value(x)
|
757
|
+
$conf.update_config({:pem_path => x})
|
758
|
+
end
|
759
|
+
end
|
760
|
+
event.skip
|
761
|
+
end
|
762
|
+
|
763
|
+
|
764
|
+
def options_pem_config(parent_panel, sizer)
|
765
|
+
pem_input = Wx::StaticBox.new(parent_panel, -1, "PEM File Selector")
|
766
|
+
pem_hsizer = Wx::StaticBoxSizer.new(pem_input, Wx::HORIZONTAL)
|
767
|
+
|
768
|
+
choose_pem_button = Wx::Button.new(parent_panel, -1, "Choose Pem File", Wx::DEFAULT_POSITION, BUTTON_SIZE)
|
769
|
+
evt_button(choose_pem_button.get_id()) { |event| options_lookup_pem_file(parent_panel, event)}
|
770
|
+
|
771
|
+
@pem_path = Wx::TextCtrl.new(parent_panel, -1, $conf.rootcert_path, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::TE_READONLY)
|
772
|
+
|
773
|
+
pem_hsizer.add_item(choose_pem_button)
|
774
|
+
pem_hsizer.add_item(@pem_path, -1, 1, Wx::EXPAND|Wx::ALL)
|
775
|
+
|
776
|
+
sizer.add_item(pem_hsizer, -1, 0, Wx::EXPAND|Wx::ALL, 10)
|
777
|
+
end
|
778
|
+
|
779
|
+
|
780
|
+
def options_apply_filter(value)
|
781
|
+
return if(@test_running)
|
782
|
+
choices = {true => "1", false => ""}
|
783
|
+
clear_gui_and_results() #unless($conf.filter == value)
|
784
|
+
|
785
|
+
begin
|
786
|
+
$conf.update_config({:filter => value})
|
787
|
+
rescue => ex
|
788
|
+
Wx::MessageDialog.new(nil, "Error Occured!!\n#{ex.message}", "", Wx::OK ).show_modal()
|
789
|
+
$log.error "Error occured. #{ex.message}"
|
790
|
+
end
|
791
|
+
|
792
|
+
#Resize the grid if required
|
793
|
+
if ((diff = ($conf.cipher_suites.length - @ws_cipher_grid.get_number_rows)) >= 0 )
|
794
|
+
@ws_cipher_grid.append_rows(diff)
|
795
|
+
else
|
796
|
+
@ws_cipher_grid.delete_rows(0, diff.abs)
|
797
|
+
end
|
798
|
+
|
799
|
+
@ws_cipher_grid.clear_grid()
|
800
|
+
$conf.cipher_suites.each_with_index do |cipher_suite, row_number|
|
801
|
+
@ws_cipher_grid.set_cell_editor(row_number, TEST_COL , Wx::GridCellBoolEditor.new)
|
802
|
+
@ws_cipher_grid.set_cell_renderer(row_number, TEST_COL , Wx::GridCellBoolRenderer.new)
|
803
|
+
@ws_cipher_grid.set_cell_value(row_number, TEST_COL , choices[cipher_suite.test])
|
804
|
+
@ws_cipher_grid.set_cell_value(row_number, VERSION_COL , cipher_suite.version)
|
805
|
+
@ws_cipher_grid.set_cell_value(row_number, NAME_COL , cipher_suite.name.gsub(":",", "))
|
806
|
+
@ws_cipher_grid.set_cell_value(row_number, BITS_COL , cipher_suite.bits)
|
807
|
+
end
|
808
|
+
|
809
|
+
end
|
810
|
+
|
811
|
+
|
812
|
+
def options_cipher_filter(parent_panel, sizer)
|
813
|
+
filters = ["DEFAULT", "DEFAULT:!SSLv2", "DEFAULT:!SSLv3", "HIGH","MEDIUM", "LOW", "LOW:EXP", "LOW:EXP:SSLv2", "ALL:eNULL:aNULL", "NULL", "aNULL"]
|
814
|
+
filter_input = Wx::StaticBox.new(parent_panel, -1, "OpenSSL Filters for Cipher Suite Selection ")
|
815
|
+
hsizer = Wx::StaticBoxSizer.new(filter_input, Wx::HORIZONTAL)
|
816
|
+
@filter_combo = Wx::ComboBox.new(parent_panel, -1, "#{filters[0]}", Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, filters)
|
817
|
+
apply_filter_button = Wx::Button.new(parent_panel, -1, "Apply Filter", Wx::DEFAULT_POSITION, BUTTON_SIZE)
|
818
|
+
|
819
|
+
evt_button(apply_filter_button.get_id()) {|event| options_apply_filter(@filter_combo.get_value())}
|
820
|
+
hsizer.add_item(apply_filter_button, -1, 0, Wx::EXPAND|Wx::ALL)
|
821
|
+
hsizer.add_item(@filter_combo, -1, 1, Wx::EXPAND|Wx::ALL)
|
822
|
+
sizer.add_item(hsizer, -1, 0, Wx::EXPAND|Wx::ALL, 10)
|
823
|
+
|
824
|
+
end
|
825
|
+
|
826
|
+
|
827
|
+
def options_create_gui(parent_panel, sizer)
|
828
|
+
$log.debug("Creating Options GUI Tab")
|
829
|
+
options_create_cipher_checkbox(parent_panel, sizer)
|
830
|
+
options_content_connect_radio(parent_panel, sizer)
|
831
|
+
options_suite_version_radio(parent_panel, sizer)
|
832
|
+
options_proxy_config(parent_panel, sizer)
|
833
|
+
options_pem_config(parent_panel, sizer)
|
834
|
+
options_cipher_filter(parent_panel, sizer)
|
835
|
+
end
|
836
|
+
|
837
|
+
###########################################################
|
838
|
+
##+ End of all GUI elements for Options Tab
|
839
|
+
###########################################################
|
840
|
+
|
841
|
+
|
842
|
+
def init_config()
|
843
|
+
options_apply_filter("DEFAULT")
|
844
|
+
end
|
845
|
+
|
846
|
+
|
847
|
+
def initialize(title,x,y)
|
848
|
+
@controller = nil
|
849
|
+
@test_running = false
|
850
|
+
@stop_test = false
|
851
|
+
@selected_grid_row = 0
|
852
|
+
#@urls = []
|
853
|
+
#super(nil, -1, title, Wx::Point.new(x, y), Wx::Size.new(800, 800),Wx::DEFAULT_FRAME_STYLE & ~ (Wx::RESIZE_BORDER|Wx::RESIZE_BOX|Wx::MAXIMIZE_BOX))
|
854
|
+
super(nil, -1, title, Wx::Point.new(x, y), Wx::Size.new(800, 800))
|
855
|
+
|
856
|
+
|
857
|
+
fs_icon = Wx::Icon.new( File.join( File.expand_path("."), "fs_icon_32.ico"), Wx::BITMAP_TYPE_ICO )
|
858
|
+
set_icon(fs_icon)
|
859
|
+
|
860
|
+
create_menu_bar()
|
861
|
+
# Start GUI Control Creation
|
862
|
+
create_workspace_and_options_tabs()
|
863
|
+
ws_create_gui(@ws_tab, @ws_mvsizer)
|
864
|
+
evt_close {|event| on_my_close()}
|
865
|
+
options_create_gui(@options_tab, @options_mvsizer)
|
866
|
+
# End GUI Creation
|
867
|
+
|
868
|
+
init_config()
|
869
|
+
|
870
|
+
timer = Wx::Timer.new(self, Wx::ID_ANY)
|
871
|
+
evt_timer(timer.id) {Thread.pass}
|
872
|
+
timer.start(10)
|
873
|
+
|
874
|
+
end
|
875
|
+
|
876
|
+
end
|
877
|
+
|
878
|
+
class SSLSmartGUI < Wx::App
|
879
|
+
def on_init()
|
880
|
+
x = 50
|
881
|
+
y = 50
|
882
|
+
frame = SSLSmartFrame.new("SSLSmart", x, y)
|
883
|
+
frame.show(true)
|
884
|
+
end
|
885
|
+
end
|
886
|
+
|
887
|
+
sslsmart = SSLSmartGUI.new
|
888
|
+
sslsmart.main_loop
|