]> 91.132.146.200 Git - selfpaste.git/commitdiff
working with bash client so far. Updated documentation. Basic config file.
authorBanana <banana@mirage>
Sat, 21 Dec 2019 20:06:05 +0000 (21:06 +0100)
committerBanana <banana@mirage>
Sat, 21 Dec 2019 20:06:05 +0000 (21:06 +0100)
README
TODO
documentation/clients.txt [new file with mode: 0644]
documentation/filetypes.txt
documentation/requirements.txt [new file with mode: 0644]
webroot/config.default.php
webroot/index.php
webroot/lib/summoner.class.php
webroot/pasties/.gitignore [new file with mode: 0644]
webroot/view/view.inc.php [new file with mode: 0644]

diff --git a/README b/README
index 73881733195425d4c6dd478477aea669cf225951..62feff478f0912d9269390f04513a327cdd0db40 100644 (file)
--- a/README
+++ b/README
@@ -8,7 +8,7 @@ This tool uses PHP fileinfo: https://www.php.net/manual/en/intro.fileinfo.php
 > 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
+It is not really bulletproof, but it does the job. Everything can be manipulated
 to look alike something it isn't.
 
 So, here is a friendly REMINDER:
diff --git a/TODO b/TODO
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8483a7ef1781fdaad170b2fd0882a91efaf17818 100644 (file)
--- a/TODO
+++ b/TODO
@@ -0,0 +1,7 @@
+* Documentation
+* lifetime
+* deletion of old ones
+* add force download parameter
+* HTTPS for selfpaste bash client
+* multiple secrets
+* extending allowed filetypes
\ No newline at end of file
diff --git a/documentation/clients.txt b/documentation/clients.txt
new file mode 100644 (file)
index 0000000..d677b53
--- /dev/null
@@ -0,0 +1,15 @@
+A bash client 'selfpaste.sh' is available for use in the client folder.
+To create this file just copy selfpaste.default.sh to selfpaste.sh and
+make sure you change ENDPOINT and SELFPASTE_UPLOAD_SECRET.
+
+Requirements to create a new client are:
+
+    - Talk to the selfpaste endpoint over HTTP(S)
+    - Make a POST with multipart/form-data
+    - The post must have field pasty and field dl
+    -- pasty=File to upload
+    -- dl=YOUR SECRET
+    - Can parse json at success
+    -- message: Contains the URL or detailed information
+    -- status: integer based in HTML status code.
+    - A normal HTTP 200 without json is not a success
\ No newline at end of file
index 93d8e41c5908d4f87f2a1b05de3f9aa9efd74433..9e7c86769fef761f07e3e95bc0a6ecb83edf6be5 100644 (file)
@@ -8,4 +8,6 @@ It is not really bullet proof, but it does the job. Everything can be manipulate
 to look alike something it isn't.
 
 To expand or reduce the allowed filetypes, edit the SELFPASTE_ALLOWED_FILETYPES string to your needs.
-Again READ the README and security info!
\ No newline at end of file
+Again READ the README and security info!
+
+Read more about filetypes here: https://www.iana.org/assignments/media-types/media-types.xhtml
\ No newline at end of file
diff --git a/documentation/requirements.txt b/documentation/requirements.txt
new file mode 100644 (file)
index 0000000..0d502e7
--- /dev/null
@@ -0,0 +1,2 @@
+PHP >=7.3
+Apache >= 2.4
\ No newline at end of file
index 15bfe4e3909b8edd636dd3170af0bb02260f0a0c..bfd756636e5a7277c610d092c1642dbd7daf3a3a 100644 (file)
@@ -18,4 +18,8 @@ define('SELFPASTE_UPLOAD_SECRET','PLEASE CHANGE YOUR SECRET');
 define('SELFPASTE_UPLOAD_DIR','pasties');
 # those are the allowed file types.
 # Make sure you read the README and documentation!
-define(SELFPASTE_ALLOWED_FILETYPES,'');
+define('SELFPASTE_ALLOWED_FILETYPES','text/plain,text/comma-separated-values,text/css,text/xml,text/x-php');
+# this is your domain and path on which selfpaste is accessible
+# needed to respond with the correct link for your paste
+# please NO / at the end
+define('SELFPASTE_URL','http://your.tld/path/selfpaste/webroot');
index 85729a4b458bfd9829d65371e09147a113bbccd7..7ebb536ed0c7e300d038b5306687187b0e41287e 100644 (file)
@@ -62,36 +62,47 @@ $contentView = 'welcome';
 $httpResponseCode = 200;
 
 if(!empty($_short)) {
+    $contentType = 'Content-type: text/plain; charset=UTF-8';
     $contentView = 'view';
+
+    $_requestFile = Summoner::createStoragePath($_short);
+    $_requestFile .= $_short;
+    if(is_readable($_requestFile)) {
+        $contentBody = $_requestFile;
+    }
 }
 elseif ($_create === true) {
     $contentView = 'created';
-    $contentBody = array(
-        'message' => 'Something went wrong.',
-        'status' => '400'
-    );
     $contentType = 'Content-type:application/json;charset=utf-8';
     $httpResponseCode = 400;
+    $_message = 'Something went wrong.';
 
     $_file = $_FILES['pasty'];
 
-    $_checks = array('fileupload','filetype','store');
+    $_file['short'] = Summoner::createShort();
+    $_file['shortUrl'] = SELFPASTE_URL.'/'.$_file['short'];
+    $_file['storagepath'] = Summoner::createStoragePath($_file['short']);
+
+    $_checks = array('checkFileUploadStatus','checkAllowedFiletype','checkStorage','moveUploadedPasteFile');
     $_do['status'] = false;
     foreach($_checks as $_check) {
         if(method_exists('Summoner',$_check)) {
             $_do = Summoner::$_check($_file);
-            if($_do['status'] !== true) {
+            $_message = $_do['message'];
+            if($_do['status'] === true) {
+                $httpResponseCode = 200;
+            }
+            else {
+                $httpResponseCode = 400;
                 break;
             }
         }
     }
 
-    if($_do['status'] === true) {
-        $contentBody = array(
-            'message' => $_do['message'],
-            'status' => '200'
-        );
-    }
+    $contentBody = array(
+        'message' => $_message,
+        'status' => $httpResponseCode
+    );
 }
 
 header($contentType);
index 8f3b2da335650f62639f88edd6511b82d27a56a8..f05aaf8a6056c8ed74c14cc5e6824dcbaad4d167 100644 (file)
@@ -144,7 +144,7 @@ class Summoner {
      * @param $file
      * @return array
      */
-    static function fileupload($file) {
+    static function checkFileUploadStatus($file) {
         $message = "Unknown upload error";
         $status = false;
 
@@ -193,15 +193,78 @@ class Summoner {
      * @param $file
      * @return array
      */
-    static function filetype($file) {
-        $message = "Filetype not suported";
+    static function checkAllowedFiletype($file) {
+        $message = "Filetype not supported";
         $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);
+            if(strpos(SELFPASTE_ALLOWED_FILETYPES,$mime) !== false) {
+                $status = true;
+                $message = "Filetype allowed";
+            }
+            if(DEBUG) $message .= " $mime";
+        }
+
+        return array(
+            'message' => $message,
+            'status' => $status
+        );
+    }
+
+    /**
+     * Simple helper to create and make sure the storage
+     * location is available
+     * Expects an array from $_FILE
+     * with an extra key = storagepath
+     *
+     * @param $file
+     * @return array
+     */
+    static function checkStorage($file) {
+        $message = "File storage failure";
+        $status = false;
+
+        if(isset($file['storagepath']) && !empty($file['storagepath'])
+            && is_writable(SELFPASTE_UPLOAD_DIR)) {
+            if (mkdir($file['storagepath'],0777,true)) {
+                $message = "File storage creation success";
+                $status = true;
+            }
+        }
+
+        if(DEBUG) $message .= " ".$file['storagepath'];
+
+        return array(
+            'message' => $message,
+            'status' => $status
+        );
+    }
+
+    /**
+     * move the uploaded file.
+     * Depends on the _FILES info and the keys
+     * storagepath, short, shortUrl
+     * @param $file
+     * @return array
+     */
+    static function moveUploadedPasteFile($file) {
+        $message = "File storage failure";
+        $status = false;
+        //shortUrl
+
+        if(isset($file['storagepath']) && !empty($file['storagepath'])
+            && isset($file['short']) && !empty($file['short'])) {
+            $_newFilename = self::endsWith($file['storagepath'],'/') ? $file['storagepath'] : $file['storagepath'].'/';
+            $_newFilename .= $file['short'];
+            if(move_uploaded_file($file['tmp_name'], $_newFilename)) {
+                $status = true;
+                $message = $file['shortUrl'];
+            }
+
+            if(DEBUG) $message .= " $_newFilename";
         }
 
         return array(
@@ -209,4 +272,56 @@ class Summoner {
             'status' => $status
         );
     }
+
+    /**
+     * Simple helper to create a new name
+     *
+     * @return string
+     * @throws Exception
+     */
+    static function createShort() {
+        $idstring = random_int(1000, 9999);
+        return self::b64sl_pack_id($idstring);
+    }
+
+    /**
+     * create a short string based on a integer
+     *
+     * @see https://www.jwz.org/base64-shortlinks/
+     *
+     * @return string
+     */
+    static function b64sl_pack_id($id) {
+        $id = intval($id);
+        $ida = ($id > 0xFFFFFFFF ? $id >> 32 : 0);     // 32 bit big endian, top
+        $idb = ($id & 0xFFFFFFFF);                     // 32 bit big endian, bottom
+        $id = pack ('N', $ida) . pack ('N', $idb);
+        $id = preg_replace('/^\000+/', '', "$id");     // omit high-order NUL bytes
+        $id = base64_encode ($id);
+        $id = str_replace ('+', '-', $id);             // encode URL-unsafe "+" "/"
+        $id = str_replace ('/', '_', $id);
+        $id = preg_replace ('/=+$/', '', $id); // omit trailing padding bytes
+        return $id;
+    }
+
+    /**
+     * create based on the given string a path
+     * each char in string is a dir
+     * and add SELFPASTE_UPLOAD_DIR
+     * asd -> SELFPASTE_UPLOAD_DIR/a/s/d
+     * @param $string
+     * @return bool|string
+     */
+    static function createStoragePath($string) {
+        $p = false;
+
+        if(!empty($string) && is_writable(SELFPASTE_UPLOAD_DIR)) {
+            $p = SELFPASTE_UPLOAD_DIR.'/';
+            for($i=0;$i<strlen($string);$i++) {
+                $p .= $string[$i]."/";
+            }
+        }
+
+        return $p;
+    }
 }
diff --git a/webroot/pasties/.gitignore b/webroot/pasties/.gitignore
new file mode 100644 (file)
index 0000000..e24a60f
--- /dev/null
@@ -0,0 +1,3 @@
+*
+!.gitignore
+!.htaccess
diff --git a/webroot/view/view.inc.php b/webroot/view/view.inc.php
new file mode 100644 (file)
index 0000000..38b06de
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+/**
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
+ *
+ * You should have received a copy of the
+ * COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+ * along with this program.  If not, see http://www.sun.com/cddl/cddl.html
+ *
+ * 2019 https://www.bananas-playground.net/projekt/selfpaste
+ */
+if (file_exists($contentBody)) {
+    header('Expires: 0');
+    header('Cache-Control: must-revalidate');
+    header('Pragma: public');
+    readfile($contentBody);
+    exit;
+}
\ No newline at end of file