ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
X509userCert.php
Go to the documentation of this file.
1 <?php
2 
10 {
11 
15  private $x509attributes = array('UID' => 'uid');
16 
17 
21  private $ldapusercert = array('userCertificate;binary');
22 
23 
27  private $ldapcf;
28 
29 
38  public function __construct($info, &$config)
39  {
40  assert(is_array($info));
41  assert(is_array($config));
42 
43  if (isset($config['authX509:x509attributes'])) {
44  $this->x509attributes = $config['authX509:x509attributes'];
45  }
46 
47  if (array_key_exists('authX509:ldapusercert', $config)) {
48  $this->ldapusercert = $config['authX509:ldapusercert'];
49  }
50 
51  parent::__construct($info, $config);
52 
53  $this->ldapcf = new sspmod_ldap_ConfigHelper(
54  $config,
55  'Authentication source ' . var_export($this->authId, true)
56  );
57 
58  return;
59  }
60 
61 
69  public function authFailed(&$state)
70  {
72 
73  $t = new SimpleSAML_XHTML_Template($config, 'authX509:X509error.php');
74  $t->data['errorcode'] = $state['authX509.error'];
76 
77  $t->show();
78  exit();
79  }
80 
81 
90  public function authenticate(&$state)
91  {
92  assert(is_array($state));
94 
95  if (!isset($_SERVER['SSL_CLIENT_CERT']) ||
96  ($_SERVER['SSL_CLIENT_CERT'] == '')) {
97  $state['authX509.error'] = "NOCERT";
98  $this->authFailed($state);
99 
100  assert(false); // should never be reached
101  return;
102  }
103 
104  $client_cert = $_SERVER['SSL_CLIENT_CERT'];
105  $client_cert_data = openssl_x509_parse($client_cert);
106  if ($client_cert_data === false) {
107  SimpleSAML\Logger::error('authX509: invalid cert');
108  $state['authX509.error'] = "INVALIDCERT";
109  $this->authFailed($state);
110 
111  assert(false); // should never be reached
112  return;
113  }
114 
115  $dn = null;
116  foreach ($this->x509attributes as $x509_attr => $ldap_attr) {
117  // value is scalar
118  if (array_key_exists($x509_attr, $client_cert_data['subject'])) {
119  $value = $client_cert_data['subject'][$x509_attr];
120  SimpleSAML\Logger::info('authX509: cert '. $x509_attr.' = '.$value);
121  $dn = $ldapcf->searchfordn($ldap_attr, $value, true);
122  if ($dn !== null) {
123  break;
124  }
125  }
126  }
127 
128  if ($dn === null) {
129  SimpleSAML\Logger::error('authX509: cert has no matching user in LDAP.');
130  $state['authX509.error'] = "UNKNOWNCERT";
131  $this->authFailed($state);
132 
133  assert(false); // should never be reached
134  return;
135  }
136 
137  if ($this->ldapusercert === null) { // do not check for certificate match
138  $attributes = $ldapcf->getAttributes($dn);
139  assert(is_array($attributes));
140  $state['Attributes'] = $attributes;
141  $this->authSuccesful($state);
142 
143  assert(false); // should never be reached
144  return;
145  }
146 
147  $ldap_certs = $ldapcf->getAttributes($dn, $this->ldapusercert);
148  if ($ldap_certs === false) {
149  SimpleSAML\Logger::error('authX509: no certificate found in LDAP for dn='.$dn);
150  $state['authX509.error'] = "UNKNOWNCERT";
151  $this->authFailed($state);
152 
153  assert(false); // should never be reached
154  return;
155  }
156 
157 
158  $merged_ldapcerts = array();
159  foreach ($this->ldapusercert as $attr) {
160  $merged_ldapcerts = array_merge($merged_ldapcerts, $ldap_certs[$attr]);
161  }
162  $ldap_certs = $merged_ldapcerts;
163 
164  foreach ($ldap_certs as $ldap_cert) {
165  $pem = \SimpleSAML\Utils\Crypto::der2pem($ldap_cert);
166  $ldap_cert_data = openssl_x509_parse($pem);
167  if ($ldap_cert_data === false) {
168  SimpleSAML\Logger::error('authX509: cert in LDAP is invalid for dn='.$dn);
169  continue;
170  }
171 
172  if ($ldap_cert_data === $client_cert_data) {
173  $attributes = $ldapcf->getAttributes($dn);
174  assert(is_array($attributes));
175  $state['Attributes'] = $attributes;
176  $this->authSuccesful($state);
177 
178  assert(false); // should never be reached
179  return;
180  }
181  }
182 
183  SimpleSAML\Logger::error('authX509: no matching cert in LDAP for dn='.$dn);
184  $state['authX509.error'] = "UNKNOWNCERT";
185  $this->authFailed($state);
186 
187  assert(false); // should never be reached
188  return;
189  }
190 
191 
199  public function authSuccesful(&$state)
200  {
202 
203  assert(false); // should never be reached
204  return;
205  }
206 }
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
$config
Definition: bootstrap.php:15
static der2pem($der, $type='CERTIFICATE')
Convert data from DER to PEM encoding.
Definition: Crypto.php:160
authenticate(&$state)
Validate certificate and login.
static getAllErrorCodeMessages()
Get a map of both errorcode titles and descriptions.
Definition: ErrorCodes.php:135
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
static info($string)
Definition: Logger.php:199
__construct($info, &$config)
Constructor for this authentication source.
$ldapusercert
LDAP attribute containing the user certificate.
static error($string)
Definition: Logger.php:166
authFailed(&$state)
Finish a failed authentication.
if(array_key_exists('yes', $_REQUEST)) $attributes
Definition: getconsent.php:85
$x509attributes
x509 attributes to use from the certificate for searching the user in the LDAP directory.
exit
Definition: backend.php:16
static completeAuth(&$state)
Complete authentication.
Definition: Source.php:136
$info
Definition: index.php:5
authSuccesful(&$state)
Finish a successful authentication.
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.