1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
<?php
//####################################################################
//
// File: auth_ticket.inc.php
//
// By: Luc Germain, STI, Universite de Sherbrooke
// Date: 2004-02-17
//
//#####################################################################
//
//#####################################################################
//
// This file defines functions to generate cookie tickets compatible
// with the "mod_auth_tkt" apache module.
//
//#####################################################################
// Configuration
// Weather we encrypt the data or not
$ENCRYPT_COOKIE = true;
// File name where the secret key is stored
$SECRET_KEY_FILE = "/path/to/file.txt";
// Initial seed for calls to rand
if( !isset($SeedIsDone) ) {
srand((double)microtime()*1000000);
$SeedIsDone = true;
}
//---------------------------------------------------------------
// Functions
//---------------------------------------------------------------
//---------------------------------------------------------------
// $result = getSecretKey( );
//---------------------------------------------------------------
//
// Returns a string that contains the secret key used to sign the
// cookie. Read from the secret key file.
//
//---------------------------------------------------------------
function getSecretKey() {
global $SECRET_KEY_FILE;
$keyword = "TktAuthSecret";
$minKeyLength = 10;
$matches = array();
$secretKey = "";
$content = file_get_contents( $SECRET_KEY_FILE );
if( $content === FALSE ){
// Cannot read key file
stopOnError( "F0006" );
}
if( preg_match( "/^\s*$keyword\s+\"(.*?)\"/m",
$content, $matches ) ) {
$secretKey = $matches[1];
}
if( strlen( $secretKey ) < $minKeyLength ) {
// Key invalid or not found
stopOnError( "F0007" );
}
return( $secretKey );
}
//---------------------------------------------------------------
// $result = stopOnError( $code );
//---------------------------------------------------------------
//
// Display an error code in html and exit
//
//---------------------------------------------------------------
function stopOnError( $code ) {
echo " <p>The program encountered an unexpected error.</p>
<p>Error code: $code</p>";
exit( );
}
//---------------------------------------------------------------
// $result = getTKTHash( $ip, $user, $tokens, $data, $key,
// [, $base64 [, $ts]] );
//---------------------------------------------------------------
//
// Returns a string that contains the signed cookie.
//
// The cookie includes the ip address of the user, the user UID, the
// tokens, the user data and a time stamp. The cookie can be
// optionnally base64 encoded. The data is also crypted with the
// encode() function.
//
//---------------------------------------------------------------
function getTKTHash( $ip, $user, $tokens, $data, $key, $base64 = false, $ts = "" ) {
// set the timestamp to now
// unless a time is specified
if( $ts == "" ) {
$ts = time();
}
$ipts = pack( "NN", ip2long($ip), $ts );
// make the cookie signature
$digest0 = md5( $ipts . $key . $user . "\0" . $tokens . "\0" . $data );
$digest = md5( $digest0 . $key );
if( $tokens ){
$tkt = sprintf( "%s%08x%s!%s!%s", $digest, $ts,
encode( $user, $ts, 0 ),
encode( $tokens, $ts, 4 ),
encode( $data, $ts, 8 ) );
} else {
$tkt = sprintf( "%s%08x%s!%s", $digest, $ts,
encode( $user, $ts, 0 ),
encode( $data, $ts, 8 ) );
}
if( $base64 ) {
return( base64_encode( $tkt ) );
} else {
return( $tkt );
}
}
//---------------------------------------------------------------
// $result = encode( $data, $timestamp, $offset );
//---------------------------------------------------------------
//
// Returns a "crypted" version of the data. The length of the data is
// unchanged.
//
// The encryption is deactivated (the function simply returns the
// string unencrypted) if the configuration variable $ENCRYPT_COOKIE
// is not set to TRUE.
//
// The function implements a encryption algorithm that substitutes
// each character for another one using a key to compute the shift
// value. The key is generated from a hash of the timestamp of the
// cookie and the secret key. This key is used from the offset
// specified. This algorithm is reversed in the mod_auth_tkt apache
// module before using the data. This may not be strictly
// cryptographically secure, but should provide sufficient protection
// for the personnal data included in the cookie.
//
//---------------------------------------------------------------
function encode( $data, $timestamp, $offset ) {
$CHARS_TO_ENCODE = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.:";
$LENGTH = strlen( $CHARS_TO_ENCODE );
$md5key = md5( $timestamp . getSecretKey() );
$encoded = "";
global $ENCRYPT_COOKIE;
// check if encryption is activated
if( ! $ENCRYPT_COOKIE ) {
return $data;
}
// encode the data one caracter at a time
for( $i = 0; $i < strlen($data); $i++ ) {
$pos = strpos( $CHARS_TO_ENCODE, $data{$i} );
if( $pos === FALSE ) {
// skip characters that are not in list to encode
$encoded .= $data{$i};
} else {
$newPos = ($pos + (hexdec( $md5key{($offset + $i)%strlen($md5key)} )*7)) % $LENGTH;
$encoded .= $CHARS_TO_ENCODE{$newPos};
// print $data{$i} . " -> $newPos " . $CHARS_TO_ENCODE{$newPos} . "<br>";
}
}
// print "<br>md5key = $md5key<br>data = $data<br>encoded = $encoded";
return $encoded;
}
//---------------------------------------------------------------
// $result = file_get_contents( $filename, $use_include_path = 0 );
//---------------------------------------------------------------
//
// Returns the content of the file in a string, or false if there is
// an error.
//
// This function exists in PHP >= 4.3.0 only
//
//---------------------------------------------------------------
if( !function_exists( 'file_get_contents' ) ) {
function file_get_contents( $filename, $use_include_path = 0 ) {
$data = '';
$file = @fopen( $filename, "rb", $use_include_path );
if( $file ) {
while( !feof( $file ) ) {
$data .= fread( $file, 1024 );
}
fclose($file);
} else {
/* There was a problem opening the file. */
return FALSE;
}
return $data;
}
}
?>
|