log login attempts (login + sha1(pw))
[cacert-mgr.git] / manager / application / controllers / LoginController.php
1 <?php
2 /**
3 * @author markus
4 * $Id: LoginController.php 75 2010-02-25 14:40:10Z markus $
5 */
6
7 require_once('helpers/GetEnv.php');
8 require_once('config/Config.php');
9
10 class LoginController extends Zend_Controller_Action
11 {
12
13 public function init() {
14 /* Initialize action controller here */
15 $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV);
16
17 $db = Zend_Db::factory($config->ca_mgr->db->auth->pdo, $config->ca_mgr->db->auth);
18 Zend_Registry::set('auth_dbc', $db);
19 $db2 = Zend_Db::factory($config->ca_mgr->db->auth2->pdo, $config->ca_mgr->db->auth2);
20 Zend_Registry::set('auth2_dbc', $db2);
21 }
22
23 public function indexAction() {
24 $this->view->form = $this->getForm();
25 $this->render('index');
26 }
27
28 public function loginAction() {
29 $form = $this->getForm();
30 if ($form->isValid($_POST)) {
31 $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV);
32
33 $db = Zend_Registry::get('auth_dbc');
34 $db2 = Zend_Registry::get('auth2_dbc');
35
36 $auth = new Zend_Auth_Adapter_DbTable($db);
37
38 $auth->setTableName($config->ca_mgr->db->auth->tablename)
39 ->setIdentityColumn('email')
40 ->setCredentialColumn('password');
41
42 Log::Log()->info(__METHOD__ . ' authenticate ' . $this->getRequest()->getParam('login_name') . ' ' . sha1(utf8_decode($this->getRequest()->getParam('login_password'))));
43
44 $auth->setIdentity( $this->getRequest()->getParam('login_name'))
45 ->setCredential( sha1(utf8_decode($this->getRequest()->getParam('login_password'))))
46 ->setCredentialTreatment('?');
47
48 $result = $auth->authenticate();
49
50 $code = $result->getCode();
51 switch ($code) {
52 case Zend_Auth_Result::FAILURE:
53 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE) to log in ' . $this->getRequest()->getParam('login_name'));
54 throw new Exception(__METHOD__ . ': unknown error');
55 case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
56 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND) to log in ' . $this->getRequest()->getParam('login_name'));
57 throw new Exception(__METHOD__ . ': ID unknown');
58 case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
59 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS) to log in ' . $this->getRequest()->getParam('login_name'));
60 throw new Exception(__METHOD__ . ': ID not unique');
61 case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
62 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID) to log in ' . $this->getRequest()->getParam('login_name'));
63 throw new Exception(__METHOD__ . ': ID unknown'); // to prevent brute force password attachs
64 case Zend_Auth_Result::FAILURE_UNCATEGORIZED:
65 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_UNCATEGORIZED) to log in ' . $this->getRequest()->getParam('login_name'));
66 throw new Exception(__METHOD__ . ': unknown error');
67 }
68
69 $this->getAuthDetailsIntoSession($auth, false);
70
71 Log::Log()->info(__METHOD__ . ' user logged in ' . $this->view->session->authdata['authed_username'] .
72 ' (' . $this->getRequest()->getParam('login_name') . ')');
73
74 #$this->_forward('index', 'index'); // only "soft" forward, we need to change the url in browser
75 $this->_redirect($this->view->url(array('controller' => 'index', 'action' => 'index'), 'default', true));
76
77 /*
78 $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
79 $viewRenderer->setRender('loginresult');
80 $this->view->request = $this->getRequest();
81 */
82 }
83 else {
84 $this->view->form = $form;
85 return $this->render('index');
86 }
87 }
88
89 public function crtAction() {
90 $ssl_client_s_dn = GetEnv::getEnvVar('SSL_CLIENT_S_DN');
91 $ssl_client_i_dn = GetEnv::getEnvVar('SSL_CLIENT_I_DN');
92
93 $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV);
94
95 $db = Zend_Registry::get('auth_dbc');
96 $db2 = Zend_Registry::get('auth2_dbc');
97
98 $auth = new Zend_Auth_Adapter_DbTable($db2);
99
100 $auth->setTableName($config->ca_mgr->db->auth2->tablename)
101 ->setIdentityColumn('user_client_crt_s_dn_i_dn')
102 ->setCredentialColumn('user_client_crt_s_dn_i_dn');
103
104 $auth->setIdentity( $ssl_client_s_dn . '//' . $ssl_client_i_dn)
105 ->setCredential($ssl_client_s_dn . '//' . $ssl_client_i_dn)
106 ->setCredentialTreatment('?');
107
108 $result = $auth->authenticate();
109
110 $code = $result->getCode();
111 switch ($code) {
112 case Zend_Auth_Result::FAILURE:
113 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
114 throw new Exception(__METHOD__ . ': unknown error');
115 case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
116 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
117 throw new Exception(__METHOD__ . ': ID unknown');
118 case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
119 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
120 throw new Exception(__METHOD__ . ': ID not unique');
121 case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
122 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
123 throw new Exception(__METHOD__ . ': ID unknown'); // to prevent brute force password attachs
124 case Zend_Auth_Result::FAILURE_UNCATEGORIZED:
125 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_UNCATEGORIZED) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
126 throw new Exception(__METHOD__ . ': unknown error');
127 }
128
129 $this->getAuthDetailsIntoSession($auth, true);
130
131 /*
132 $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
133 $viewRenderer->setRender('loginresult');
134 */
135
136 Log::Log()->info(__METHOD__ . ' user logged in ' . $this->view->session->authdata['authed_username'] .
137 ' (' . $ssl_client_s_dn . '//' . $ssl_client_i_dn . ')');
138
139 #$this->_forward('index', 'index'); // only "soft" forward, we need to change the url in browser
140 $this->_redirect($this->view->url(array('controller' => 'index', 'action' => 'index'), 'default', true));
141 }
142
143 /**
144 * get user data from Zend_Auth result and store data in session
145 * @param Zend_Auth_Result $auth
146 */
147 protected function getAuthDetailsIntoSession($auth, $crt) {
148 $session = Zend_Registry::get('session');
149
150 $db = Zend_Registry::get('auth_dbc');
151 $db2 = Zend_Registry::get('auth2_dbc');
152
153 /**
154 * non existent in our case, look up a 2nd table (ca_mgr.system_user by login name (email)) and
155 * get id from there, defaulting to User (1) when no db entry exists
156 */
157 $auth_res = $auth->getResultRowObject();
158
159 if (!isset($auth_res->system_role_id) || $auth_res->system_role_id == 0) {
160 $res = $db2->query('select * from system_user where login=?', array($auth_res->email));
161 if ($res->rowCount() > 0) {
162 $res_ar = $res->fetch();
163 $system_roles_id = $res_ar['system_role_id'];
164 }
165 else {
166 // no extra user info in manager database, assume standard user
167 $system_roles_id = 1;
168 }
169 }
170 else
171 $system_roles_id = $auth_res->system_role_id;
172
173 $session->authdata['authed'] = true;
174 $session->authdata['authed_id'] = $auth_res->id;
175 if (!isset($auth_res->fname) || !isset($auth_res->lname)) {
176 $res = $db->query('select * from users where email=?', array($auth_res->login));
177 $res_ar = $res->fetch();
178 $session->authdata['authed_username'] = 'crt' . $res_ar['login'];
179 $session->authdata['authed_fname'] = $res_ar['fname'];
180 $session->authdata['authed_lname'] = $res_ar['lname'];
181 }
182 else {
183 $session->authdata['authed_username'] = $auth_res->email;
184 $session->authdata['authed_fname'] = $auth_res->fname;
185 $session->authdata['authed_lname'] = $auth_res->lname;
186 }
187 $session->authdata['authed_by_crt'] = $crt;
188 $session->authdata['authed_by_cli'] = true;
189
190 $res = $db2->query('select * from system_role where id=?', array($system_roles_id));
191 $res_ar = $res->fetch();
192 $session->authdata['authed_role'] = $res_ar['role'];
193
194 $acl = $this->makeAcl($db2);
195
196 $session->authdata['authed_permissions'] = $acl;
197
198 /* test cases
199 Log::Log()->debug(($acl->isAllowed('User', 'Administration', 'view') == true)?'true':'false');
200 Log::Log()->debug(($acl->isAllowed('User', 'Administration', 'edit') == true)?'true':'false');
201 Log::Log()->debug(($acl->isAllowed('User', 'Account', 'view') == true)?'true':'false');
202 Log::Log()->debug(($acl->isAllowed('User', 'Account', 'edit') == true)?'true':'false');
203 Log::Log()->debug(($acl->isAllowed('Admin', 'Administration', 'view') == true)?'true':'false');
204 Log::Log()->debug(($acl->isAllowed('Admin', 'Account', 'view') == true)?'true':'false');
205 */
206
207 $this->view->session = $session;
208 }
209
210 /**
211 * build login form and return to requesting method
212 * @return Zend_Form
213 */
214 protected function getForm() {
215 $form = new Zend_Form();
216 $form->setAction('/login/login')
217 ->setMethod('post');
218 #$form->setAttrib('id', 'loginform');
219 $username = new Zend_Form_Element_Text('login_name');
220 $username->setRequired(true)
221 ->setLabel(I18n::_('User Name'))
222 ->addFilter(new Zend_Filter_StringTrim())
223 ->addFilter(new Zend_Filter_StripTags());
224 $password = new Zend_Form_Element_Password('login_password');
225 $password->setRequired(true)
226 ->setLabel(I18n::_('Password'))
227 ->addFilter(new Zend_Filter_StringTrim());
228 $submit = new Zend_Form_Element_Submit('submit');
229 $submit->setLabel(I18n::_('Login'));
230 $form->addElement($username)
231 ->addElement($password)
232 ->addElement($submit);
233
234 return $form;
235 }
236
237 /**
238 * get roles and resources from db, build Zend_Acl structure and add permissions
239 * @param Zend_Db $db
240 */
241 protected function makeAcl($db) {
242 $acl = new Zend_Acl();
243
244 $res = $db->fetchAll('select * from system_role');
245 foreach ($res as $obj) {
246 if ($obj['inherit_role'] != '') {
247 if ($acl->hasRole($obj['inherit_role'])) {
248 $acl->addRole(new Zend_Acl_Role($obj['role']), $obj['inherit_role']);
249 }
250 else {
251 /**
252 * @todo very simply system to order roles, add role before inherited role
253 */
254 $res[] = $obj;
255 continue;
256 }
257 }
258 else {
259 $acl->addRole(new Zend_Acl_Role($obj['role']));
260 }
261 }
262
263 $res = $db->fetchAll('select * from system_resource');
264 foreach ($res as $obj) {
265 $acl->addResource(new Zend_Acl_Resource($obj['resource']));
266 }
267
268 $res = $db->fetchAll('select r.role as role, rs.resource as resource, permission, privilege '.
269 'from system_role as r join system_role_has_system_resource as m on ' .
270 '(r.id = m.system_role_id) join system_resource as rs on (m.system_resource_id = rs.id)');
271
272 foreach ($res as $obj) {
273 $privilege = explode(',', $obj['privilege']);
274 if ($obj['permission'] == 'allow') {
275 $acl->allow($obj['role'], $obj['resource'], $privilege);
276 }
277 else {
278 $acl->deny($obj['role'], $obj['resource'], $privilege);
279 }
280 }
281
282 return $acl;
283 }
284 }