From aa43cb5e2338b8dbd12a75314104a34ba608263b Mon Sep 17 00:00:00 2001 From: Nick Date: Sun, 19 Jul 2020 16:24:52 -0400 Subject: [PATCH] PortalAuth, Papers, and CursedScreech Updates (#87) * Version 1.9 * Version 2.0 * Version 1.6 * Updated Papers to v2.0 * Replaced readKeys.sh with cfgNginx.py * Fixed PKCS12 export bug Co-authored-by: combsn --- CursedScreech/api/module.php | 4 +- CursedScreech/includes/changelog/Version 1.6 | 4 + CursedScreech/includes/forest/settings | 4 +- .../includes/scripts/getInterfaceIP.sh | 2 +- CursedScreech/module.info | 2 +- Papers/.gitignore | 1 + Papers/README.md | 4 + Papers/api/module.php | 94 +- Papers/includes/changelog/Version 1.9 | 6 + Papers/includes/changelog/Version 2.0 | 5 + Papers/includes/help/status.help | 7 +- Papers/includes/nginx.conf | 17 +- Papers/includes/scripts/checkDepends.sh | 19 +- Papers/includes/scripts/decryptRSAKeys.sh | 73 ++ Papers/includes/scripts/decryptSSHKey.sh | 55 ++ Papers/includes/scripts/encryptRSAKeys.sh | 97 +++ Papers/includes/scripts/encryptSSHKey.sh | 55 ++ Papers/includes/scripts/getCertInfo.sh | 6 +- Papers/includes/scripts/installDepends.sh | 6 +- Papers/includes/scripts/isEncrypted.sh | 89 ++ Papers/includes/scripts/readKeys.sh | 18 - Papers/includes/scripts/removeDepends.sh | 6 +- Papers/includes/scripts/testEncrypt.sh | 2 +- Papers/js/module.js | 102 ++- Papers/module.html | 91 +- Papers/module.info | 2 +- PortalAuth/includes/changelog/Version 2.0 | 5 + PortalAuth/includes/config | 2 +- PortalAuth/includes/scripts/PortalCloner.py | 2 +- PortalAuth/includes/scripts/depends.sh | 1 + .../Free_WiFi_Week/backups/injectJS.txt | 2 +- .../injects/Free_WiFi_Week/injectJS.txt | 2 +- .../injects/Harvester/backups/injectJS.txt | 2 +- .../scripts/injects/Harvester/injectJS.txt | 2 +- .../injects/Payloader/backups/injectJS.txt | 2 +- .../scripts/injects/Payloader/injectJS.txt | 2 +- .../includes/scripts/jquery-3.4.1.min.js | 2 + .../includes/scripts/libs/tinycss/__init__.py | 47 + .../includes/scripts/libs/tinycss/color3.py | 383 ++++++++ .../includes/scripts/libs/tinycss/css21.py | 823 ++++++++++++++++++ .../includes/scripts/libs/tinycss/decoding.py | 252 ++++++ .../includes/scripts/libs/tinycss/page3.py | 162 ++++ .../includes/scripts/libs/tinycss/parsing.py | 166 ++++ .../scripts/libs/tinycss/speedups.pyx | 189 ++++ .../scripts/libs/tinycss/tests/__init__.py | 26 + .../scripts/libs/tinycss/tests/speed.py | 134 +++ .../scripts/libs/tinycss/tests/test_api.py | 45 + .../scripts/libs/tinycss/tests/test_color3.py | 202 +++++ .../scripts/libs/tinycss/tests/test_css21.py | 353 ++++++++ .../libs/tinycss/tests/test_decoding.py | 79 ++ .../scripts/libs/tinycss/tests/test_page3.py | 101 +++ .../scripts/libs/tinycss/token_data.py | 452 ++++++++++ .../scripts/libs/tinycss/tokenizer.py | 215 +++++ PortalAuth/module.info | 2 +- 54 files changed, 4244 insertions(+), 182 deletions(-) create mode 100644 CursedScreech/includes/changelog/Version 1.6 create mode 100644 Papers/.gitignore create mode 100644 Papers/README.md create mode 100644 Papers/includes/changelog/Version 1.9 create mode 100644 Papers/includes/changelog/Version 2.0 create mode 100644 Papers/includes/scripts/decryptRSAKeys.sh create mode 100644 Papers/includes/scripts/decryptSSHKey.sh create mode 100644 Papers/includes/scripts/encryptRSAKeys.sh create mode 100644 Papers/includes/scripts/encryptSSHKey.sh create mode 100644 Papers/includes/scripts/isEncrypted.sh delete mode 100755 Papers/includes/scripts/readKeys.sh create mode 100644 PortalAuth/includes/changelog/Version 2.0 create mode 100644 PortalAuth/includes/scripts/jquery-3.4.1.min.js create mode 100644 PortalAuth/includes/scripts/libs/tinycss/__init__.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/color3.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/css21.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/decoding.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/page3.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/parsing.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/speedups.pyx create mode 100644 PortalAuth/includes/scripts/libs/tinycss/tests/__init__.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/tests/speed.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/tests/test_api.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/tests/test_color3.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/tests/test_css21.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/tests/test_decoding.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/tests/test_page3.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/token_data.py create mode 100644 PortalAuth/includes/scripts/libs/tinycss/tokenizer.py diff --git a/CursedScreech/api/module.php b/CursedScreech/api/module.php index 686ae8c..2a9856f 100755 --- a/CursedScreech/api/module.php +++ b/CursedScreech/api/module.php @@ -313,7 +313,7 @@ class CursedScreech extends Module { $data = array(); exec("pgrep -lf " . $procName, $data); $output = explode(" ", $data[0]); - if (strpos($output[2], $procName) !== False) { + if (strpos($output[1], "python") !== False) { return $output[0]; } return false; @@ -651,4 +651,4 @@ class CursedScreech extends Module { return true; } } -} \ No newline at end of file +} diff --git a/CursedScreech/includes/changelog/Version 1.6 b/CursedScreech/includes/changelog/Version 1.6 new file mode 100644 index 0000000..e82c4ca --- /dev/null +++ b/CursedScreech/includes/changelog/Version 1.6 @@ -0,0 +1,4 @@ +December 26, 2019 +

+ - Fixed bug in latest firmware that saved module settings in an invalid state causing issues when running Sein.
+ diff --git a/CursedScreech/includes/forest/settings b/CursedScreech/includes/forest/settings index dbde3b0..fed6f93 100755 --- a/CursedScreech/includes/forest/settings +++ b/CursedScreech/includes/forest/settings @@ -1,8 +1,8 @@ kuro_key= target_key= client_serial=File does not exist -iface_name=br-lan -iface_ip=172.16.42.1 +iface_name=wlan2 +iface_ip=192.168.0.138 mcast_group=231.253.78.29 mcast_port=19578 target_list=/pineapple/modules/CursedScreech/includes/forest/targets.log diff --git a/CursedScreech/includes/scripts/getInterfaceIP.sh b/CursedScreech/includes/scripts/getInterfaceIP.sh index 18963df..d808c35 100755 --- a/CursedScreech/includes/scripts/getInterfaceIP.sh +++ b/CursedScreech/includes/scripts/getInterfaceIP.sh @@ -6,4 +6,4 @@ if [ $# -lt 1 ]; then fi -ifconfig $1 | grep inet | awk '{split($2,a,":"); print a[2]}' +ifconfig $1 | grep inet | awk '{split($2,a,":"); print a[2]}' | tr -d '\n' diff --git a/CursedScreech/module.info b/CursedScreech/module.info index 693eda7..ca4157b 100755 --- a/CursedScreech/module.info +++ b/CursedScreech/module.info @@ -6,5 +6,5 @@ "tetra" ], "title": "CursedScreech", - "version": "1.5" + "version": "1.6" } diff --git a/Papers/.gitignore b/Papers/.gitignore new file mode 100644 index 0000000..600d2d3 --- /dev/null +++ b/Papers/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/Papers/README.md b/Papers/README.md new file mode 100644 index 0000000..74fd2ef --- /dev/null +++ b/Papers/README.md @@ -0,0 +1,4 @@ +# Papers +This is a module for the WiFi Pineaple NANO and TETRA that allows you to create and manage TLS/SSL certificates with ease. It will also update the nginx configuration on the Pineapple to use/remove SSL automatically. + +Check out the [tutorial video](https://www.youtube.com/watch?v=XQ6qmouMtS4) for Papers. diff --git a/Papers/api/module.php b/Papers/api/module.php index 06f22af..b028ecb 100755 --- a/Papers/api/module.php +++ b/Papers/api/module.php @@ -83,7 +83,10 @@ class Papers extends Module break; case 'loadCertProps': $this->loadCertificateProperties($this->request->certName); - break; + break; + case 'loadSSHKeys': + $this->loadSSHKeys($this->request->keyName); + break; case 'downloadKeys': $this->downloadKeys($this->request->parameters->name, $this->request->parameters->type); break; @@ -255,28 +258,19 @@ class Papers extends Module $cryptInfo = array(); $argString = ""; - $cryptInfo['-k'] = $keyName; + $cryptInfo['-k'] = "{$keyName}.key"; + $cryptInfo['-a'] = $params['algo']; // Check if the certificate should be encrypted if (array_key_exists('encrypt', $params)) { $argString = "--encrypt "; - - $cryptInfo['-a'] = (array_key_exists('algo', $params)) ? $params['algo'] : False; - $cryptInfo['-p'] = (array_key_exists('pkey_pass', $params)) ? $params['pkey_pass'] : False; - - if (!$cryptInfo['-a'] || !$cryptInfo['-p']) { - $this->logError("Build Certificate Error", "The public and private keys were generated successfully but an algorithm or password were not supplied for encryption. The certs can still be found in your SSL store."); - $this->respond(false, "Build finished with errors. Check the logs for details."); - return; - } } // Check if the certificates should be placed into an encrypted container if (array_key_exists('container', $params)) { + $cryptInfo['--pubkey'] = "{$keyName}.cer"; $cryptInfo['-c'] = (array_key_exists('container', $params)) ? $params['container'] : False; - $cryptInfo['-calgo'] = (array_key_exists('c_algo', $params)) ? $params['c_algo'] : False; - $cryptInfo['-cpass'] = (array_key_exists('c_pass', $params)) ? $params['c_pass'] : False; } - + // Build an argument string with all available arguments foreach ($cryptInfo as $k => $v) { if (!$v) {continue;} @@ -284,11 +278,11 @@ class Papers extends Module } $argString = rtrim($argString); - // Execute encryptKeys.sh with the parameters and check for errors + // Execute encryptRSAKeys.sh with the parameters and check for errors $retData = array(); - exec(__SCRIPTS__ . "encryptKeys.sh " . $argString, $retData); - $res = implode("\n", $retData); - if ($res != "Complete") { + exec("echo " . escapeshellcmd($params['pkey_pass']) . " | " . __SCRIPTS__ . "encryptRSAKeys.sh {$argString}", $retData); + if (end($retData) != "Complete") { + $res = implode("\n", $retData); $this->logError("Certificate Encryption Error", "The public and private keys were generated successfully but encryption failed with the following error:\n\n" . $res); $this->respond(false, "Build finished with errors. Check the logs for details."); return; @@ -298,16 +292,16 @@ class Papers extends Module } private function encryptKey($keyName, $keyType, $algo, $pass) { - $retData = array(); - $argString = "encryptKeys.sh --encrypt -k " . $keyName . " -a " . $algo . " -p " . $pass; - + $retData = array(); + $cmdString = "encryptRSAKeys.sh --encrypt -k {$keyName}.key -a {$algo}"; + if ($keyType == "SSH") { - $argString .= " --ssh"; - } + $cmdString = "encryptSSHKey.sh -k {$keyName}.key"; + } - exec(__SCRIPTS__ . $argString, $retData); - $res = implode("\n", $retData); - if ($res != "Complete") { + exec("echo " . escapeshellcmd($pass) . " | " . __SCRIPTS__ . $cmdString, $retData); + if (end($retData) != "Complete") { + $res = implode("\n", $retData); $this->logError("Key Encryption Error", "The following error occurred:\n\n" . $res); return false; } @@ -315,16 +309,16 @@ class Papers extends Module } private function decryptKey($keyName, $keyType, $pass) { - $retData = array(); - $argString = "decryptKeys.sh -k " . $keyName . " -p " . $pass; + $retData = array(); + $cmdString = "decryptRSAKeys.sh -k {$keyName}.key"; + + if ($keyType == "SSH") { + $cmdString = "decryptSSHKey.sh -k {$keyName}.key"; + } - if ($keyType == "SSH") { - $argString .= " --ssh"; - } - - exec(__SCRIPTS__ . $argString, $retData); - $res = implode("\n", $retData); - if ($res != "Complete") { + exec("echo " . escapeshellcmd($pass) . " | " . __SCRIPTS__ . $cmdString, $retData); + if (end($retData) != "Complete") { + $res = implode("\n", $retData); $this->logError("Key Decryption Error", "The following error occurred:\n\n" . $res); return false; } @@ -374,7 +368,7 @@ class Papers extends Module $retData = array(); $res = []; - exec(__SCRIPTS__ . "getCertInfo.sh -k " . $cert, $retData); + exec(__SCRIPTS__ . "getCertInfo.sh -k {$cert}.cer", $retData); if (count($retData) == 0) { $this->respond(false); return false; @@ -386,12 +380,23 @@ class Papers extends Module $key = $parts[0]; $val = $parts[1]; $res[$key] = $val; - } + } + + $res['privkey'] = file_get_contents(__SSLSTORE__ . "{$cert}.key"); + $res['certificate'] = file_get_contents(__SSLSTORE__ . "{$cert}.cer"); // Return success and the contents of the tmp file $this->respond(true, null, $res); return true; - } + } + + private function loadSSHKeys($name) { + $this->respond(true, null, array( + "privkey" => file_get_contents(__SSHSTORE__ . "{$name}.key"), + "pubkey" => file_get_contents(__SSHSTORE__ . "{$name}.pub")) + ); + return true; + } private function getKeys($dir) { $keyType = ($dir == __SSLSTORE__) ? "TLS/SSL" : "SSH"; @@ -436,12 +441,13 @@ class Papers extends Module private function keyIsEncrypted($keyName, $keyType) { $data = array(); - $keyDir = ($keyType == "SSH") ? __SSHSTORE__ : __SSLSTORE__; - exec(__SCRIPTS__ . "testEncrypt.sh -k " . $keyName . " -d " . $keyDir . " 2>&1", $data); - if ($data[0] == "writing RSA key") { - return false; - } else if ($data[0] == "unable to load Private Key") { + $keyDir = ($keyType == "SSH") ? __SSHSTORE__ : __SSLSTORE__; + $type = ($keyType == "SSH") ? "SSH" : "RSA"; + exec(__SCRIPTS__ . "isEncrypted.sh -k {$keyName}.key -d {$keyDir} -t {$type} 2>&1", $data); + if ($data[0] == "true") { return true; + } else if ($data[0] == "false") { + return false; } } @@ -536,7 +542,7 @@ class Papers extends Module private function checkSSLConfig() { $retData = array(); - exec(__SCRIPTS__ . "readKeys.sh", $retData); + exec(__SCRIPTS__ . "cfgNginx.py --getSSLCerts", $retData); return implode(" ", $retData); } diff --git a/Papers/includes/changelog/Version 1.9 b/Papers/includes/changelog/Version 1.9 new file mode 100644 index 0000000..f463475 --- /dev/null +++ b/Papers/includes/changelog/Version 1.9 @@ -0,0 +1,6 @@ +December 26, 2019

+- Fixed bug in latest firmware that prevented the module from detecting whether a key is encrypted.
+- Fixed bug in latest firmware that broke the nginx config when removing SSL certs.
+- Added requirement to remove SSL certs before uninstalling dependencies due to a change made by adde88 that swaps nginx/nginx-ssl as dependencies in the latest firmware.
+- Added requirement to install dependencies (nginx-ssl) before gaining the ability to install SSL certificates.
+- Updated the Status section help file.
diff --git a/Papers/includes/changelog/Version 2.0 b/Papers/includes/changelog/Version 2.0 new file mode 100644 index 0000000..8a0b13c --- /dev/null +++ b/Papers/includes/changelog/Version 2.0 @@ -0,0 +1,5 @@ +July 17, 2020

+- Fixed SSH key encryption to work with new OpenSSH format.
+- Added raw key contents to key view modal for easy copy/paste.
+- Merged encryption passphrase section with PKCS#12 export. The same password is used for both operations.
+- Added coreutils-base64 dependency to help determine if an SSH key is encrypted. diff --git a/Papers/includes/help/status.help b/Papers/includes/help/status.help index 5d08808..0921a85 100755 --- a/Papers/includes/help/status.help +++ b/Papers/includes/help/status.help @@ -3,8 +3,11 @@ Displays the keys currently being used by nginx on your Pineapple. These values

Dependencies
-The only dependencies for Papers are zip and unzip which are downloaded via opkg. They are used to pack, and unpack, certificate archives for download/upload. -

+zip and unzip - used to pack and unpack certificate archives for download/upload.
+coreutils-base64 - Used in the process to determine whether an SSH key is encrypted.
+nginx-ssl - Replaces the base nginx application.
+

Since nginx is replaced with nginx-ssl in the installation process you may need to refresh your browser after installation if the button doesn't change to 'Uninstall'

+

In order to uninstall dependencies you must first remove the SSL certificates from your Pineapple.

Remove SSL
This reverts the Pineapple back to its original web configuration and removes all traces of SSL from the nginx config. This does not affect the certificate store or any configuration in the Papers module. diff --git a/Papers/includes/nginx.conf b/Papers/includes/nginx.conf index 8297d61..8f8863d 100755 --- a/Papers/includes/nginx.conf +++ b/Papers/includes/nginx.conf @@ -1,13 +1,10 @@ user root root; worker_processes 1; - - events { worker_connections 1024; } - http { include mime.types; index index.php index.html index.htm; @@ -24,8 +21,8 @@ http { gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; server { - listen 80; # Port, make sure it is not in conflict with another http daemon. - server_name www; # Change this, reference -> http://nginx.org/en/docs/http/server_names.html + listen 80; # Port, make sure it is not in conflict with another http daemon. + server_name www; # Change this, reference -> http://nginx.org/en/docs/http/server_names.html error_page 404 =200 /index.php; error_log /dev/null; access_log /dev/null; @@ -51,16 +48,15 @@ http { if (-f $request_filename) { # Only throw it at PHP-FPM if the file exists (prevents some PHP exploits) - fastcgi_pass unix:/var/run/php5-fpm.sock; # The upstream determined above + fastcgi_pass unix:/var/run/php7-fpm.sock; # The upstream determined above } } error_page 404 =200 /index.php; } - server { - listen 1471; - server_name pineapple; # Change this, reference -> http://nginx.org/en/docs/http/server_names.html + listen 1471; # Port, make sure it is not in conflict with another http daemon. + server_name pineapple; # Change this, reference -> http://nginx.org/en/docs/http/server_names.html error_page 404 =200 /index.php; error_log /dev/null; access_log /dev/null; @@ -87,9 +83,8 @@ http { if (-f $request_filename) { # Only throw it at PHP-FPM if the file exists (prevents some PHP exploits) - fastcgi_pass unix:/var/run/php5-fpm.sock; # The upstream determined above + fastcgi_pass unix:/var/run/php7-fpm.sock; # The upstream determined above } } } } - diff --git a/Papers/includes/scripts/checkDepends.sh b/Papers/includes/scripts/checkDepends.sh index 85fcb95..593ec7f 100755 --- a/Papers/includes/scripts/checkDepends.sh +++ b/Papers/includes/scripts/checkDepends.sh @@ -2,14 +2,19 @@ testZip=$(opkg list-installed | grep -w 'zip') testUnzip=$(opkg list-installed | grep -w 'unzip') +testBase64=$(opkg list-installed | grep -w 'coreutils-base64') testNginxssl=$(opkg list-installed | grep -w 'nginx-ssl') -if [ -z "$testZip" -a -z "$testNginxssl" ]; then - echo "Not Installed"; +if [ -z "$testBase64" ]; then + echo "Not Installed"; else - if [ -z "$testUnzip" ]; then - echo "Not Installed"; - else - echo "Installed"; - fi + if [ -z "$testZip" -a -z "$testNginxssl" ]; then + echo "Not Installed"; + else + if [ -z "$testUnzip" ]; then + echo "Not Installed"; + else + echo "Installed"; + fi + fi fi diff --git a/Papers/includes/scripts/decryptRSAKeys.sh b/Papers/includes/scripts/decryptRSAKeys.sh new file mode 100644 index 0000000..70d9d21 --- /dev/null +++ b/Papers/includes/scripts/decryptRSAKeys.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# Author: sud0nick +# Date: Dec 2018 + +# Location of SSL keys +SSL_STORE="/pineapple/modules/Papers/includes/ssl/"; + +help() { + echo "Decryption script for OpenSSL keys"; + echo "Usage: ./decryptRSAKeys.sh "; + echo "Use './decryptRSAKeys.sh --examples' to see example commands"; + echo ''; + echo 'NOTE:'; + echo "Current SSL store is at $SSL_STORE"; + echo ''; + echo 'Parameters:'; + echo ''; + echo -e '\t-k:\tFile name of key to be decrypted'; + echo -e '\t-p:\tPassword to use to unlock the key'; + echo -e '\t-s:\tKey store to use other than default.' + echo -e '\t--help:\tDisplays this help info'; + echo ''; +} + +examples() { + echo ''; + echo 'Examples:'; + echo 'Decrypt private key:'; + echo './decryptRSAKeys.sh -k keyName -p password'; + echo ''; + echo ''; +} + +if [ "$#" -lt 1 ]; then + help; + exit; +fi + +KEYDIR=$SSL_STORE +read PASS + +while [ "$#" -gt 0 ]; do + + if [[ "$1" == "--examples" ]]; then + examples; + exit; + fi + if [[ "$1" == "--help" ]]; then + help; + exit; + fi + if [[ "$1" == "-k" ]]; then + KEY="$2"; + fi + if [[ "$1" == "-p" ]]; then + PASS="$2"; + fi + if [[ "$1" == "-s" ]]; then + KEYDIR="$2" + fi + + shift +done; + +# Generate a password on the private key +openssl rsa -in $KEYDIR/$KEY -out $KEYDIR/$KEY -passin pass:"$PASS" 2>&1 > /dev/null; +if [[ $? != 0 ]]; then + echo "Bad Password"; + exit; +fi + +echo "Complete" diff --git a/Papers/includes/scripts/decryptSSHKey.sh b/Papers/includes/scripts/decryptSSHKey.sh new file mode 100644 index 0000000..6078195 --- /dev/null +++ b/Papers/includes/scripts/decryptSSHKey.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# Author: sud0nick +# Date: July 2020 + +# Location of SSH keys +SSH_STORE="/pineapple/modules/Papers/includes/ssh/"; + +help() { + echo "Encrypt OpenSSH private keys"; + echo "Usage: ./encryptSSHKey.sh "; + echo ''; + echo 'NOTE:'; + echo "Current SSH store is at $SSH_STORE"; + echo ''; + echo 'Parameters:'; + echo ''; + echo -e '\t-k:\tFile name of key to be encrypted'; + echo ''; + echo 'Options:'; + echo ''; + echo -e "\t-s:\t\tUse an SSH store other than the default." + echo ''; +} + +if [ "$#" -lt 1 ]; then + help; + exit; +fi + +# Read password from pipe input +read PASS + +# Fetch arguments from command line +while [ "$#" -gt 0 ]; do + + if [[ "$1" == "-k" ]]; then + KEY="$2"; + fi + + if [[ "$1" == "-s" ]]; then + SSH_STORE="$2"; + fi + + shift +done; + +# Decrypt the key +ssh-keygen -o -p -P "$PASS" -N "" -q -f $SSH_STORE/$KEY 2>&1 > /dev/null + +if [[ "$?" == "0" ]]; then + echo "Complete" +else + echo "false" +fi \ No newline at end of file diff --git a/Papers/includes/scripts/encryptRSAKeys.sh b/Papers/includes/scripts/encryptRSAKeys.sh new file mode 100644 index 0000000..539028d --- /dev/null +++ b/Papers/includes/scripts/encryptRSAKeys.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +# Author: sud0nick +# Date: Jan 2016 + +# Location of SSL keys +SSL_STORE="/pineapple/modules/Papers/includes/ssl/"; + +help() { + echo "Encryption/Export script for OpenSSL certificates"; + echo "Usage: ./encryptRSAKeys.sh "; + echo "Use './encryptRSAKeys.sh --examples' to see example commands"; + echo ''; + echo 'NOTE:'; + echo "Current SSL store is at $SSL_STORE"; + echo ''; + echo 'Parameters:'; + echo ''; + echo -e '\t-k:\tFile name of key to be encrypted'; + echo ''; + echo 'Encryption Options:'; + echo ''; + echo -e '\t--encrypt:\tMust be supplied to encrypt keys'; + echo -e '\t-a:\t\tAlgorithm to use for key encryption (aes256, 3des, camellia256, etc)'; + echo ''; + echo 'Container Options:'; + echo ''; + echo -e '\t-c:\t\tContainer type (pkcs12, pkcs8)'; + echo -e '\t--pubkey:\tFile name of public key. Must be in selected key store.'; + echo ''; +} + +examples() { + echo ''; + echo 'Examples:'; + echo 'Encrypt private key:'; + echo 'echo $pass | ./encryptRSAKeys.sh -k keyName.key --encrypt -a aes256'; + echo ''; + echo 'Export keys to PKCS#12 container:'; + echo 'echo $pass | ./encryptRSAKeys.sh -k keyName.key -c pkcs12 -a aes256'; + echo ''; + echo 'Encrypt private key and export to PKCS#12 container using same algo and pass:'; + echo './encryptRSAKeys.sh -k keyName.key --encrypt -a aes256 -c pkcs12'; + echo ''; +} + +if [ "$#" -lt 1 ]; then + help; + exit; +fi + +ENCRYPT_KEYS=false; +KEYDIR=$SSL_STORE; +read PASS + +while [ "$#" -gt 0 ]; do + + if [[ "$1" == "--examples" ]]; then + examples; + exit; + fi + if [[ "$1" == "--encrypt" ]]; then + ENCRYPT_KEYS=true; + fi + if [[ "$1" == "-a" ]]; then + ALGO="$2"; + fi + if [[ "$1" == "-k" ]]; then + KEY="$2"; + fi + if [[ "$1" == "-c" ]]; then + CONTAINER="$2"; + fi + if [[ "$1" == "-s" ]]; then + KEYDIR="$2" + fi + if [[ "$1" == "--pubkey" ]]; then + PUBKEY="$2" + fi + + shift +done; + +# Generate a password on the private key +if [ $ENCRYPT_KEYS = true ]; then + openssl rsa -$ALGO -in $KEYDIR/$KEY -out $KEYDIR/$KEY -passout pass:"$PASS" 2>&1 > /dev/null; +fi + +# If a container type is present but not an algo or pass then use +# the same algo and pass from the private key +if [ -n "$CONTAINER" ]; then + + # Generate a container for the public and private keys + openssl $CONTAINER -$ALGO -export -nodes -out $KEYDIR/${KEY%%.*}.pfx -inkey $KEYDIR/$KEY -in $KEYDIR/$PUBKEY -passin pass:"$PASS" -passout pass:"$PASS" 2>&1 > /dev/null; +fi + +echo "Complete" diff --git a/Papers/includes/scripts/encryptSSHKey.sh b/Papers/includes/scripts/encryptSSHKey.sh new file mode 100644 index 0000000..b8772e5 --- /dev/null +++ b/Papers/includes/scripts/encryptSSHKey.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# Author: sud0nick +# Date: July 2020 + +# Location of SSH keys +SSH_STORE="/pineapple/modules/Papers/includes/ssh/"; + +help() { + echo "Encrypt OpenSSH private keys"; + echo "Usage: ./encryptSSHKey.sh "; + echo ''; + echo 'NOTE:'; + echo "Current SSH store is at $SSH_STORE"; + echo ''; + echo 'Parameters:'; + echo ''; + echo -e '\t-k:\tFile name of key to be encrypted'; + echo ''; + echo 'Options:'; + echo ''; + echo -e "\t-s:\t\tUse an SSH store other than the default." + echo ''; +} + +if [ "$#" -lt 1 ]; then + help; + exit; +fi + +# Read password from pipe input +read PASS + +# Fetch arguments from command line +while [ "$#" -gt 0 ]; do + + if [[ "$1" == "-k" ]]; then + KEY="$2"; + fi + + if [[ "$1" == "-s" ]]; then + SSH_STORE="$2"; + fi + + shift +done; + +# Encrypt the key +ssh-keygen -o -p -N "$PASS" -q -f $SSH_STORE/$KEY 2>&1 > /dev/null + +if [[ "$?" == "0" ]]; then + echo "Complete" +else + echo "false" +fi \ No newline at end of file diff --git a/Papers/includes/scripts/getCertInfo.sh b/Papers/includes/scripts/getCertInfo.sh index 7655968..a93d53e 100644 --- a/Papers/includes/scripts/getCertInfo.sh +++ b/Papers/includes/scripts/getCertInfo.sh @@ -4,14 +4,14 @@ # Date: Dec 2018 # Location of SSL keys -ssl_store="/pineapple/modules/Papers/includes/ssl/"; +SSL_STORE="/pineapple/modules/Papers/includes/ssl/"; help() { echo "Get certificate properties via OpenSSL"; echo "Usage: ./getCertInfo.sh "; echo ''; echo 'NOTE:'; - echo "Current SSL store is at $ssl_store"; + echo "Current SSL store is at $SSL_STORE"; echo ''; echo 'Parameters:'; echo ''; @@ -28,7 +28,7 @@ while [ "$#" -gt 0 ] do if [[ "$1" == "-k" ]]; then - KEY="$ssl_store$2.cer"; + KEY="$SSL_STORE/$2"; fi shift diff --git a/Papers/includes/scripts/installDepends.sh b/Papers/includes/scripts/installDepends.sh index 7ad7e59..760c73f 100755 --- a/Papers/includes/scripts/installDepends.sh +++ b/Papers/includes/scripts/installDepends.sh @@ -1,11 +1,9 @@ #!/bin/sh # Author: sud0nick & adde88 -# Date: 18.10.2019 +# Date: July 17, 2020 opkg update > /dev/null; -/etc/init.d/nginx stop > /dev/null; opkg remove nginx > /dev/null; -opkg install zip unzip nginx-ssl > /dev/null; -/etc/init.d/nginx restart > /dev/null; +opkg install zip unzip coreutils-base64 nginx-ssl > /dev/null; echo "Complete" diff --git a/Papers/includes/scripts/isEncrypted.sh b/Papers/includes/scripts/isEncrypted.sh new file mode 100644 index 0000000..efb8dbc --- /dev/null +++ b/Papers/includes/scripts/isEncrypted.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +SSL_STORE="/pineapple/modules/Papers/includes/ssl/"; +SSH_STORE="/pineapple/modules/Papers/includes/ssh/"; + +help() { + echo "Usage: ./testEncrypt.sh "; + echo ''; + echo 'NOTE:'; + echo "Current SSL store is at $SSL_STORE"; + echo "Current SSH store is at $SSH_STORE"; + echo ''; + echo 'Parameters:'; + echo ''; + echo -e '\t-k:\tName of key to test.'; + echo -e '\t-t:\tType of key: RSA|SSH.'; + echo -e "\t-s:\tKey store to use other than default." + echo ''; +} + +if [ "$#" -lt 2 ]; then + help; + exit; +fi + +KEYDIR='' + +# Get arguments +while [ "$#" -gt 0 ]; do + + if [[ "$1" == "-k" ]]; then + KEY="$2" + fi + if [[ "$1" == "-s" ]]; then + KEYDIR="$2" + fi + if [[ "$1" == "-t" ]]; then + TYPE="$2" + fi + + shift +done; + +# If the type selected is SSH... +if [[ "$TYPE" == "SSH" ]]; then + + if [[ "$KEYDIR" == "" ]]; then + KEYDIR=$SSH_STORE + fi + + # Pull the header from the key file + HEADER=$(sed '1d;$d' $KEYDIR/$KEY | base64 -d | head -c 32) + FORMAT=$(echo $HEADER | cut -c 0-14) + ENC=$(echo $HEADER | cut -c 16-19) + + # Ensure the key is in OpenSSH private key format + if [[ "$FORMAT" == "openssh-key-v1" ]]; then + + # Check if the key is encrypted + if [[ "$ENC" == "none" ]]; then + echo "false" + else + echo "true" + fi + + else + # This should never happen... + echo "Invalid OpenSSH key" + fi +else + if [[ "$TYPE" == "RSA" ]]; then + + if [[ "$KEYDIR" == "" ]]; then + KEYDIR=$SSL_STORE + fi + + # Check if the RSA key is encrypted + RES=$(openssl rsa -in $KEYDIR/$KEY -passin pass:_ 2>&1 > /dev/null) + + if [[ "$?" == "1" ]]; then + echo "true" + else + echo "false" + fi + else + # This should never happen when called from the module. + echo "Invalid option: $TYPE" + fi +fi diff --git a/Papers/includes/scripts/readKeys.sh b/Papers/includes/scripts/readKeys.sh deleted file mode 100755 index 5ea9f77..0000000 --- a/Papers/includes/scripts/readKeys.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Author: sud0nick -# Date: April 6, 2016 - -IN_SERVER_BLOCK=false; - -while read p; do - if [[ $IN_SERVER_BLOCK == false ]]; then - if [[ $p == *"listen"* && $p == *"1471"* ]]; then - IN_SERVER_BLOCK=true; - fi - else - if [[ $p == *".cer;" || $p == *".key;" ]]; then - echo $p | cut -d '/' -f 5 | tr -d ';'; - fi - fi -done < /etc/nginx/nginx.conf diff --git a/Papers/includes/scripts/removeDepends.sh b/Papers/includes/scripts/removeDepends.sh index ae8715f..df15dfc 100755 --- a/Papers/includes/scripts/removeDepends.sh +++ b/Papers/includes/scripts/removeDepends.sh @@ -1,8 +1,8 @@ #!/bin/sh # Author: sud0nick & adde88 -# Date: 18.10.2019 +# Date: July 17, 2020 -/etc/init.d/nginx stop > /dev/null; -opkg remove zip unzip nginx-ssl > /dev/null; +opkg update > /dev/null; +opkg remove zip unzip coreutils-base64 nginx-ssl > /dev/null; opkg install nginx > /dev/null; diff --git a/Papers/includes/scripts/testEncrypt.sh b/Papers/includes/scripts/testEncrypt.sh index bffb14f..e7c2964 100755 --- a/Papers/includes/scripts/testEncrypt.sh +++ b/Papers/includes/scripts/testEncrypt.sh @@ -32,4 +32,4 @@ fi shift done; -openssl rsa -in $KEYDIR$KEY -passin pass: | awk 'NR==0;' +openssl rsa -in $KEYDIR$KEY -passin pass:_ | awk 'NR==0;' diff --git a/Papers/js/module.js b/Papers/js/module.js index 588497b..3c717f3 100755 --- a/Papers/js/module.js +++ b/Papers/js/module.js @@ -18,8 +18,6 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $scope.certEncryptAlgo = "aes256"; $scope.certEncryptPassword = ""; $scope.certExportPKCS12 = false; - $scope.certEncryptPKCS12Algo = "aes256"; - $scope.certContainerPassword = ""; $scope.certificates = ""; $scope.SSLStatus = ['Loading...']; $scope.showCertThrobber = false; @@ -41,6 +39,14 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $scope.viewCert = ''; $scope.selectedCert = ''; $scope.loadingCert = false; + $scope.certsInstalled = true; + $scope.selectedSSHKeys = ''; + $scope.loadingSSHKeys = false; + $scope.sshPrivKey = ''; + $scope.sshPubKey = ''; + $scope.sslPrivKey = ''; + $scope.sslCert = ''; + $scope.checkDepends = (function(){ $api.request({ @@ -61,10 +67,10 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct module: 'Papers', action: 'installDepends' },function(response){ - $scope.checkDepends(); if (response.success === false) { alert("Failed to install dependencies. Make sure you are connected to the internet."); } + $scope.checkDepends(); $scope.dependsProcessing = false; }); }); @@ -151,14 +157,14 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct params['pkey_pass'] = $scope.certEncryptPassword; } if ($scope.certExportPKCS12 === true) { - params['container'] = "pkcs12"; - params['c_algo'] = $scope.certEncryptPKCS12Algo; - if (!$scope.certContainerPassword) { - alert("You must enter a password for the exported container!"); - return; - } - params['c_pass'] = $scope.certContainerPassword; - } + params['container'] = "pkcs12"; + params['algo'] = $scope.certEncryptAlgo; + if (!$scope.certEncryptPassword) { + alert("You must set a password for the private key!"); + return; + } + params['pkey_pass'] = $scope.certEncryptPassword; + } $scope.showBuildThrobber = true; $api.request({ @@ -173,7 +179,29 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $api.reloadNavbar(); }); } - }); + }); + + $scope.loadSSHKeys = (function(key){ + + $scope.loadingSSHKeys = true; + $scope.sshPrivKey = ''; + $scope.sshPubKey = ''; + $scope.selectedSSHKeys = key; + + $api.request({ + module: 'Papers', + action: 'loadSSHKeys', + keyName: key + },function(response){ + $scope.loadingSSHKeys = false; + if (response === false) { + $('#viewSSHKeys').modal('hide'); + return; + } + $scope.sshPrivKey = $sce.trustAsHtml(response.data.privkey); + $scope.sshPubKey = $sce.trustAsHtml(response.data.pubkey); + }); + }); $scope.loadCertProps = (function(cert){ @@ -191,7 +219,9 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $('#viewCert').modal('hide'); return; } - $scope.viewCert = response.data; + $scope.viewCert = response.data; + $scope.sslPrivKey = $sce.trustAsHtml($scope.viewCert.privkey); + $scope.sslCert = $sce.trustAsHtml($scope.viewCert.certificate); }); }); @@ -264,24 +294,22 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct }); $scope.clearForm = (function() { - $scope.certKeyType = "tls_ssl"; - $scope.certDaysValid = "365"; - $scope.certBitSize = "2048"; - $scope.certSigAlgo = "sha256"; - $scope.certSANs = ""; - $scope.certKeyName = ""; - $scope.certInfoCountry = ""; - $scope.certInfoState = ""; - $scope.certInfoLocality = ""; - $scope.certInfoOrganization = ""; - $scope.certInfoSection = ""; - $scope.certInfoCN = ""; - $scope.certEncryptKeysBool = false; - $scope.certEncryptAlgo = "aes256"; - $scope.certEncryptPassword = ""; - $scope.certExportPKCS12 = false; - $scope.certEncryptPKCS12Algo = "aes256"; - $scope.certContainerPassword = ""; + $scope.certKeyType = "tls_ssl"; + $scope.certDaysValid = "365"; + $scope.certBitSize = "2048"; + $scope.certSigAlgo = "sha256"; + $scope.certSANs = ""; + $scope.certKeyName = ""; + $scope.certInfoCountry = ""; + $scope.certInfoState = ""; + $scope.certInfoLocality = ""; + $scope.certInfoOrganization = ""; + $scope.certInfoSection = ""; + $scope.certInfoCN = ""; + $scope.certEncryptKeysBool = false; + $scope.certEncryptAlgo = "aes256"; + $scope.certEncryptPassword = ""; + $scope.certExportPKCS12 = false; }); $scope.loadCertificates = (function() { @@ -291,7 +319,7 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct },function(response){ if (response.success === true) { // Display certificate information - $scope.certificates = response.data; + $scope.certificates = response.data; } else { // Display error console.log("Failed to load certificates."); @@ -410,8 +438,10 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct action: 'getNginxSSLCerts' },function(response){ if (response.success === true) { + $scope.certsInstalled = true; $scope.SSLStatus = response.data; } else { + $scope.certsInstalled = false; $scope.SSLStatus = response.message; } }); @@ -467,10 +497,10 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct $scope.refresh = (function(){ $scope.getLogs(); - $scope.getChangeLogs(); $scope.clearDownloadArchive(); - $scope.getNginxSSLCerts(); - $scope.loadCertificates(); + $scope.getNginxSSLCerts(); + $scope.checkDepends(); + $scope.loadCertificates(); }); // Upload functions @@ -531,6 +561,6 @@ registerController('PapersController', ['$api', '$scope', '$sce', '$http', funct // Init $scope.init(); - $scope.checkDepends(); + $scope.getChangeLogs(); $scope.refresh(); }]) diff --git a/Papers/module.html b/Papers/module.html index a675dfd..42065e2 100755 --- a/Papers/module.html +++ b/Papers/module.html @@ -4,6 +4,10 @@ text-align: left; font-weight: normal; } + +textarea { + width: 100%; +} + + + + + +