1 |
<?xml version="1.0" ?>
|
2 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3 |
<html xmlns="http://www.w3.org/1999/xhtml">
|
4 |
<head>
|
5 |
<title>SecurityModule.pm - Web Security Module</title>
|
6 |
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
7 |
<link rev="made" href="mailto:Gentoo@dflt1.psi.ch" />
|
8 |
</head>
|
9 |
|
10 |
<body style="background-color: white">
|
11 |
|
12 |
<p><a name="__index__"></a></p>
|
13 |
<!-- INDEX BEGIN -->
|
14 |
|
15 |
<ul>
|
16 |
|
17 |
<li><a href="#name">NAME</a></li>
|
18 |
<li><a href="#synopsis">SYNOPSIS</a></li>
|
19 |
<li><a href="#description">DESCRIPTION</a></li>
|
20 |
<ul>
|
21 |
|
22 |
<li><a href="#initialization">Initialization</a></li>
|
23 |
<li><a href="#calling_the_password_form_via_a_web_page__login__link_">Calling the password form via a web page 'Login' link:</a></li>
|
24 |
</ul>
|
25 |
|
26 |
<li><a href="#author">AUTHOR</a></li>
|
27 |
<li><a href="#issues___todo">ISSUES / TODO</a></li>
|
28 |
</ul>
|
29 |
<!-- INDEX END -->
|
30 |
|
31 |
<hr />
|
32 |
<p>
|
33 |
</p>
|
34 |
<hr />
|
35 |
<h1><a name="name">NAME</a></h1>
|
36 |
<p>SecurityModule.pm - Web Security Module</p>
|
37 |
<p>
|
38 |
</p>
|
39 |
<hr />
|
40 |
<h1><a name="synopsis">SYNOPSIS</a></h1>
|
41 |
<p>Note: This applies specifically to the MySQL implementation. There is also
|
42 |
a SecurityModule::SQLite implementation.</p>
|
43 |
<pre>
|
44 |
use SecurityModule::MySQL;
|
45 |
$sec = new SecurityModule::MySQL({CALLER_URL => $myurl,
|
46 |
CONFIG => "/etc/sec/SecMod.conf";
|
47 |
LOGLEVEL => 5,
|
48 |
KEYVALIDTIME => 7200,
|
49 |
PWDFORM_HANDLER => \&myPasswordForm
|
50 |
});</pre>
|
51 |
<pre>
|
52 |
$ret = $sec->init(); # returns 0 in case of failure</pre>
|
53 |
<pre>
|
54 |
$errmsg = $sec->getErrMsg(); # returns error message</pre>
|
55 |
<pre>
|
56 |
# if getCookie() returns a defined value, your page needs to make
|
57 |
# sure that this cookie will be set using CGI.pm's
|
58 |
# header(-cookie => $cookie ) command
|
59 |
if( ($cookie=$sec->getCookie) ) {
|
60 |
print header(-cookie => $cookie );
|
61 |
} else {
|
62 |
print header();
|
63 |
}</pre>
|
64 |
<pre>
|
65 |
# Access to authentication / authorization information
|
66 |
$state = $sec->getAuthnState(); # returns (failed | cert | passwd)
|
67 |
$user_dn = $sec->getDN(); # returns user's distinguished name
|
68 |
$roles = $sec->getRoles(); # returns a hash of roles, each role mapping to a
|
69 |
# list of scopes</pre>
|
70 |
<pre>
|
71 |
# Protecting functions: reqAuthnCert() and reqAuthnPasswd()
|
72 |
sub my_certificate_protected_function {
|
73 |
$sec->reqAuthnCert();
|
74 |
...
|
75 |
}
|
76 |
sub my_password_protected_function {
|
77 |
$sec->reqAuthnPasswd();
|
78 |
...
|
79 |
}</pre>
|
80 |
<p>
|
81 |
</p>
|
82 |
<hr />
|
83 |
<h1><a name="description">DESCRIPTION</a></h1>
|
84 |
<p>The SecurityModule handles authentication and authorization to a web site. Users
|
85 |
are identified by a certificate loaded in their browser or by a previously
|
86 |
set cookie that was issued upon a successful password authentication.</p>
|
87 |
<p>Certificate based authentication is the strongest authentication type,
|
88 |
so functions protected by the <code>reqAuthnPasswd()</code> method will allow
|
89 |
access to certificate authenticated users, but <code>reqAuthnCert()</code> will deny
|
90 |
access to password authenticated users.</p>
|
91 |
<p>The SecurityModule was written for a setup where a <strong>remote Proxy</strong> mediates access
|
92 |
to a number of backend servers. The remote proxy handles
|
93 |
the SSL authentication and is required to set the following request headers to
|
94 |
the values of the respective environment variables for this request:</p>
|
95 |
<p><strong>SSL_CLIENT_VERIFY</strong>,
|
96 |
<strong>SSL_CLIENT_S_DN</strong>,
|
97 |
<strong>HTTPS</strong>.</p>
|
98 |
<p>On the backend servers these must be available as environment variables of identical names
|
99 |
except for the prefix <strong>HTTP_</strong>, e.g. <strong>HTTP_SSL_CLIENT_S_DN</strong>.</p>
|
100 |
<p>Since all backend servers are hidden behind the reverse proxy, an authentication
|
101 |
cookie is set restrictively to only be sent back to the issueing server. The
|
102 |
necessary translation for the proxy is handled transparently by apache's mod_proxy
|
103 |
module (needs >= apache-2.2).</p>
|
104 |
<p>The SecurityModule can also be run without a reverse proxy in pure SSL mode (by
|
105 |
setting the REVPROXY_MODE option to 0), mainly for testing.</p>
|
106 |
<p>
|
107 |
</p>
|
108 |
<h2><a name="initialization">Initialization</a></h2>
|
109 |
<p>Arguments which can be passed to the constructor:</p>
|
110 |
<ul>
|
111 |
<li>
|
112 |
<p><strong>CALLER_URL</strong>: (Required) URL of the current page that was invoked by
|
113 |
the browser, i.e. it must contain the URL which the reverse proxy got
|
114 |
before redirecting to the backend server.</p>
|
115 |
</li>
|
116 |
<li>
|
117 |
<p><strong>REVPROXY_MODE</strong>: 1 for reverse proxy mode, 0 for basic SSL mode. Default is 1.</p>
|
118 |
</li>
|
119 |
<li>
|
120 |
<p><strong>CONFIG</strong>: Filename of a configuration file. The file must contain ``option = value''
|
121 |
lines as in this example:</p>
|
122 |
<pre>
|
123 |
LOGFILE = /tmp/SecMod.log
|
124 |
LOGLEVEL = 5
|
125 |
KEYVALIDTIME = 1500
|
126 |
# Comments and empty lines are allowed
|
127 |
DBHOST = localhost
|
128 |
DBPORT = 3306
|
129 |
DBNAME = secmod
|
130 |
DBUSER = smwriter
|
131 |
DBPASS = mypasswd
|
132 |
REQCERT_FAIL_HANDLER = https://localhost/bclear/testSecMod/nopermission
|
133 |
PWDFORM_HANDLER = https://localhost/bclear/testSecMod/passform</pre>
|
134 |
<p><strong>Note</strong>: The configuration options specified in the constructor will override
|
135 |
any options specified in the configuration file.</p>
|
136 |
</li>
|
137 |
<li>
|
138 |
<p><strong>KEYVALIDTIME</strong>: Validity time in seconds of generated keys</p>
|
139 |
</li>
|
140 |
<li>
|
141 |
<p><strong>PWDFORM_HANDLER</strong>: URL or reference to a function generating a
|
142 |
password page. If a function reference is given, two values will be
|
143 |
passed into the function: The URL of the present page (so we can get
|
144 |
back) and a status message describing why the password form was
|
145 |
called. If an URL is given, the two values will be passed using a
|
146 |
query string (?caller_url=...&msg=...) in the redirection.</p>
|
147 |
<pre>
|
148 |
Status messages: password authentication required
|
149 |
reauthentication
|
150 |
invalid cookie</pre>
|
151 |
</li>
|
152 |
<li>
|
153 |
<p><strong>REQCERT_FAIL_HANDLER</strong>: URL or reference to a function to call when a page secured by
|
154 |
<code>reqAuthnCert()</code> is encountered and the client is not certificate authenticated.
|
155 |
Typically, to display some diagnostic message.</p>
|
156 |
</li>
|
157 |
<li>
|
158 |
<p><strong>LOGFILE</strong>: Filename of the logfile</p>
|
159 |
</li>
|
160 |
<li>
|
161 |
<p><strong>LOGLEVEL</strong>: Integer value from 0-5</p>
|
162 |
<pre>
|
163 |
0: no log messages at all
|
164 |
1: error and security relevant messages only
|
165 |
3: Logs password authentications (standard log level)
|
166 |
5: debugging messages</pre>
|
167 |
</li>
|
168 |
<li>
|
169 |
<p>For the MySQL implementation you can also supply the DB connection parameters
|
170 |
<strong>DBHOST, DBPORT, DBNAME, DBUSER, DBPASS</strong></p>
|
171 |
</li>
|
172 |
<li>
|
173 |
<p>For the SQLite implementation you only need to supply a <strong>DBFILE</strong> parameter
|
174 |
with the location of the data base file.</p>
|
175 |
</li>
|
176 |
</ul>
|
177 |
<p>
|
178 |
</p>
|
179 |
<h2><a name="calling_the_password_form_via_a_web_page__login__link_">Calling the password form via a web page 'Login' link:</a></h2>
|
180 |
<p>You can pass <strong>SecModPwd=1</strong> as a GET variable to any page using the
|
181 |
SecurityModule. This will call the handler for / redirect to the password form
|
182 |
and insure that the user can return to the same page.</p>
|
183 |
<p>
|
184 |
</p>
|
185 |
<hr />
|
186 |
<h1><a name="author">AUTHOR</a></h1>
|
187 |
<p>Derek Feichtinger <<a href="mailto:derek.feichtinger@psi.ch">derek.feichtinger@psi.ch</a>></p>
|
188 |
<p>CMS web interfaces group <<a href="mailto:hn-cms-webInterfaces@cern.ch">hn-cms-webInterfaces@cern.ch</a>></p>
|
189 |
<p>
|
190 |
</p>
|
191 |
<hr />
|
192 |
<h1><a name="issues___todo">ISSUES / TODO</a></h1>
|
193 |
<p>List of issues to resolve:</p>
|
194 |
<ul>
|
195 |
<li>
|
196 |
<p>POST arguments are not carried across the password form</p>
|
197 |
</li>
|
198 |
<li>
|
199 |
<p>The mapping from username to certificate distinguished name needs to be established
|
200 |
separately.</p>
|
201 |
</li>
|
202 |
<li>
|
203 |
<p>Look at ``TODO'' comments in the code.</p>
|
204 |
</li>
|
205 |
</ul>
|
206 |
|
207 |
</body>
|
208 |
|
209 |
</html>
|