diff options
| author | 2014-03-01 14:45:58 +0100 | |
|---|---|---|
| committer | 2014-03-01 14:45:58 +0100 | |
| commit | 29b3bbfe284a6e56413a2e89b740ffc4172c6847 (patch) | |
| tree | 5e1b74f889f071e3e45beca09673304629e79f74 /p/api | |
| parent | f44683b5671b323ba96f0c4cd47ba9458e934679 (diff) | |
API: Real password system
https://github.com/marienfressinaud/FreshRSS/issues/13
Expiring token not implemented yet
Diffstat (limited to 'p/api')
| -rw-r--r-- | p/api/greader.php | 89 |
1 files changed, 54 insertions, 35 deletions
diff --git a/p/api/greader.php b/p/api/greader.php index e99e1c0c8..035a031dd 100644 --- a/p/api/greader.php +++ b/p/api/greader.php @@ -20,9 +20,6 @@ Server-side API compatible with Google Reader API layer 2 * https://github.com/theoldreader/api */ -define('TEMP_PASSWORD', 'temp123'); //Change to another ASCII password -define('TEMP_AUTH', 'XtofqkkOkCULRLH8'); //Change to another random ASCII auth - require('../../constants.php'); require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader @@ -119,14 +116,28 @@ function checkCompatibility() { exit(); } -function authorizationToUser() { +function authorizationToUserConf() { $headerAuth = headerVariable('Authorization', 'GoogleLogin_auth'); //Input is 'GoogleLogin auth', but PHP replaces spaces by '_' http://php.net/language.variables.external if ($headerAuth != '') { $headerAuthX = explode('/', $headerAuth, 2); - if ((count($headerAuthX) === 2) && ($headerAuthX[1] === TEMP_AUTH)) { + if (count($headerAuthX) === 2) { $user = $headerAuthX[0]; if (ctype_alnum($user)) { - return $user; + try { + $conf = new FreshRSS_Configuration($user); + } catch (Exception $e) { + logMe($e->getMessage() . "\n"); + unauthorized(); + } + if ($headerAuthX[1] === sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash)) { + return $conf; + } else { + logMe('Invalid API authorisation for user ' . $user . ': ' . $headerAuthX[1] . "\n"); + Minz_Log::record('Invalid API authorisation for user ' . $user . ': ' . $headerAuthX[1], Minz_Log::WARNING); + unauthorized(); + } + } else { + badRequest(); } } } @@ -135,28 +146,45 @@ function authorizationToUser() { function clientLogin($email, $pass) { //http://web.archive.org/web/20130604091042/http://undoc.in/clientLogin.html logMe('clientLogin(' . $email . ")\n"); - if ($pass !== TEMP_PASSWORD) { - unauthorized(); + if (ctype_alnum($email)) { + if (!function_exists('password_verify')) { + include_once(LIB_PATH . '/password_compat.php'); + } + try { + $conf = new FreshRSS_Configuration($email); + } catch (Exception $e) { + logMe($e->getMessage() . "\n"); + Minz_Log::record('Invalid API user ' . $email, Minz_Log::WARNING); + unauthorized(); + } + if ($conf->apiPasswordHash != '' && password_verify($pass, $conf->apiPasswordHash)) { + header('Content-Type: text/plain; charset=UTF-8'); + $auth = $email . '/' . sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash); + echo 'SID=', $auth, "\n", + 'Auth=', $auth, "\n"; + exit(); + } else { + Minz_Log::record('Password API mismatch for user ' . $email, Minz_Log::WARNING); + unauthorized(); + } + } else { + badRequest(); } - header('Content-Type: text/plain; charset=UTF-8'); - $auth = $email . '/' . TEMP_AUTH; - echo 'SID=', $auth, "\n", - 'Auth=', $auth, "\n"; - exit(); + die(); } -function token($user) { +function token($conf) { //http://blog.martindoms.com/2009/08/15/using-the-google-reader-api-part-1/ https://github.com/ericmann/gReader-Library/blob/master/greader.class.php - logMe('token('. $user . ")\n"); - $token = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ01234'; //Must have 57 characters... + logMe('token('. $conf->user . ")\n"); //TODO: Implement real token that expires + $token = str_pad(sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash), 57, 'Z'); //Must have 57 characters echo $token, "\n"; exit(); } -function checkToken($user, $token) { +function checkToken($conf, $token) { //http://code.google.com/p/google-reader-api/wiki/ActionToken logMe('checkToken(' . $token . ")\n"); - if ($token === 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ01234') { + if ($token === str_pad(sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash), 57, 'Z')) { return true; } unauthorized(); @@ -462,32 +490,23 @@ if (!Minz_Configuration::apiEnabled()) { Minz_Session::init('FreshRSS'); -$user = authorizationToUser(); -$conf = null; +$conf = authorizationToUserConf(); +$user = $conf == null ? '' : $conf->user; logMe('User => ' . $user . "\n"); -if ($user != null) { - try { - $conf = new FreshRSS_Configuration($user); - } catch (Exception $e) { - logMe($e->getMessage()); - $user = null; - badRequest(); - } -} - Minz_Session::_param('currentUser', $user); if (count($pathInfos) < 3) { badRequest(); } elseif ($pathInfos[1] === 'accounts') { - if (($pathInfos[2] === 'ClientLogin') && isset($_REQUEST['Email']) && isset($_REQUEST['Passwd'])) + if (($pathInfos[2] === 'ClientLogin') && isset($_REQUEST['Email']) && isset($_REQUEST['Passwd'])) { clientLogin($_REQUEST['Email'], $_REQUEST['Passwd']); + } } elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfos[3]) && $pathInfos[3] === '0' && isset($pathInfos[4])) { - if ($user == null) { + if ($user == '') { unauthorized(); } $timestamp = isset($_GET['ck']) ? intval($_GET['ck']) : 0; //ck=[unix timestamp] : Use the current Unix time here, helps Google with caching. @@ -543,7 +562,7 @@ elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfo break; case 'edit-tag': //http://blog.martindoms.com/2010/01/20/using-the-google-reader-api-part-3/ $token = isset($_POST['T']) ? trim($_POST['T']) : ''; - checkToken($user, $token); + checkToken($conf, $token); $a = isset($_POST['a']) ? $_POST['a'] : ''; //Add: user/-/state/com.google/read user/-/state/com.google/starred $r = isset($_POST['r']) ? $_POST['r'] : ''; //Remove: user/-/state/com.google/read user/-/state/com.google/starred $e_ids = multiplePosts('i'); //item IDs @@ -551,7 +570,7 @@ elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfo break; case 'mark-all-as-read': $token = isset($_POST['T']) ? trim($_POST['T']) : ''; - checkToken($user, $token); + checkToken($conf, $token); $streamId = $_POST['s']; //StreamId $ts = isset($_POST['ts']) ? $_POST['ts'] : '0'; //Older than timestamp in nanoseconds if (!ctype_digit($ts)) { @@ -560,7 +579,7 @@ elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfo markAllAsRead($streamId, $ts); break; case 'token': - Token($user); + Token($conf); break; } } elseif ($pathInfos[1] === 'check' && $pathInfos[2] === 'compatibility') { |
