From d98c495abf51c2581b2d8b1edfc09004f5defcde Mon Sep 17 00:00:00 2001 From: Jerome Jutteau Date: Mon, 29 Jun 2015 00:58:08 +0200 Subject: [PATCH] add an alias system to the API. This alias system permits to create an "alias" to an uploaded file. This permits to upload some new content and update the alias to the new content. This will permits to implement a lot of services, for example: - Storing a live chat between two people - Update a list of files - Put a whole website and update it A few notes: - An alias MUST point to an existing upload at his creation or update. - Alias are not protected against reading but are protected against updates and deletion using a password. The destination of the alias can still be protected by a password. - Alias can be updated to change it's target and/or change the password. - Alias names and passwords must be between 8 and 32 characters. Some examples: - Create an alias: curl -X POST \ --http1.0 \ -F "alias=my-awsome-alias" \ -F "destination=13dA8apU" \ -F "password=my-very-secret-password" \ http://my-host/jirafeau/script.php?alias_create=1 => OK - Get an alias curl -X POST \ --http1.0 \ -F "alias=my-awsome-alias" \ http://my-host/jirafeau/script.php?alias_get=1 => 13dA8apU - Update an alias: curl -X POST \ --http1.0 \ -F "alias=my-awsome-alias" \ -F "destination=2Ab6f17o" \ -F "password=my-new-password" \ http://my-host/jirafeau/script.php?alias_update=1 => OK - Access to alias using the web interface, let's go to: http://couak.net/jirafeau-dev/f.php?h=my-awsome-alias - Delete an alias: curl -X POST \ --http1.0 \ -F "alias=my-awsome-alias" \ -F "password=my-new-password" \ http://my-host/jirafeau/script.php?alias_delete=1 => OK Signed-off-by: Jerome Jutteau --- f.php | 9 ++- install.php | 2 +- lib/functions.php | 175 +++++++++++++++++++++++++++++++++++++++++++++- lib/settings.php | 1 + script.php | 76 ++++++++++++++++++++ 5 files changed, 258 insertions(+), 5 deletions(-) diff --git a/f.php b/f.php index 75d77d7..e3f4420 100644 --- a/f.php +++ b/f.php @@ -49,9 +49,16 @@ if (!preg_match ('/[0-9a-zA-Z_-]+$/', $link_name)) $link = jirafeau_get_link ($link_name); if (count ($link) == 0) +{ + /* Try alias. */ + $alias = jirafeau_get_alias (md5 ($link_name)); + if (count ($alias) > 0) + $link = jirafeau_get_link ($alias["destination"]); +} +if (count ($link) == 0) { require (JIRAFEAU_ROOT.'lib/template/header.php'); - echo '

' . t('Sorry, the requested file is not found') . + echo '

' . t('Sorry, the requested file is not found....' . $link_name) . '

'; require (JIRAFEAU_ROOT.'lib/template/footer.php'); exit; diff --git a/install.php b/install.php index 451ebe3..78680f8 100644 --- a/install.php +++ b/install.php @@ -101,7 +101,7 @@ jirafeau_check_var_dir ($path) $path . '
' . $solution_str . '
' . $mkdir_str2); - foreach (array ('files', 'links', 'async') as $subdir) + foreach (array ('files', 'links', 'async', 'alias') as $subdir) { $subpath = $path.$subdir; diff --git a/lib/functions.php b/lib/functions.php index 2c799f2..c0e0c72 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -770,7 +770,7 @@ jirafeau_get_async_ref ($ref) /** * Delete async transfert informations - */ + */ function jirafeau_async_delete ($ref) { @@ -1120,7 +1120,7 @@ function has_http_forwarded() /** * Generate IP list from HTTP headers generated by a proxy - * return array of IP strings + * @return array of IP strings */ function get_ip_list_http_forwarded() { @@ -1147,7 +1147,7 @@ function get_ip_list_http_forwarded() /** * Get the ip address of the client from REMOTE_ADDR * or from HTTP_X_FORWARDED_FOR if behind a proxy - * @returns an the client ip address + * @returns the client ip address */ function get_ip_address($cfg) { $remote = $_SERVER['REMOTE_ADDR']; @@ -1178,3 +1178,172 @@ function hex_to_base64($hex) $b .= chr (hexdec ($pair)); return base64_encode ($b); } + +/** + * Read alias informations + * @return array containing informations. + */ +function +jirafeau_get_alias ($hash) +{ + $out = array (); + $link = VAR_ALIAS . s2p ("$hash") . $hash; + + if (!file_exists ($link)) + return $out; + + $c = file ($link); + $out['md5_password'] = trim ($c[0]); + $out['ip'] = trim ($c[1]); + $out['update_date'] = trim ($c[2]); + $out['destination'] = trim ($c[3], NL); + + return $out; +} + +/** Create an alias to a jirafeau's link. + * @param $alias alias name + * @param $destination reference of the destination + * @param $password password to protect alias + * @param $ip client's IP + * @return a string containing the edit code of the alias or the string "Error" + */ +function jirafeau_alias_create ($alias, $destination, $password, $ip) +{ + /* Check that alias and password are long enough. */ + if (strlen ($alias) < 8 || + strlen ($alias) > 32 || + strlen ($password) < 8 || + strlen ($password) > 32) + return "Error"; + + /* Check that destination exists. */ + $l = jirafeau_get_link ($destination); + if (!count ($l)) + return "Error"; + + /* Check that alias does not already exists. */ + $alias = md5 ($alias); + $p = VAR_ALIAS . s2p ($alias); + if (file_exists ($p)) + return "Error"; + + /* Create alias folder. */ + @mkdir ($p, 0755, true); + if (!file_exists ($p)) + return "Error"; + + /* Generate password. */ + $md5_password = md5 ($password); + + /* Store informations. */ + $p .= $alias; + $handle = fopen ($p, 'w'); + fwrite ($handle, + $md5_password . NL . + $ip . NL . + date ('U') . NL . + $destination . NL); + fclose ($handle); + + return "Ok"; +} + +/** Update an alias. + * @param $alias alias to update + * @param $destination reference of the new destination + * @param $password password to protect alias + * @param $new_password optional new password to protect alias + * @param $ip client's IP + * @return "Ok" or "Error" string + */ +function jirafeau_alias_update ($alias, $destination, $password, + $new_password, $ip) +{ + $alias = md5 ($alias); + /* Check that alias exits. */ + $a = jirafeau_get_alias ($alias); + if (!count ($a)) + return "Error"; + + /* Check that destination exists. */ + $l = jirafeau_get_link ($a["destination"]); + if (!count ($l)) + return "Error"; + + /* Check password. */ + if ($a["md5_password"] != md5 ($password)) + return "Error"; + + $p = $a["md5_password"]; + if (strlen ($new_password) >= 8 && + strlen ($new_password) <= 32) + $p = md5 ($new_password); + else if (strlen ($new_password) > 0) + return "Error"; + + /* Rewrite informations. */ + $p = VAR_ALIAS . s2p ($alias) . $alias; + $handle = fopen ($p, 'w'); + fwrite ($handle, + $p . NL . + $ip . NL . + date ('U') . NL . + $destination . NL); + fclose ($handle); + return "Ok"; +} + +/** Get an alias. + * @param $alias alias to get + * @return alias destination or "Error" string + */ +function jirafeau_alias_get ($alias) +{ + $alias = md5 ($alias); + /* Check that alias exits. */ + $a = jirafeau_get_alias ($alias); + if (!count ($a)) + return "Error"; + + return $a["destination"]; +} + +function jirafeau_clean_rm_alias ($alias) +{ + $p = s2p ("$alias"); + if (file_exists (VAR_ALIAS . $p . $alias)) + unlink (VAR_ALIAS . $p . $alias); + $parse = VAR_ALIAS . $p; + $scan = array(); + while (file_exists ($parse) + && ($scan = scandir ($parse)) + && count ($scan) == 2 // '.' and '..' folders => empty. + && basename ($parse) != basename (VAR_ALIAS)) + { + rmdir ($parse); + $parse = substr ($parse, 0, strlen($parse) - strlen(basename ($parse)) - 1); + } +} + +/** Delete an alias. + * @param $alias alias to delete + * @param $password password to protect alias + * @return "Ok" or "Error" string + */ +function jirafeau_alias_delete ($alias, $password) +{ + $alias = md5 ($alias); + /* Check that alias exits. */ + $a = jirafeau_get_alias ($alias); + if (!count ($a)) + return "Error"; + + /* Check password. */ + if ($a["md5_password"] != md5 ($password)) + return "Error"; + + jirafeau_clean_rm_alias ($alias); + return "Ok"; +} + diff --git a/lib/settings.php b/lib/settings.php index e3203d9..3812e63 100644 --- a/lib/settings.php +++ b/lib/settings.php @@ -24,6 +24,7 @@ define ('JIRAFEAU_VERSION', '1.0'); define ('VAR_FILES', $cfg['var_root'] . 'files/'); define ('VAR_LINKS', $cfg['var_root'] . 'links/'); define ('VAR_ASYNC', $cfg['var_root'] . 'async/'); +define ('VAR_ALIAS', $cfg['var_root'] . 'alias/'); /* Useful constants. */ if (!defined ('NL')) diff --git a/script.php b/script.php index 1c154b1..d17978c 100644 --- a/script.php +++ b/script.php @@ -508,6 +508,82 @@ fi exit; } } +/* Create alias. */ +elseif (isset ($_GET['alias_create'])) +{ + $ip = get_ip_address($cfg); + if (!jirafeau_challenge_upload_ip ($cfg, $ip)) + { + echo "Error"; + exit; + } + + if (jirafeau_has_upload_password ($cfg) && + (!isset ($_POST['upload_password']) || + !jirafeau_challenge_upload_password ($cfg, $_POST['upload_password']))) + { + echo "Error"; + exit; + } + + if (!isset ($_POST['alias']) || + !isset ($_POST['destination']) || + !isset ($_POST['password'])) + { + echo "Error"; + exit; + } + + echo jirafeau_alias_create ($_POST['alias'], + $_POST['destination'], + $_POST['password'], + $ip); +} +/* Get alias. */ +elseif (isset ($_GET['alias_get'])) +{ + if (!isset ($_POST['alias'])) + { + echo "Error"; + exit; + } + + echo jirafeau_alias_get ($_POST['alias']); +} +/* Update alias. */ +elseif (isset ($_GET['alias_update'])) +{ + if (!isset ($_POST['alias']) || + !isset ($_POST['destination']) || + !isset ($_POST['password'])) + { + echo "Error"; + exit; + } + + $new_password = ''; + if (isset ($_POST['new_password'])) + $new_password = $_POST['new_password']; + + echo jirafeau_alias_update ($_POST['alias'], + $_POST['destination'], + $_POST['password'], + $new_password, + get_ip_address($cfg)); +} +/* Delete alias. */ +elseif (isset ($_GET['alias_delete'])) +{ + if (!isset ($_POST['alias']) || + !isset ($_POST['password'])) + { + echo "Error"; + exit; + } + + echo jirafeau_alias_delete ($_POST['alias'], + $_POST['password']); +} /* Initialize an asynchronous upload. */ elseif (isset ($_GET['init_async'])) { -- 2.34.1