arachni 0.2.4 → 0.3
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/CHANGELOG.md +33 -0
- data/README.md +2 -4
- data/Rakefile +15 -4
- data/bin/arachni +0 -0
- data/bin/arachni_web +0 -0
- data/bin/arachni_web_autostart +0 -0
- data/bin/arachni_xmlrpc +0 -0
- data/bin/arachni_xmlrpcd +0 -0
- data/bin/arachni_xmlrpcd_monitor +0 -0
- data/lib/arachni.rb +1 -1
- data/lib/framework.rb +36 -6
- data/lib/http.rb +12 -5
- data/lib/module/auditor.rb +482 -59
- data/lib/module/base.rb +17 -0
- data/lib/module/manager.rb +26 -2
- data/lib/module/trainer.rb +1 -12
- data/lib/module/utilities.rb +12 -0
- data/lib/parser/auditable.rb +8 -3
- data/lib/parser/elements.rb +11 -0
- data/lib/parser/page.rb +3 -1
- data/lib/parser/parser.rb +130 -18
- data/lib/rpc/xml/server/dispatcher.rb +21 -0
- data/lib/spider.rb +141 -82
- data/lib/ui/cli/cli.rb +2 -3
- data/lib/ui/web/addon_manager.rb +273 -0
- data/lib/ui/web/addons/autodeploy.rb +172 -0
- data/lib/ui/web/addons/autodeploy/lib/manager.rb +291 -0
- data/lib/ui/web/addons/autodeploy/views/index.erb +124 -0
- data/lib/ui/web/addons/sample.rb +78 -0
- data/lib/ui/web/addons/sample/views/index.erb +4 -0
- data/lib/ui/web/addons/scheduler.rb +139 -0
- data/lib/ui/web/addons/scheduler/views/index.erb +131 -0
- data/lib/ui/web/addons/scheduler/views/options.erb +93 -0
- data/lib/ui/web/dispatcher_manager.rb +80 -13
- data/lib/ui/web/instance_manager.rb +87 -0
- data/lib/ui/web/scheduler.rb +166 -0
- data/lib/ui/web/server.rb +142 -202
- data/lib/ui/web/server/public/js/jquery-ui-timepicker.js +985 -0
- data/lib/ui/web/server/public/plugins/sample/style.css +0 -0
- data/lib/ui/web/server/public/style.css +42 -0
- data/lib/ui/web/server/views/addon.erb +15 -0
- data/lib/ui/web/server/views/addons.erb +46 -0
- data/lib/ui/web/server/views/dispatchers.erb +1 -1
- data/lib/ui/web/server/views/instance.erb +9 -11
- data/lib/ui/web/server/views/layout.erb +14 -1
- data/lib/ui/web/server/views/welcome.erb +7 -6
- data/lib/ui/web/utilities.rb +134 -0
- data/modules/audit/code_injection_timing.rb +6 -2
- data/modules/audit/code_injection_timing/payloads.txt +2 -2
- data/modules/audit/os_cmd_injection_timing.rb +7 -3
- data/modules/audit/os_cmd_injection_timing/payloads.txt +1 -1
- data/modules/audit/sqli_blind_rdiff.rb +18 -233
- data/modules/audit/sqli_blind_rdiff/payloads.txt +5 -0
- data/modules/audit/sqli_blind_timing.rb +9 -2
- data/path_extractors/anchors.rb +1 -1
- data/path_extractors/forms.rb +1 -1
- data/path_extractors/frames.rb +1 -1
- data/path_extractors/generic.rb +1 -1
- data/path_extractors/links.rb +1 -1
- data/path_extractors/meta_refresh.rb +1 -1
- data/path_extractors/scripts.rb +1 -1
- data/path_extractors/sitemap.rb +1 -1
- data/plugins/proxy/server.rb +3 -2
- data/plugins/waf_detector.rb +0 -3
- metadata +37 -34
- data/lib/anemone/cookie_store.rb +0 -35
- data/lib/anemone/core.rb +0 -371
- data/lib/anemone/exceptions.rb +0 -5
- data/lib/anemone/http.rb +0 -144
- data/lib/anemone/page.rb +0 -338
- data/lib/anemone/page_store.rb +0 -160
- data/lib/anemone/storage.rb +0 -34
- data/lib/anemone/storage/base.rb +0 -75
- data/lib/anemone/storage/exceptions.rb +0 -15
- data/lib/anemone/storage/mongodb.rb +0 -89
- data/lib/anemone/storage/pstore.rb +0 -50
- data/lib/anemone/storage/redis.rb +0 -90
- data/lib/anemone/storage/tokyo_cabinet.rb +0 -57
- data/lib/anemone/tentacle.rb +0 -40
@@ -0,0 +1,124 @@
|
|
1
|
+
|
2
|
+
<div>
|
3
|
+
|
4
|
+
<form action="<%=root%>/" method="post">
|
5
|
+
<h2>Perform a new deployment</h2>
|
6
|
+
<br/>
|
7
|
+
|
8
|
+
<fieldset>
|
9
|
+
<legend>SSH options:</legend>
|
10
|
+
Host: <input name="host" />
|
11
|
+
Port: <input name="port" value="22" size="4" />
|
12
|
+
Username: <input name="username" />
|
13
|
+
Password (will not be stored): <input name="password" type="password" />
|
14
|
+
</fieldset>
|
15
|
+
<br/>
|
16
|
+
|
17
|
+
<fieldset>
|
18
|
+
<legend>Dispatcher options:</legend>
|
19
|
+
Port: <input name="dispatcher_port" value="7331" />
|
20
|
+
</fieldset>
|
21
|
+
<br/>
|
22
|
+
|
23
|
+
<%= csrf_tag %>
|
24
|
+
<input type="submit" value="Add" />
|
25
|
+
</form>
|
26
|
+
|
27
|
+
<% if show_output || !ret.empty? %>
|
28
|
+
<br/>
|
29
|
+
<h3>Output</h3>
|
30
|
+
<b>Status: <span id="status"><%=ret[:status]%></span></b>
|
31
|
+
<br/>
|
32
|
+
<pre id="output" style="max-height: 400px; overflow: scroll"><%=ret[:output]%></pre>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
</div>
|
36
|
+
|
37
|
+
|
38
|
+
<% if !deployments.empty? %>
|
39
|
+
<br/>
|
40
|
+
<br/>
|
41
|
+
|
42
|
+
<i>(Shutting down a Dispatcher will terminate all its running scans.)</i>
|
43
|
+
<table>
|
44
|
+
<tr>
|
45
|
+
<th>ID</th>
|
46
|
+
<th>Host</th>
|
47
|
+
<th>SSH Port</th>
|
48
|
+
<th>Dispatcher port</th>
|
49
|
+
<th>Username</th>
|
50
|
+
<th>Password</th>
|
51
|
+
<th>Running?</th>
|
52
|
+
<th>Created at</th>
|
53
|
+
<th>Action</th>
|
54
|
+
</tr>
|
55
|
+
<% deployments.each do |dep| %>
|
56
|
+
<tr>
|
57
|
+
|
58
|
+
<form action="<%=root%>/<%=dep.id%>" method="post">
|
59
|
+
<td><%=dep.id%></td>
|
60
|
+
<td><%=dep.host%></td>
|
61
|
+
<td><%=dep.port%></td>
|
62
|
+
<td><%=dep.dispatcher_port%></td>
|
63
|
+
<td><%=dep.user%></td>
|
64
|
+
<td><input name="password" type="password" /></td>
|
65
|
+
<td><%=is_alive = dispatchers.alive?( 'https://' + dep.host + ':' + dep.dispatcher_port )%></td>
|
66
|
+
<td><%=dep.created_at%></td>
|
67
|
+
<td>
|
68
|
+
<%= csrf_tag %>
|
69
|
+
<input type="hidden" name="id" value="<%=dep.id%>">
|
70
|
+
|
71
|
+
<% if !is_alive%>
|
72
|
+
<input type="radio" name="action" value="run"> Run <br/>
|
73
|
+
<%else%>
|
74
|
+
<input type="radio" name="action" value="shutdown"> Shutdown <br/>
|
75
|
+
<%end%>
|
76
|
+
<input type="radio" name="action" value="delete"> Uninstall & Delete <br/>
|
77
|
+
|
78
|
+
<input type="submit" value="Submit">
|
79
|
+
</td>
|
80
|
+
</form>
|
81
|
+
</tr>
|
82
|
+
<% end %>
|
83
|
+
</table>
|
84
|
+
<% else %>
|
85
|
+
<p class="notice">There are no deployments at the moment.</p>
|
86
|
+
<% end %>
|
87
|
+
|
88
|
+
<% if show_output%>
|
89
|
+
<script type="text/javascript">
|
90
|
+
//<![CDATA[
|
91
|
+
|
92
|
+
function updateOutput() {
|
93
|
+
if( !document.getElementById( 'output' ) ) return;
|
94
|
+
|
95
|
+
var output_url = "<%=root%>/channel/<%=channel%>";
|
96
|
+
$.getJSON( output_url, function(data) {
|
97
|
+
if( data.status == 'finished' ) {
|
98
|
+
window.location.replace( "<%=root%>/channel/<%=channel%>/finalize" );
|
99
|
+
} if( data.status == 'failed' ) {
|
100
|
+
document.getElementById( 'status' ).innerHTML = data.status;
|
101
|
+
obj = document.getElementById( 'output' );
|
102
|
+
obj.innerHTML = data.output;
|
103
|
+
} else {
|
104
|
+
|
105
|
+
document.getElementById( 'status' ).innerHTML = data.status;
|
106
|
+
|
107
|
+
obj = document.getElementById( 'output' );
|
108
|
+
obj.innerHTML = data.output;
|
109
|
+
obj.scrollTop = obj.scrollHeight;
|
110
|
+
}
|
111
|
+
});
|
112
|
+
}
|
113
|
+
|
114
|
+
$( document ).ready(function() {
|
115
|
+
|
116
|
+
updateOutput( );
|
117
|
+
setInterval( function() {
|
118
|
+
updateOutput( );
|
119
|
+
}, 1500 );
|
120
|
+
|
121
|
+
})
|
122
|
+
//]]>
|
123
|
+
</script>
|
124
|
+
<%end%>
|
@@ -0,0 +1,78 @@
|
|
1
|
+
=begin
|
2
|
+
Arachni
|
3
|
+
Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
4
|
+
|
5
|
+
This is free software; you can copy and distribute and modify
|
6
|
+
this program under the term of the GPL v2.0 License
|
7
|
+
(See LICENSE file for details)
|
8
|
+
|
9
|
+
=end
|
10
|
+
|
11
|
+
module Arachni
|
12
|
+
module UI
|
13
|
+
module Web
|
14
|
+
module Addons
|
15
|
+
|
16
|
+
#
|
17
|
+
#
|
18
|
+
# Sample add-on, see the code for examples.
|
19
|
+
#
|
20
|
+
# @author: Tasos "Zapotek" Laskos
|
21
|
+
# <tasos.laskos@gmail.com>
|
22
|
+
# <zapotek@segfault.gr>
|
23
|
+
#
|
24
|
+
# @see http://www.sinatrarb.com/intro.html
|
25
|
+
#
|
26
|
+
# @version: 0.1
|
27
|
+
#
|
28
|
+
class Sample < Base
|
29
|
+
|
30
|
+
#
|
31
|
+
# This method gets fired when the plugin is loaded.
|
32
|
+
#
|
33
|
+
def run
|
34
|
+
|
35
|
+
#
|
36
|
+
# You can work with get/post/put/delete handlers just like
|
37
|
+
# when using Sinatra.
|
38
|
+
#
|
39
|
+
get '/' do
|
40
|
+
|
41
|
+
#
|
42
|
+
# From inside the block you have access to regular Sinatra stuff
|
43
|
+
# like sessions, helpers etc.
|
44
|
+
#
|
45
|
+
|
46
|
+
# session => Direct access to the session, *be careful!*.
|
47
|
+
# settings => Direct access to the Sinatra methods, attributes, etc.
|
48
|
+
|
49
|
+
# You can treat 'present' just like 'erb' with a default layout.
|
50
|
+
present :index, :msg => 'world'
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# This optional method allows you to specify the title which will be
|
57
|
+
# used for the menu (in case you want it to be dynamic).
|
58
|
+
#
|
59
|
+
def title
|
60
|
+
'Sample'
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.info
|
64
|
+
{
|
65
|
+
:name => 'Sample add-on',
|
66
|
+
:description => %q{This add-on serves as an example/tutorial.},
|
67
|
+
:author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com> ',
|
68
|
+
:version => '0.1'
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
=begin
|
2
|
+
Arachni
|
3
|
+
Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
4
|
+
|
5
|
+
This is free software; you can copy and distribute and modify
|
6
|
+
this program under the term of the GPL v2.0 License
|
7
|
+
(See LICENSE file for details)
|
8
|
+
|
9
|
+
=end
|
10
|
+
|
11
|
+
module Arachni
|
12
|
+
module UI
|
13
|
+
module Web
|
14
|
+
module Addons
|
15
|
+
|
16
|
+
#
|
17
|
+
#
|
18
|
+
# Scheduler add-on.
|
19
|
+
#
|
20
|
+
# @author: Tasos "Zapotek" Laskos
|
21
|
+
# <tasos.laskos@gmail.com>
|
22
|
+
# <zapotek@segfault.gr>
|
23
|
+
#
|
24
|
+
# @version: 0.1
|
25
|
+
#
|
26
|
+
class Scheduler < Base
|
27
|
+
|
28
|
+
def run
|
29
|
+
|
30
|
+
get "/" do
|
31
|
+
present :index,
|
32
|
+
:jobs => scheduler.jobs( :order => :created_at.desc ),
|
33
|
+
# we need to get our context via "addons.running['scheduler']"
|
34
|
+
# which is, essentially, this class.
|
35
|
+
:root => current_addon.path_root
|
36
|
+
end
|
37
|
+
|
38
|
+
post '/' do
|
39
|
+
valid = true
|
40
|
+
|
41
|
+
begin
|
42
|
+
URI.parse( params['url'] )
|
43
|
+
rescue
|
44
|
+
valid = false
|
45
|
+
end
|
46
|
+
|
47
|
+
if !params['url'] || params['url'].empty? || !valid
|
48
|
+
flash[:err] = "Invalid URL."
|
49
|
+
elsif !params['dispatcher'] || params['dispatcher'].empty?
|
50
|
+
flash[:err] = "Please select a Dispatcher."
|
51
|
+
else
|
52
|
+
|
53
|
+
session['opts']['settings']['url'] = params[:url]
|
54
|
+
|
55
|
+
unescape_hash( session['opts'] )
|
56
|
+
session['opts']['settings']['audit_links'] = true if session['opts']['settings']['audit_links']
|
57
|
+
session['opts']['settings']['audit_forms'] = true if session['opts']['settings']['audit_forms']
|
58
|
+
session['opts']['settings']['audit_cookies'] = true if session['opts']['settings']['audit_cookies']
|
59
|
+
session['opts']['settings']['audit_headers'] = true if session['opts']['settings']['audit_headers']
|
60
|
+
|
61
|
+
opts = {}
|
62
|
+
opts['settings'] = prep_opts( session['opts']['settings'] )
|
63
|
+
opts['plugins'] = YAML::load( session['opts']['plugins'] )
|
64
|
+
opts['modules'] = session['opts']['modules']
|
65
|
+
|
66
|
+
if params[:datetime] && !params[:datetime].empty?
|
67
|
+
|
68
|
+
job = Arachni::UI::Web::Scheduler::Job.new(
|
69
|
+
:dispatcher => params[:dispatcher],
|
70
|
+
:url => params[:url],
|
71
|
+
:opts => opts.to_yaml,
|
72
|
+
:owner_addr => env['REMOTE_ADDR'],
|
73
|
+
:owner_host => env['REMOTE_HOST'],
|
74
|
+
:created_at => Time.now
|
75
|
+
)
|
76
|
+
|
77
|
+
begin
|
78
|
+
job.datetime = parse_datetime( params[:datetime] )
|
79
|
+
|
80
|
+
if !job.valid?
|
81
|
+
flash[:err] = 'Job holds invalid data, skipping...'
|
82
|
+
else
|
83
|
+
job.save
|
84
|
+
flash[:ok] = "Job saved."
|
85
|
+
end
|
86
|
+
rescue Exception => e
|
87
|
+
flash[:err] = 'Could not parse date (' + e.to_s + ').'
|
88
|
+
end
|
89
|
+
|
90
|
+
else
|
91
|
+
flash[:err] = 'Date cannot be empty.'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
present :index,
|
96
|
+
:jobs => scheduler.jobs( :order => :created_at.desc ),
|
97
|
+
# we need to get our context via "addons.running['scheduler']"
|
98
|
+
# which is, essentially, this class.
|
99
|
+
:root => current_addon.path_root
|
100
|
+
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
post '/delete' do
|
105
|
+
scheduler.delete_all
|
106
|
+
log.scheduler_jobs_deleted( env )
|
107
|
+
|
108
|
+
redirect addons.running['scheduler'].path_root + '/'
|
109
|
+
end
|
110
|
+
|
111
|
+
post '/:id/delete' do
|
112
|
+
scheduler.delete( params[:id] )
|
113
|
+
log.scheduler_job_deleted( env, params[:id] )
|
114
|
+
|
115
|
+
redirect addons.running['scheduler'].path_root + '/'
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
def title
|
121
|
+
"Scheduler [#{settings.scheduler.jobs.size}]"
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.info
|
125
|
+
{
|
126
|
+
:name => 'Scheduler',
|
127
|
+
:description => %q{Schedules and runs scan jobs.},
|
128
|
+
:author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com> ',
|
129
|
+
:version => '0.1'
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
|
2
|
+
<% if !jobs.empty? %>
|
3
|
+
<form action="<%=root%>/delete" method="post">
|
4
|
+
<%= csrf_tag %>
|
5
|
+
<input type="submit" value="Delete all" />
|
6
|
+
</form>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<div>
|
10
|
+
|
11
|
+
<form action="<%=root%>/" method="post">
|
12
|
+
<h2>Schedule a scan</h2>
|
13
|
+
|
14
|
+
<i>You can configure the scan parameters just like you normally would.</i>
|
15
|
+
<br/>
|
16
|
+
|
17
|
+
Select a Dispatcher:
|
18
|
+
<select name="dispatcher">
|
19
|
+
<% if !dispatchers.first_alive%>
|
20
|
+
<option value="">None available, please add a Dispatcher to continue.</option>
|
21
|
+
<%else%>
|
22
|
+
<% dispatcher_stats.each_pair do |d_url, stats| %>
|
23
|
+
<% next if !dispatchers.alive?( d_url ) %>
|
24
|
+
<option value="<%=d_url%>">
|
25
|
+
@<%=escape( d_url )%> - <%=stats['running_jobs'].size%> running scans,
|
26
|
+
<%=i=0;stats['running_jobs'].each{ |job| i+= proc_mem( job['proc']['rss'] ).to_i }; i.to_s%>MB RAM usage.
|
27
|
+
</option>
|
28
|
+
<%end%>
|
29
|
+
<%end%>
|
30
|
+
</select>
|
31
|
+
|
32
|
+
URL: <input name="url" value="<%=session['opts']['settings']['url']%>" size="50" <% if !dispatchers.first_alive%> disabled="disabled"<%end%> />
|
33
|
+
Schedule for: <input id="datetime" name="datetime" <% if !dispatchers.first_alive%> disabled="disabled"<%end%> />
|
34
|
+
|
35
|
+
<%= csrf_tag %>
|
36
|
+
<input type="submit" value="Add" <% if !dispatchers.first_alive%> disabled="disabled"<%end%> />
|
37
|
+
|
38
|
+
</form>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
|
42
|
+
<% if !jobs.empty? %>
|
43
|
+
<table>
|
44
|
+
<tr>
|
45
|
+
<th>ID</th>
|
46
|
+
<th>Dispatcher</th>
|
47
|
+
<th>Target</th>
|
48
|
+
<th>Starts at</th>
|
49
|
+
<th>Created by</th>
|
50
|
+
<th>Created at</th>
|
51
|
+
</tr>
|
52
|
+
<% jobs.each do |job| %>
|
53
|
+
<tr>
|
54
|
+
|
55
|
+
|
56
|
+
<td><%=job.id%></td>
|
57
|
+
<td><%=job.dispatcher%></td>
|
58
|
+
<td><%=job.url%></td>
|
59
|
+
<td><%=job.datetime%></td>
|
60
|
+
<td><%=job.owner_host%> (<%=job.owner_addr%>)</td>
|
61
|
+
<td><%=job.created_at%></td>
|
62
|
+
<td>
|
63
|
+
<form action="<%=root%>/<%=job.id%>/delete" method="post">
|
64
|
+
<%= csrf_tag %>
|
65
|
+
<input type="submit" value="Delete" />
|
66
|
+
</form>
|
67
|
+
|
68
|
+
<form action="#" onsubmit="showDialog( '#dialog_options_<%=job.id%>' ); return;" >
|
69
|
+
<input type="submit" value="Options" />
|
70
|
+
</form>
|
71
|
+
|
72
|
+
<form action="#" onsubmit="showDialog( '#dialog_modules_<%=job.id%>' ); return;" >
|
73
|
+
<input type="submit" value="Modules" />
|
74
|
+
</form>
|
75
|
+
|
76
|
+
<form action="#" onsubmit="showDialog( '#dialog_plugins_<%=job.id%>' ); return;" >
|
77
|
+
<input type="submit" value="Plugins" />
|
78
|
+
</form>
|
79
|
+
|
80
|
+
</td>
|
81
|
+
</tr>
|
82
|
+
<tr>
|
83
|
+
|
84
|
+
<% stored_opts = YAML::load( job.opts ); opts = stored_opts['settings'] %>
|
85
|
+
|
86
|
+
<%=partial :options, :job => job, :opts => opts %>
|
87
|
+
|
88
|
+
<div style="display: none" id="dialog_modules_<%=job.id%>" title="Modules">
|
89
|
+
<p>
|
90
|
+
<ul>
|
91
|
+
<% stored_opts['modules'].each do |name| %>
|
92
|
+
<li><%=name%></li>
|
93
|
+
<%end%>
|
94
|
+
</ul>
|
95
|
+
</p>
|
96
|
+
|
97
|
+
</div>
|
98
|
+
|
99
|
+
<div style="display: none" id="dialog_plugins_<%=job.id%>" title="Plugins">
|
100
|
+
<p>
|
101
|
+
<ul>
|
102
|
+
<% stored_opts['plugins'].each do |plugin| %>
|
103
|
+
<li><%=plugin[0]%></li>
|
104
|
+
<%end%>
|
105
|
+
</ul>
|
106
|
+
</p>
|
107
|
+
|
108
|
+
</div>
|
109
|
+
|
110
|
+
|
111
|
+
</tr>
|
112
|
+
<% end %>
|
113
|
+
</table>
|
114
|
+
<% else %>
|
115
|
+
<p class="notice"> There are no scheduled scans at the moment.</p>
|
116
|
+
<% end %>
|
117
|
+
|
118
|
+
<script type="text/javascript">
|
119
|
+
//<![CDATA[
|
120
|
+
|
121
|
+
$('#datetime').datetimepicker();
|
122
|
+
|
123
|
+
function showDialog( id ){
|
124
|
+
$( id ).dialog({
|
125
|
+
height: 500,
|
126
|
+
width: 1000,
|
127
|
+
modal: true
|
128
|
+
});
|
129
|
+
}
|
130
|
+
//]]>
|
131
|
+
</script>
|