ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
Auth_OpenID_FileStore Class Reference
+ Inheritance diagram for Auth_OpenID_FileStore:
+ Collaboration diagram for Auth_OpenID_FileStore:

Public Member Functions

 Auth_OpenID_FileStore ($directory)
 Initializes a new Auth_OpenID_FileStore. More...
 
 destroy ()
 
 _setup ()
 Make sure that the directories in which we store our data exist. More...
 
 _mktemp ()
 Create a temporary file on the same filesystem as $this->association_dir. More...
 
 cleanupNonces ()
 
 getAssociationFilename ($server_url, $handle)
 Create a unique filename for a given server url and handle. More...
 
 storeAssociation ($server_url, $association)
 Store an association in the association directory. More...
 
 getAssociation ($server_url, $handle=null)
 Retrieve an association. More...
 
 _getAssociation ($filename)
 @access private More...
 
 removeAssociation ($server_url, $handle)
 Remove an association if it exists. More...
 
 useNonce ($server_url, $timestamp, $salt)
 Return whether this nonce is present. More...
 
 _allAssocs ()
 Remove expired entries from the database. More...
 
 clean ()
 
 _rmtree ($dir)
 @access private More...
 
 _mkstemp ($dir)
 @access private More...
 
 _listdir ($dir)
 @access private More...
 
 _isFilenameSafe ($char)
 @access private More...
 
 _safe64 ($str)
 @access private More...
 
 _filenameEscape ($str)
 @access private More...
 
 _removeIfPresent ($filename)
 Attempt to remove a file, returning whether the file existed at the time of the call. More...
 
 cleanupAssociations ()
 
- Public Member Functions inherited from Auth_OpenID_OpenIDStore
 storeAssociation ($server_url, $association)
 This method puts an Association object into storage, retrievable by server URL and handle. More...
 
 cleanupNonces ()
 
 cleanupAssociations ()
 
 cleanup ()
 
 supportsCleanup ()
 Report whether this storage supports cleanup. More...
 
 getAssociation ($server_url, $handle=null)
 This method returns an Association object from storage that matches the server URL and, if specified, handle. More...
 
 removeAssociation ($server_url, $handle)
 This method removes the matching association if it's found, and returns whether the association was removed or not. More...
 
 useNonce ($server_url, $timestamp, $salt)
 Called when using a nonce. More...
 
 reset ()
 Removes all entries from the store; implementation is optional. More...
 

Static Public Member Functions

static _mkdtemp ($dir)
 @access private More...
 

Detailed Description

Definition at line 39 of file FileStore.php.

Member Function Documentation

◆ _allAssocs()

Auth_OpenID_FileStore::_allAssocs ( )

Remove expired entries from the database.

This is potentially expensive, so only run when it is acceptable to take time.

@access private

Definition at line 405 of file FileStore.php.

406 {
407 $all_associations = array();
408
409 $association_filenames =
410 Auth_OpenID_FileStore::_listdir($this->association_dir);
411
412 foreach ($association_filenames as $association_filename) {
413 $association_file = fopen($association_filename, 'rb');
414
415 if ($association_file !== false) {
416 $assoc_s = fread($association_file,
417 filesize($association_filename));
418 fclose($association_file);
419
420 // Remove expired or corrupted associations
421 $association =
423 'Auth_OpenID_Association', $assoc_s);
424
425 if ($association === null) {
427 $association_filename);
428 } else {
429 if ($association->getExpiresIn() == 0) {
430 $all_associations[] = array($association_filename,
431 $association);
432 }
433 }
434 }
435 }
436
437 return $all_associations;
438 }
static deserialize($class_name, $assoc_s)
Parse an association as stored by serialize().
_listdir($dir)
@access private
Definition: FileStore.php:539
_removeIfPresent($filename)
Attempt to remove a file, returning whether the file existed at the time of the call.
Definition: FileStore.php:599

References _listdir(), _removeIfPresent(), and Auth_OpenID_Association\deserialize().

Referenced by clean(), and cleanupAssociations().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _filenameEscape()

Auth_OpenID_FileStore::_filenameEscape (   $str)

@access private

Definition at line 576 of file FileStore.php.

577 {
578 $filename = "";
579 $b = Auth_OpenID::toBytes($str);
580
581 for ($i = 0; $i < count($b); $i++) {
582 $c = $b[$i];
584 $filename .= $c;
585 } else {
586 $filename .= sprintf("_%02X", ord($c));
587 }
588 }
589 return $filename;
590 }
$filename
Definition: buildRTE.php:89
_isFilenameSafe($char)
@access private
Definition: FileStore.php:554
static toBytes($str)
Get the bytes in a string independently of multibyte support conditions.
Definition: OpenID.php:471

References $filename, _isFilenameSafe(), and Auth_OpenID\toBytes().

Referenced by getAssociationFilename(), and useNonce().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _getAssociation()

Auth_OpenID_FileStore::_getAssociation (   $filename)

@access private

Definition at line 296 of file FileStore.php.

297 {
298 if (!$this->active) {
299 trigger_error("FileStore no longer active", E_USER_ERROR);
300 return null;
301 }
302
303 $assoc_file = @fopen($filename, 'rb');
304
305 if ($assoc_file === false) {
306 return null;
307 }
308
309 $assoc_s = fread($assoc_file, filesize($filename));
310 fclose($assoc_file);
311
312 if (!$assoc_s) {
313 return null;
314 }
315
316 $association =
317 Auth_OpenID_Association::deserialize('Auth_OpenID_Association',
318 $assoc_s);
319
320 if (!$association) {
322 return null;
323 }
324
325 if ($association->getExpiresIn() == 0) {
327 return null;
328 } else {
329 return $association;
330 }
331 }

References $filename, _removeIfPresent(), and Auth_OpenID_Association\deserialize().

Referenced by getAssociation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _isFilenameSafe()

Auth_OpenID_FileStore::_isFilenameSafe (   $char)

@access private

Definition at line 554 of file FileStore.php.

555 {
556 $_Auth_OpenID_filename_allowed = Auth_OpenID_letters .
557 Auth_OpenID_digits . ".";
558 return (strpos($_Auth_OpenID_filename_allowed, $char) !== false);
559 }
const Auth_OpenID_letters
Defines for regexes and format checking.
Definition: OpenID.php:96
const Auth_OpenID_digits
Definition: OpenID.php:98

References Auth_OpenID_digits, and Auth_OpenID_letters.

Referenced by _filenameEscape().

+ Here is the caller graph for this function:

◆ _listdir()

Auth_OpenID_FileStore::_listdir (   $dir)

@access private

Definition at line 539 of file FileStore.php.

540 {
541 $handle = opendir($dir);
542 $files = array();
543 while (false !== ($filename = readdir($handle))) {
544 if (!in_array($filename, array('.', '..'))) {
545 $files[] = $dir . DIRECTORY_SEPARATOR . $filename;
546 }
547 }
548 return $files;
549 }

References $filename.

Referenced by _allAssocs(), clean(), cleanupNonces(), and getAssociation().

+ Here is the caller graph for this function:

◆ _mkdtemp()

static Auth_OpenID_FileStore::_mkdtemp (   $dir)
static

@access private

Definition at line 522 of file FileStore.php.

523 {
524 foreach (range(0, 4) as $i) {
525 $name = $dir . strval(DIRECTORY_SEPARATOR) . strval(getmypid()) .
526 "-" . strval(rand(1, time()));
527 if (!mkdir($name, 0700)) {
528 return false;
529 } else {
530 return $name;
531 }
532 }
533 return false;
534 }

◆ _mkstemp()

Auth_OpenID_FileStore::_mkstemp (   $dir)

@access private

Definition at line 507 of file FileStore.php.

508 {
509 foreach (range(0, 4) as $i) {
510 $name = tempnam($dir, "php_openid_filestore_");
511
512 if ($name !== false) {
513 return $name;
514 }
515 }
516 return false;
517 }

Referenced by _mktemp().

+ Here is the caller graph for this function:

◆ _mktemp()

Auth_OpenID_FileStore::_mktemp ( )

Create a temporary file on the same filesystem as $this->association_dir.

The temporary directory should not be cleaned if there are any processes using the store. If there is no active process using the store, it is safe to remove all of the files in the temporary directory.

Returns
array ($fd, $filename) @access private

Definition at line 108 of file FileStore.php.

109 {
110 $name = Auth_OpenID_FileStore::_mkstemp($dir = $this->temp_dir);
111 $file_obj = @fopen($name, 'wb');
112 if ($file_obj !== false) {
113 return array($file_obj, $name);
114 } else {
116 }
117 }
_mkstemp($dir)
@access private
Definition: FileStore.php:507

References _mkstemp(), and _removeIfPresent().

Referenced by storeAssociation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _removeIfPresent()

Auth_OpenID_FileStore::_removeIfPresent (   $filename)

Attempt to remove a file, returning whether the file existed at the time of the call.

@access private

Returns
bool $result True if the file was present, false if not.

Definition at line 599 of file FileStore.php.

600 {
601 return @unlink($filename);
602 }

References $filename.

Referenced by _allAssocs(), _getAssociation(), _mktemp(), clean(), cleanupAssociations(), cleanupNonces(), removeAssociation(), and storeAssociation().

+ Here is the caller graph for this function:

◆ _rmtree()

Auth_OpenID_FileStore::_rmtree (   $dir)

@access private

Definition at line 469 of file FileStore.php.

470 {
471 if ($dir[strlen($dir) - 1] != DIRECTORY_SEPARATOR) {
472 $dir .= DIRECTORY_SEPARATOR;
473 }
474
475 if ($handle = opendir($dir)) {
476 while ($item = readdir($handle)) {
477 if (!in_array($item, array('.', '..'))) {
478 if (is_dir($dir . $item)) {
479
480 if (!Auth_OpenID_FileStore::_rmtree($dir . $item)) {
481 return false;
482 }
483 } else if (is_file($dir . $item)) {
484 if (!unlink($dir . $item)) {
485 return false;
486 }
487 }
488 }
489 }
490
491 closedir($handle);
492
493 if (!@rmdir($dir)) {
494 return false;
495 }
496
497 return true;
498 } else {
499 // Couldn't open directory.
500 return false;
501 }
502 }
_rmtree($dir)
@access private
Definition: FileStore.php:469

References _rmtree().

Referenced by _rmtree(), and destroy().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _safe64()

Auth_OpenID_FileStore::_safe64 (   $str)

@access private

Definition at line 564 of file FileStore.php.

565 {
566 $h64 = base64_encode(Auth_OpenID_SHA1($str));
567 $h64 = str_replace('+', '_', $h64);
568 $h64 = str_replace('/', '.', $h64);
569 $h64 = str_replace('=', '', $h64);
570 return $h64;
571 }
Auth_OpenID_SHA1($text)
Definition: HMAC.php:25

References Auth_OpenID_SHA1().

Referenced by getAssociationFilename(), and useNonce().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _setup()

Auth_OpenID_FileStore::_setup ( )

Make sure that the directories in which we store our data exist.

@access private

Definition at line 89 of file FileStore.php.

90 {
91 return (Auth_OpenID::ensureDir($this->nonce_dir) &&
92 Auth_OpenID::ensureDir($this->association_dir) &&
93 Auth_OpenID::ensureDir($this->temp_dir));
94 }
static ensureDir($dir_name)
Create dir_name as a directory if it does not exist.
Definition: OpenID.php:204

References Auth_OpenID\ensureDir().

Referenced by Auth_OpenID_FileStore().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Auth_OpenID_FileStore()

Auth_OpenID_FileStore::Auth_OpenID_FileStore (   $directory)

Initializes a new Auth_OpenID_FileStore.

This initializes the nonce and association directories, which are subdirectories of the directory passed in.

Parameters
string$directoryThis is the directory to put the store directories in.

Definition at line 49 of file FileStore.php.

50 {
51 if (!Auth_OpenID::ensureDir($directory)) {
52 trigger_error('Not a directory and failed to create: '
53 . $directory, E_USER_ERROR);
54 }
55 $directory = realpath($directory);
56
57 $this->directory = $directory;
58 $this->active = true;
59
60 $this->nonce_dir = $directory . DIRECTORY_SEPARATOR . 'nonces';
61
62 $this->association_dir = $directory . DIRECTORY_SEPARATOR .
63 'associations';
64
65 // Temp dir must be on the same filesystem as the assciations
66 // $directory.
67 $this->temp_dir = $directory . DIRECTORY_SEPARATOR . 'temp';
68
69 $this->max_nonce_age = 6 * 60 * 60; // Six hours, in seconds
70
71 if (!$this->_setup()) {
72 trigger_error('Failed to initialize OpenID file store in ' .
73 $directory, E_USER_ERROR);
74 }
75 }
_setup()
Make sure that the directories in which we store our data exist.
Definition: FileStore.php:89

References _setup(), and Auth_OpenID\ensureDir().

+ Here is the call graph for this function:

◆ clean()

Auth_OpenID_FileStore::clean ( )

Definition at line 440 of file FileStore.php.

441 {
442 if (!$this->active) {
443 trigger_error("FileStore no longer active", E_USER_ERROR);
444 return null;
445 }
446
447 $nonces = Auth_OpenID_FileStore::_listdir($this->nonce_dir);
448 $now = time();
449
450 // Check all nonces for expiry
451 foreach ($nonces as $nonce) {
452 if (!Auth_OpenID_checkTimestamp($nonce, $now)) {
453 $filename = $this->nonce_dir . DIRECTORY_SEPARATOR . $nonce;
455 }
456 }
457
458 foreach ($this->_allAssocs() as $pair) {
459 list($assoc_filename, $assoc) = $pair;
460 if ($assoc->getExpiresIn() == 0) {
462 }
463 }
464 }
Auth_OpenID_checkTimestamp($nonce_string, $allowed_skew=null, $now=null)
Definition: Nonce.php:57
_allAssocs()
Remove expired entries from the database.
Definition: FileStore.php:405

References $filename, _allAssocs(), _listdir(), _removeIfPresent(), and Auth_OpenID_checkTimestamp().

+ Here is the call graph for this function:

◆ cleanupAssociations()

Auth_OpenID_FileStore::cleanupAssociations ( )

Reimplemented from Auth_OpenID_OpenIDStore.

Definition at line 604 of file FileStore.php.

605 {
606 $removed = 0;
607 foreach ($this->_allAssocs() as $pair) {
608 list($assoc_filename, $assoc) = $pair;
609 if ($assoc->getExpiresIn() == 0) {
610 $this->_removeIfPresent($assoc_filename);
611 $removed += 1;
612 }
613 }
614 return $removed;
615 }

References _allAssocs(), and _removeIfPresent().

+ Here is the call graph for this function:

◆ cleanupNonces()

Auth_OpenID_FileStore::cleanupNonces ( )

Reimplemented from Auth_OpenID_OpenIDStore.

Definition at line 119 of file FileStore.php.

120 {
121 global $Auth_OpenID_SKEW;
122
123 $nonces = Auth_OpenID_FileStore::_listdir($this->nonce_dir);
124 $now = time();
125
126 $removed = 0;
127 // Check all nonces for expiry
128 foreach ($nonces as $nonce_fname) {
129 $base = basename($nonce_fname);
130 $parts = explode('-', $base, 2);
131 $timestamp = $parts[0];
132 $timestamp = intval($timestamp, 16);
133 if (abs($timestamp - $now) > $Auth_OpenID_SKEW) {
135 $removed += 1;
136 }
137 }
138 return $removed;
139 }
global $Auth_OpenID_SKEW
Definition: Nonce.php:23
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81

References $Auth_OpenID_SKEW, $timestamp, _listdir(), and _removeIfPresent().

+ Here is the call graph for this function:

◆ destroy()

Auth_OpenID_FileStore::destroy ( )

Definition at line 77 of file FileStore.php.

78 {
79 Auth_OpenID_FileStore::_rmtree($this->directory);
80 $this->active = false;
81 }

References _rmtree().

+ Here is the call graph for this function:

◆ getAssociation()

Auth_OpenID_FileStore::getAssociation (   $server_url,
  $handle = null 
)

Retrieve an association.

If no handle is specified, return the association with the most recent issue time.

Returns
mixed $association

Reimplemented from Auth_OpenID_OpenIDStore.

Definition at line 232 of file FileStore.php.

233 {
234 if (!$this->active) {
235 trigger_error("FileStore no longer active", E_USER_ERROR);
236 return null;
237 }
238
239 if ($handle === null) {
240 $handle = '';
241 }
242
243 // The filename with the empty handle is a prefix of all other
244 // associations for the given server URL.
245 $filename = $this->getAssociationFilename($server_url, $handle);
246
247 if ($handle) {
248 return $this->_getAssociation($filename);
249 } else {
250 $association_files =
251 Auth_OpenID_FileStore::_listdir($this->association_dir);
252 $matching_files = array();
253
254 // strip off the path to do the comparison
255 $name = basename($filename);
256 foreach ($association_files as $association_file) {
257 $base = basename($association_file);
258 if (strpos($base, $name) === 0) {
259 $matching_files[] = $association_file;
260 }
261 }
262
263 $matching_associations = array();
264 // read the matching files and sort by time issued
265 foreach ($matching_files as $full_name) {
266 $association = $this->_getAssociation($full_name);
267 if ($association !== null) {
268 $matching_associations[] = array($association->issued,
269 $association);
270 }
271 }
272
273 $issued = array();
274 $assocs = array();
275 foreach ($matching_associations as $key => $assoc) {
276 $issued[$key] = $assoc[0];
277 $assocs[$key] = $assoc[1];
278 }
279
280 array_multisort($issued, SORT_DESC, $assocs, SORT_DESC,
281 $matching_associations);
282
283 // return the most recently issued one.
284 if ($matching_associations) {
285 list($issued, $assoc) = $matching_associations[0];
286 return $assoc;
287 } else {
288 return null;
289 }
290 }
291 }
getAssociationFilename($server_url, $handle)
Create a unique filename for a given server url and handle.
Definition: FileStore.php:150
_getAssociation($filename)
@access private
Definition: FileStore.php:296

References $filename, _getAssociation(), _listdir(), and getAssociationFilename().

Referenced by removeAssociation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getAssociationFilename()

Auth_OpenID_FileStore::getAssociationFilename (   $server_url,
  $handle 
)

Create a unique filename for a given server url and handle.

This implementation does not assume anything about the format of the handle. The filename that is returned will contain the domain name from the server URL for ease of human inspection of the data directory.

Returns
string $filename

Definition at line 150 of file FileStore.php.

151 {
152 if (!$this->active) {
153 trigger_error("FileStore no longer active", E_USER_ERROR);
154 return null;
155 }
156
157 if (strpos($server_url, '://') === false) {
158 trigger_error(sprintf("Bad server URL: %s", $server_url),
159 E_USER_WARNING);
160 return null;
161 }
162
163 list($proto, $rest) = explode('://', $server_url, 2);
164 $parts = explode('/', $rest);
165 $domain = Auth_OpenID_FileStore::_filenameEscape($parts[0]);
166 $url_hash = Auth_OpenID_FileStore::_safe64($server_url);
167 if ($handle) {
168 $handle_hash = Auth_OpenID_FileStore::_safe64($handle);
169 } else {
170 $handle_hash = '';
171 }
172
173 $filename = sprintf('%s-%s-%s-%s', $proto, $domain, $url_hash,
174 $handle_hash);
175
176 return $this->association_dir. DIRECTORY_SEPARATOR . $filename;
177 }
_filenameEscape($str)
@access private
Definition: FileStore.php:576
_safe64($str)
@access private
Definition: FileStore.php:564
$rest
Definition: goto.php:85

References $filename, $rest, _filenameEscape(), and _safe64().

Referenced by getAssociation(), removeAssociation(), and storeAssociation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ removeAssociation()

Auth_OpenID_FileStore::removeAssociation (   $server_url,
  $handle 
)

Remove an association if it exists.

Do nothing if it does not.

Returns
bool $success

Reimplemented from Auth_OpenID_OpenIDStore.

Definition at line 338 of file FileStore.php.

339 {
340 if (!$this->active) {
341 trigger_error("FileStore no longer active", E_USER_ERROR);
342 return null;
343 }
344
345 $assoc = $this->getAssociation($server_url, $handle);
346 if ($assoc === null) {
347 return false;
348 } else {
349 $filename = $this->getAssociationFilename($server_url, $handle);
351 }
352 }
getAssociation($server_url, $handle=null)
Retrieve an association.
Definition: FileStore.php:232

References $filename, _removeIfPresent(), getAssociation(), and getAssociationFilename().

+ Here is the call graph for this function:

◆ storeAssociation()

Auth_OpenID_FileStore::storeAssociation (   $server_url,
  $association 
)

Store an association in the association directory.

Reimplemented from Auth_OpenID_OpenIDStore.

Definition at line 182 of file FileStore.php.

183 {
184 if (!$this->active) {
185 trigger_error("FileStore no longer active", E_USER_ERROR);
186 return false;
187 }
188
189 $association_s = $association->serialize();
190 $filename = $this->getAssociationFilename($server_url,
191 $association->handle);
192 list($tmp_file, $tmp) = $this->_mktemp();
193
194 if (!$tmp_file) {
195 trigger_error("_mktemp didn't return a valid file descriptor",
196 E_USER_WARNING);
197 return false;
198 }
199
200 fwrite($tmp_file, $association_s);
201
202 fflush($tmp_file);
203
204 fclose($tmp_file);
205
206 if (@rename($tmp, $filename)) {
207 return true;
208 } else {
209 // In case we are running on Windows, try unlinking the
210 // file in case it exists.
211 @unlink($filename);
212
213 // Now the target should not exist. Try renaming again,
214 // giving up if it fails.
215 if (@rename($tmp, $filename)) {
216 return true;
217 }
218 }
219
220 // If there was an error, don't leave the temporary file
221 // around.
223 return false;
224 }
_mktemp()
Create a temporary file on the same filesystem as $this->association_dir.
Definition: FileStore.php:108

References $filename, _mktemp(), _removeIfPresent(), and getAssociationFilename().

+ Here is the call graph for this function:

◆ useNonce()

Auth_OpenID_FileStore::useNonce (   $server_url,
  $timestamp,
  $salt 
)

Return whether this nonce is present.

As a side effect, mark it as no longer present.

Returns
bool $present

Reimplemented from Auth_OpenID_OpenIDStore.

Definition at line 360 of file FileStore.php.

361 {
362 global $Auth_OpenID_SKEW;
363
364 if (!$this->active) {
365 trigger_error("FileStore no longer active", E_USER_ERROR);
366 return null;
367 }
368
369 if ( abs($timestamp - time()) > $Auth_OpenID_SKEW ) {
370 return false;
371 }
372
373 if ($server_url) {
374 list($proto, $rest) = explode('://', $server_url, 2);
375 } else {
376 $proto = '';
377 $rest = '';
378 }
379
380 $parts = explode('/', $rest, 2);
381 $domain = $this->_filenameEscape($parts[0]);
382 $url_hash = $this->_safe64($server_url);
383 $salt_hash = $this->_safe64($salt);
384
385 $filename = sprintf('%08x-%s-%s-%s-%s', $timestamp, $proto,
386 $domain, $url_hash, $salt_hash);
387 $filename = $this->nonce_dir . DIRECTORY_SEPARATOR . $filename;
388
389 $result = @fopen($filename, 'x');
390
391 if ($result === false) {
392 return false;
393 } else {
394 fclose($result);
395 return true;
396 }
397 }
$result

References $Auth_OpenID_SKEW, $filename, $rest, $result, $timestamp, _filenameEscape(), and _safe64().

+ Here is the call graph for this function:

The documentation for this class was generated from the following file: