selfpaste is a small self hosting paste service.
+It is not the aim to replace any other well know paste service. It is an experiment
+and build for private use only.
+
+This tool uses PHP fileinfo: https://www.php.net/manual/en/intro.fileinfo.php
+
+ The functions in this module try to guess the content type and encoding of a file
+ by looking for certain magic byte sequences at specific positions within the file.
+ While this is not a bullet proof approach the heuristics used do a very good job.
+
+It is not really bullet proof, but it does the job. Everything can be manipulated
+to look alike something it isn't.
+
+So, here is a friendly REMINDER:
+
+ - Use at own risk.
+ - Don't open it up to the public
+ - Check regularly what is added
+ - Clean everything what you do not know
+ - You provide the service by hosting it. Your are responsible for it!
+ - Change your secret often.
+
+# Why json as a response?
+In cases the upload is over post_max_size the request will not be "arrive".
+Meaning the script does not receive enough information to work with.
+In this case we return the start page. Which is a valid HTTP 200 status response.
+So the client can not only rely in the HTTP status code alone.
# Third party resources
-Link shortening inspired and some code used from: https://www.jwz.org/base64-shortlinks/
-UAC image from: https://doomwiki.org/wiki/File:UAC_insignia.png
\ No newline at end of file
+Link shortening inspired and some code used from: https://www.jwz.org/base64-shortlinks/
\ No newline at end of file
Change upload_max_filesize and php_value post_max_size in webroot/.htaccess
-Change ENDPOINT variable in selfpaste.sh client file.
\ No newline at end of file
+Change ENDPOINT variable in selfpaste.sh client file.
+Change the SELFPASTE_UPLOAD_SECRET in config.php and client file.
+Change SELFPASTE_ALLOWED_FILETYPES to your needs.
\ No newline at end of file
RewriteRule ^(.*)$ index.php?s=$1 [QSA,L]
</IfModule>
+# post_max_size should be greater then upload_max_filesize
+# otherwise there will be no feedback and it looks like
+# nothing has happened
+# if post is greater than post_max_size set in php.ini, no feedback is given...
+php_value post_max_size 2M
php_value upload_max_filesize 1M
-php_value post_max_size 1M
\ No newline at end of file
}
}
+# error reporting
ini_set('log_errors',true);
ini_set('error_log','./logs/error.log');
if(DEBUG === true) {
# static helper class
require 'lib/summoner.class.php';
+# config file
+require 'config.php';
$_short = false;
if(isset($_GET['s']) && !empty($_GET['s'])) {
}
$_create = false;
-if(isset($_POST['c']) && !empty($_GET['s'])) {
- $_create = trim($_GET['s']);
- $_create = Summoner::validate($_short,'nospace') ? $_short : false;
+if(isset($_POST['dl']) && !empty($_POST['dl'])
+ && isset($_FILES['pasty']) && !empty($_FILES['pasty'])
+ && $_POST['dl'] === SELFPASTE_UPLOAD_SECRET) {
+ $_create = true;
}
$contentType = 'Content-type: text/html; charset=UTF-8';
-$contentBody = 'welcome';
+$contentView = 'welcome';
+$httpResponseCode = 200;
if(!empty($_short)) {
-
+ $contentView = 'view';
}
+elseif ($_create === true) {
+ $contentView = 'created';
+ $contentBody = array(
+ 'message' => 'Something went wrong.',
+ 'status' => '400'
+ );
+ $contentType = 'Content-type:application/json;charset=utf-8';
+ $httpResponseCode = 400;
+
+ $_file = $_FILES['pasty'];
+
+ $_checks = array('fileupload','filetype','store');
+ $_do['status'] = false;
+ foreach($_checks as $_check) {
+ if(method_exists('Summoner',$_check)) {
+ $_do = Summoner::$_check($_file);
+ if($_do['status'] !== true) {
+ break;
+ }
+ }
+ }
-var_dump($_POST);
-var_dump($_FILES);
-var_dump($_SERVER);
+ if($_do['status'] === true) {
+ $contentBody = array(
+ 'message' => $_do['message'],
+ 'status' => '200'
+ );
+ }
+}
-# header information
header($contentType);
-if(file_exists('view/'.$contentBody.'.inc.php')) {
- require_once 'view/'.$contentBody.'.inc.php';
+http_response_code($httpResponseCode);
+if(file_exists('view/'.$contentView.'.inc.php')) {
+ require_once 'view/'.$contentView.'.inc.php';
}
else {
error_log('Content body file missing. '.var_export($_SERVER,true),3,'./logs/error.log');
return (substr($haystack, -$length) === $needle);
}
+
+
+ /**
+ * Simple helper to detect the $_FILE upload status
+ * Expects an array from $_FILE
+ * @param $file
+ * @return array
+ */
+ static function fileupload($file) {
+ $message = "Unknown upload error";
+ $status = false;
+
+ if(isset($file['error'])) {
+ switch ($file['error']) {
+ case UPLOAD_ERR_OK:
+ $message = "There is no error, the file uploaded with success.";
+ $status = true;
+ break;
+ case UPLOAD_ERR_INI_SIZE:
+ $message = "The uploaded file exceeds the upload_max_filesize directive in php.ini";
+ break;
+ case UPLOAD_ERR_FORM_SIZE:
+ $message = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form";
+ break;
+ case UPLOAD_ERR_PARTIAL:
+ $message = "The uploaded file was only partially uploaded";
+ break;
+ case UPLOAD_ERR_NO_FILE:
+ $message = "No file was uploaded";
+ break;
+ case UPLOAD_ERR_NO_TMP_DIR:
+ $message = "Missing a temporary folder";
+ break;
+ case UPLOAD_ERR_CANT_WRITE:
+ $message = "Failed to write file to disk";
+ break;
+ case UPLOAD_ERR_EXTENSION:
+ $message = "File upload stopped by extension";
+ break;
+ }
+ }
+
+ return array(
+ 'message' => $message,
+ 'status' => $status
+ );
+ }
+
+ /**
+ * Simple helper to detect the $_FILE type
+ * Expects an array from $_FILE
+ *
+ * @see https://www.php.net/manual/en/intro.fileinfo.php
+ *
+ * @param $file
+ * @return array
+ */
+ static function filetype($file) {
+ $message = "Filetype not suported";
+ $status = false;
+
+ if(isset($file['tmp_name'])) {
+ $finfo = finfo_open(FILEINFO_MIME_TYPE);
+ $mime = finfo_file($finfo, $file['tmp_name']);
+ finfo_close($finfo);
+ var_dump($mime);
+ }
+
+ return array(
+ 'message' => $message,
+ 'status' => $status
+ );
+ }
}