Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/nextcloudpi.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornachoparker <nacho@ownyourbits.com>2021-10-23 03:02:49 +0300
committernachoparker <nacho@ownyourbits.com>2021-10-28 00:46:13 +0300
commit7b73d1db5f0f4d2fcb4ba0957d6ac69954cfe35d (patch)
tree708b7d359755237c8ec26edc63d6a1a42aae4bd4
parent532a6a8bb6e994d3277b0d9a776df5d978ff1b6c (diff)
add nc-encryptv1.43.0
Signed-off-by: nachoparker <nacho@ownyourbits.com>
-rw-r--r--bin/ncp-provisioning.sh8
-rw-r--r--bin/ncp/CONFIG/nc-datadir.sh1
-rw-r--r--bin/ncp/SECURITY/nc-encrypt.sh107
-rw-r--r--bin/nextcloud-domain.sh6
-rw-r--r--build/docker/docker-compose.yml6
-rwxr-xr-xbuild/docker/nextcloud/020nextcloud8
-rw-r--r--changelog.md10
-rw-r--r--etc/library.sh25
-rw-r--r--etc/ncp-config.d/nc-encrypt.cfg22
-rw-r--r--ncp-web/activate/index.php30
-rw-r--r--ncp-web/decrypt/CSS.css259
-rw-r--r--ncp-web/decrypt/JS.js81
-rw-r--r--ncp-web/decrypt/index.php92
-rw-r--r--ncp-web/img/toggle-white.svg56
-rw-r--r--ncp-web/index.php57
15 files changed, 731 insertions, 37 deletions
diff --git a/bin/ncp-provisioning.sh b/bin/ncp-provisioning.sh
index cda1c70c..68b12df1 100644
--- a/bin/ncp-provisioning.sh
+++ b/bin/ncp-provisioning.sh
@@ -64,4 +64,12 @@ BKP="$( ls -1t /var/www/nextcloud-bkp_*.tar.gz 2>/dev/null | head -1 )"
ncp-restore "$BKP_NEW" && rm "$BKP_NEW"
}
+## Check for encrypted data and ask for password
+if needs_decrypt; then
+ echo "Detected encrypted instance"
+ a2dissite ncp nextcloud
+ a2ensite ncp-activation
+ apache2ctl -k graceful
+fi
+
exit 0
diff --git a/bin/ncp/CONFIG/nc-datadir.sh b/bin/ncp/CONFIG/nc-datadir.sh
index f99fdcfd..6948518a 100644
--- a/bin/ncp/CONFIG/nc-datadir.sh
+++ b/bin/ncp/CONFIG/nc-datadir.sh
@@ -100,6 +100,7 @@ configure()
# datadir
ncc config:system:set datadirectory --value="$DATADIR"
ncc config:system:set logfile --value="$DATADIR/nextcloud.log"
+ set_ncpcfg datadir "${datadir}"
restore_maintenance_mode
}
diff --git a/bin/ncp/SECURITY/nc-encrypt.sh b/bin/ncp/SECURITY/nc-encrypt.sh
new file mode 100644
index 00000000..33f8dea3
--- /dev/null
+++ b/bin/ncp/SECURITY/nc-encrypt.sh
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+# Data at rest encryption for NextCloudPi
+#
+# Copyleft 2021 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
+# GPL licensed (see end of file) * Use at your own risk!
+#
+# More at: nextcloudpi.com
+#
+
+is_active()
+{
+ mount | grep ncdata_enc | grep -q gocryptfs
+}
+
+install()
+{
+ apt_install gocryptfs
+}
+
+configure()
+{
+(
+ set -eu -o pipefail
+ local datadir parentdir encdir tmpdir
+ datadir="$(get_ncpcfg datadir)"
+ [[ "${datadir}" == "null" ]] && datadir=/var/www/nextcloud/data
+ parentdir="$(dirname "${datadir}")"
+ encdir="${parentdir}/ncdata_enc"
+ tmpdir="$(mktemp -u -p "${parentdir}" -t nc-data-crypt.XXXXXX))"
+
+ [[ "${ACTIVE}" != "yes" ]] && {
+ if ! is_active; then
+ echo "Data not currently encrypted"
+ return 0
+ fi
+ save_maintenance_mode
+ trap restore_maintenance_mode EXIT
+ echo "Decrypting data..."
+ mkdir "${tmpdir}"
+ chown www-data: "${tmpdir}"
+ pkill tail # prevents from umounting in docker
+ mv "${datadir}"/* "${datadir}"/.[!.]* "${tmpdir}"
+ fusermount -u "${datadir}"
+ rmdir "${datadir}"
+ mv "${tmpdir}" "${datadir}"
+ rm "${encdir}"/gocryptfs.*
+ rmdir "${encdir}"
+ echo "Data no longer encrypted"
+ return
+ }
+
+ if is_active; then
+ echo "Encrypted data already in use"
+ return
+ fi
+
+ # Just mount already encrypted data
+ if [[ -f "${encdir}"/gocryptfs.conf ]]; then
+ echo "${PASSWORD}" | gocryptfs -allow_other -q "${encdir}" "${datadir}" 2>&1 | sed /^Switch/d
+
+ # switch to the regular virtual hosts after we decrypt, so we can access NC and ncp-web
+ a2ensite ncp nextcloud
+ a2dissite ncp-activation
+ apache2ctl -k graceful
+
+ echo "Encrypted data now accessible"
+ return
+ fi
+ mkdir -p "${encdir}"
+ echo "${PASSWORD}" | gocryptfs -init -q "${encdir}"
+ save_maintenance_mode
+ trap restore_maintenance_mode EXIT
+
+ mv "${datadir}" "${tmpdir}"
+
+ mkdir "${datadir}"
+ echo "${PASSWORD}" | gocryptfs -allow_other -q "${encdir}" "${datadir}" 2>&1 | sed /^Switch/d
+
+ echo "Encrypting data..."
+ mv "${tmpdir}"/* "${tmpdir}"/.[!.]* "${datadir}"
+ chown -R www-data: "${datadir}"
+ rmdir "${tmpdir}"
+
+ set_ncpcfg datadir "${datadir}"
+
+ echo "Data is now encrypted"
+)
+}
+
+# License
+#
+# This script is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This script is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this script; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA 02111-1307 USA
+
diff --git a/bin/nextcloud-domain.sh b/bin/nextcloud-domain.sh
index 8d511160..ff50c1b5 100644
--- a/bin/nextcloud-domain.sh
+++ b/bin/nextcloud-domain.sh
@@ -2,6 +2,12 @@
source /usr/local/etc/library.sh
+# wait until user decrypts the instance first
+while :; do
+ needs_decrypt || break
+ sleep 1
+done
+
# wicd service finishes before completing DHCP
while :; do
local_ip="$(get_ip)"
diff --git a/build/docker/docker-compose.yml b/build/docker/docker-compose.yml
index 8e1f5e19..e1c94452 100644
--- a/build/docker/docker-compose.yml
+++ b/build/docker/docker-compose.yml
@@ -10,6 +10,12 @@ services:
volumes:
- ncdata:/data
- /etc/localtime:/etc/localtime:ro
+ # for nc-encrypt
+ devices:
+ - /dev/fuse:/dev/fuse
+ # for nc-encrypt # NOTE: take a look at this https://github.com/docker/for-linux/issues/321#issuecomment-677744121
+ cap_add:
+ - SYS_ADMIN
container_name: nextcloudpi
volumes:
diff --git a/build/docker/nextcloud/020nextcloud b/build/docker/nextcloud/020nextcloud
index 4826e035..257818ef 100755
--- a/build/docker/nextcloud/020nextcloud
+++ b/build/docker/nextcloud/020nextcloud
@@ -58,6 +58,14 @@ bash /usr/local/bin/ncp-provisioning.sh
echo "Starting notify_push daemon"
start_notify_push
+if needs_decrypt; then
+ echo "Waiting for user to decrypt instance"
+ while :; do
+ sleep 1
+ needs_decrypt || break
+ done
+fi
+
echo "Configuring Domain"
# Trusted Domain (local/public IP)
bash /usr/local/bin/nextcloud-domain.sh
diff --git a/changelog.md b/changelog.md
index a230b03d..e559f3ab 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,7 +1,13 @@
-[v1.42.3](https://github.com/nextcloud/nextcloudpi/commit/2d804cb) (2021-10-25) nextcloud-domain: fix variable collision
+[v1.43.0](https://github.com/nextcloud/nextcloudpi/commit/9bad41c) (2021-10-22) add nc-encrypt
-[v1.42.2](https://github.com/nextcloud/nextcloudpi/commit/9ff21bb) (2021-10-23) nc-backup-auto: ncc path
+[v1.42.5](https://github.com/nextcloud/nextcloudpi/commit/f0abbbc) (2021-10-27) letsencrypt: sync ncp and nc cert paths
+
+[v1.42.4 ](https://github.com/nextcloud/nextcloudpi/commit/f7e28c2) (2021-10-27) small trusted domains refactor
+
+[v1.42.3 ](https://github.com/nextcloud/nextcloudpi/commit/b1e7323) (2021-10-25) nextcloud-domain: fix variable collision
+
+[v1.42.2 ](https://github.com/nextcloud/nextcloudpi/commit/9ff21bb) (2021-10-23) nc-backup-auto: ncc path
[v1.42.1 ](https://github.com/nextcloud/nextcloudpi/commit/e11ce59) (2021-10-22) ncp-web: fix log download bug
diff --git a/etc/library.sh b/etc/library.sh
index 63858c35..be674f34 100644
--- a/etc/library.sh
+++ b/etc/library.sh
@@ -32,7 +32,7 @@ command -v jq &>/dev/null || {
PHPVER=$( jq -r .php_version < "$NCPCFG")
RELEASE=$( jq -r .release < "$NCPCFG")
}
-command -v ncc &>/dev/null && NCVER="$(ncc status | grep "version:" | awk '{ print $3 }')"
+command -v ncc &>/dev/null && NCVER="$(ncc status 2>/dev/null | grep "version:" | awk '{ print $3 }')"
function configure_app()
{
@@ -481,6 +481,29 @@ function restore_maintenance_mode()
fi
}
+function needs_decrypt()
+{
+ local active
+ active="$(find_app_param nc-encrypt ACTIVE)"
+ (! is_active_app nc-encrypt) && [[ "${active}" == "yes" ]]
+}
+
+function set_ncpcfg()
+{
+ local name="${1}"
+ local value="${2}"
+ local cfg
+ cfg="$(jq '.' "${NCPCFG}")"
+ cfg="$(jq ".${name} = \"${value}\"" <<<"${cfg}")"
+ echo "$cfg" > "${NCPCFG}"
+}
+
+function get_ncpcfg()
+{
+ local name="${1}"
+ jq -r ".${name}" < "${NCPCFG}"
+}
+
# License
#
# This script is free software; you can redistribute it and/or modify it
diff --git a/etc/ncp-config.d/nc-encrypt.cfg b/etc/ncp-config.d/nc-encrypt.cfg
new file mode 100644
index 00000000..a86e7655
--- /dev/null
+++ b/etc/ncp-config.d/nc-encrypt.cfg
@@ -0,0 +1,22 @@
+{
+ "id": "nc-encrypt",
+ "name": "Nc-encrypt",
+ "title": "nc-encrypt",
+ "description": "Data at rest encryption for NCP",
+ "info": "The encryption password will be needed after every reboot.\nThis will increase CPU usage.",
+ "infotitle": "",
+ "params": [
+ {
+ "id": "ACTIVE",
+ "name": "Active",
+ "value": "no",
+ "type": "bool"
+ },
+ {
+ "id": "PASSWORD",
+ "name": "Password",
+ "value": "ownyourbits",
+ "type": "password"
+ }
+ ]
+}
diff --git a/ncp-web/activate/index.php b/ncp-web/activate/index.php
index 5c94a1a3..b983b8d7 100644
--- a/ncp-web/activate/index.php
+++ b/ncp-web/activate/index.php
@@ -1,11 +1,25 @@
<?php
-// disallow once activated
-exec("a2query -s ncp-activation", $output, $ret);
-if ($ret != 0) {
- http_response_code(404);
- exit();
-}
-session_start();
+ // disallow once activated
+ exec("a2query -s ncp-activation", $output, $ret);
+ if ($ret != 0) {
+ http_response_code(404);
+ exit();
+ }
+ ini_set('session.cookie_httponly', 1);
+ if (isset($_SERVER['HTTPS']))
+ ini_set('session.cookie_secure', 1);
+ session_start();
+
+ // security headers
+ header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; object-src 'self';");
+ header("X-XSS-Protection: 1; mode=block");
+ header("X-Content-Type-Options: nosniff");
+ header("X-Robots-Tag: none");
+ header("X-Permitted-Cross-Domain-Policies: none");
+ header("X-Frame-Options: DENY");
+ header("Cache-Control: no-cache");
+ header('Pragma: no-cache');
+ header('Expires: -1');
?>
<!DOCTYPE html>
<html class="ng-csp" data-placeholder-focus="false" lang="en">
@@ -63,7 +77,7 @@ HTML;
</div>
<footer role="contentinfo">
<p class="info">
- <a href="https://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/" target="_blank" rel="noreferrer noopener">NextCloudPi</a> – Keep your data close</p>
+ <a href="https://nextcloudpi.com" target="_blank" rel="noreferrer noopener">NextCloudPi</a> – Keep your data close</p>
</footer>
<?php
include('../csrf.php');
diff --git a/ncp-web/decrypt/CSS.css b/ncp-web/decrypt/CSS.css
new file mode 100644
index 00000000..a687c9be
--- /dev/null
+++ b/ncp-web/decrypt/CSS.css
@@ -0,0 +1,259 @@
+/*
+ * NextCloudPi Web Panel style sheets. Based on official Nextcloud 12 datasheets
+ *
+ * Copyleft 2018 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
+ * GPL licensed (see end of file) * Use at your own risk!
+ *
+ * More at https://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/
+*/
+
+
+html,body {
+ height:100%
+}
+article,aside,dialog,figure,footer,header,hgroup,nav,section {
+ display:block
+}
+body {
+ text-align: center;
+ line-height:1.5
+}
+a {
+ border:0;
+ color:#fff;
+ text-decoration:none;
+ cursor:pointer
+}
+a * {
+ cursor:pointer
+}
+select,.button span,label {
+ cursor:pointer
+}
+body {
+ background-image: url(../img/background.png);
+ background-color:#0082c9;
+ font-weight:400;
+ line-height:1.6em;
+ font-family:'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif;
+ color:#fff;
+ height:auto
+}
+#nojavascript {
+ position:fixed;
+ top:0;
+ bottom:0;
+ height:100%;
+ width:100%;
+ z-index:9000;
+ text-align:center;
+ background-color:rgba(0, 0, 0, 0.5);
+ color:#fff;
+ line-height:125%;
+ font-size:24px
+}
+#nojavascript div {
+ display:block;
+ position:relative;
+ width:50%;
+ top:35%;
+ margin:0px auto
+}
+#nojavascript a {
+ color:#fff;
+ border-bottom:2px dotted #fff
+}
+#nojavascript a:hover,#nojavascript a:focus {
+ color:#dbdbdb
+}
+::-webkit-scrollbar {
+ width:5px
+}
+::-webkit-scrollbar-track-piece {
+ background-color:transparent
+}
+::-webkit-scrollbar-thumb {
+ background:#dbdbdb;
+ border-radius:3px
+}
+select,button,input,textarea {
+ width: 3em;
+ min-height:32px;
+ box-sizing:border-box;
+ text-align: center;
+}
+select,button,.button,input:not([type='range']),textarea,#quota,.pager li a {
+ margin:3px 3px 3px 0;
+ padding:7px 6px;
+ font-size:13px;
+ background-color:#fff;
+ color:#545454;
+ border:1px solid #dbdbdb;
+ outline:none;
+ border-radius:3px;
+}
+select:not(:disabled):not(.primary),button:not(:disabled):not(.primary),.button:not(:disabled):not(.primary),input:not([type='range']):not(:disabled):not(.primary),textarea:not(:disabled):not(.primary),#quota:not(:disabled):not(.primary),.pager li a:not(:disabled):not(.primary) {
+}
+select:not(:disabled):not(.primary):not(#quota):hover,button:not(:disabled):not(.primary):not(#quota):hover,.button:not(:disabled):not(.primary):not(#quota):hover,input:not([type='range']):not(:disabled):not(.primary):not(#quota):hover,textarea:not(:disabled):not(.primary):not(#quota):hover,#quota:not(:disabled):not(.primary):not(#quota):hover,.pager li a:not(:disabled):not(.primary):not(#quota):hover,select:not(:disabled):not(.primary):focus,button:not(:disabled):not(.primary):focus,.button:not(:disabled):not(.primary):focus,input:not([type='range']):not(:disabled):not(.primary):focus,textarea:not(:disabled):not(.primary):focus,#quota:not(:disabled):not(.primary):focus,.pager li a:not(:disabled):not(.primary):focus,select:not(:disabled):not(.primary).active,button:not(:disabled):not(.primary).active,.button:not(:disabled):not(.primary).active,input:not([type='range']):not(:disabled):not(.primary).active,textarea:not(:disabled):not(.primary).active,#quota:not(:disabled):not(.primary).active,.pager li a:not(:disabled):not(.primary).active {
+ border-color:#0082c9;
+ outline:none
+}
+select:not(:disabled):not(.primary):active,button:not(:disabled):not(.primary):active,.button:not(:disabled):not(.primary):active,input:not([type='range']):not(:disabled):not(.primary):active,textarea:not(:disabled):not(.primary):active,#quota:not(:disabled):not(.primary):active,.pager li a:not(:disabled):not(.primary):active {
+ outline:none;
+ background-color:#fff
+}
+select:disabled,button:disabled,.button:disabled,input:not([type='range']):disabled,textarea:disabled,#quota:disabled,.pager li a:disabled {
+ background-color:#ebebeb;
+ color:rgba(0, 0, 0, 0.4);
+ cursor:default;
+ opacity:0.5
+}
+select.primary,button.primary,.button.primary,input:not([type='range']).primary,textarea.primary,#quota.primary,.pager li a.primary {
+ border:1px solid #0082c9;
+ background-color:rgba(0, 130, 201, .7);
+ color:#fff;
+ cursor:pointer
+}
+select.primary:not(:disabled):hover,button.primary:not(:disabled):hover,.button.primary:not(:disabled):hover,input:not([type='range']).primary:not(:disabled):hover,textarea.primary:not(:disabled):hover,#quota.primary:not(:disabled):hover,.pager li a.primary:not(:disabled):hover,select.primary:not(:disabled):focus,button.primary:not(:disabled):focus,.button.primary:not(:disabled):focus,input:not([type='range']).primary:not(:disabled):focus,textarea.primary:not(:disabled):focus,#quota.primary:not(:disabled):focus,.pager li a.primary:not(:disabled):focus {
+ background-color:rgba(0, 130, 201, .85)
+}
+select.primary:not(:disabled):active,button.primary:not(:disabled):active,.button.primary:not(:disabled):active,input:not([type='range']).primary:not(:disabled):active,textarea.primary:not(:disabled):active,#quota.primary:not(:disabled):active,.pager li a.primary:not(:disabled):active {
+ background-color:rgba(0, 130, 201, .7)
+}
+select.primary:disabled,button.primary:disabled,.button.primary:disabled,input:not([type='range']).primary:disabled,textarea.primary:disabled,#quota.primary:disabled,.pager li a.primary:disabled {
+ background-color:rgba(0, 130, 201, .7);
+ color:#bababa
+}
+input {
+}
+input:not([type='radio']):not([type='checkbox']):not([type='range']):not([type='submit']):not([type='button']):not([type='reset']):not([type='color']):not([type='file']):not([type='image']) {
+ -webkit-appearance:textfield;
+ -moz-appearance:textfield
+}
+select,button,.button,input[type='button'],input[type='submit'],input[type='reset'] {
+ padding:6px 12px;
+ width:auto;
+ min-height:34px;
+ cursor:pointer;
+ box-sizing:border-box;
+ background-color:#f7f7f7
+}
+button,.button,input[type='button'],input[type='submit'],input[type='reset'] {
+ font-weight:bold;
+}
+button::-moz-focus-inner,.button::-moz-focus-inner,input[type='button']::-moz-focus-inner,input[type='submit']::-moz-focus-inner,input[type='reset']::-moz-focus-inner {
+ border:0
+}
+button,.button {
+}
+button > span[class^='icon-'],.button > span[class^='icon-'],button > span[class*=' icon-'],.button > span[class*=' icon-'] {
+ display:inline-block;
+ vertical-align:text-bottom;
+ opacity:0.5
+}
+textarea {
+ color:#545454;
+ cursor:text;
+ font-family:inherit;
+ height:auto
+}
+textarea:not(:disabled):active,textarea:not(:disabled):hover,textarea:not(:disabled):focus {
+ border-color:#dbdbdb !important;
+ background-color:#fff !important
+}
+select {
+ -webkit-appearance:none;
+ -moz-appearance:none;
+ appearance:none;
+ background:url('../../../core/css/../img/actions/triangle-s.svg') no-repeat right 4px center;
+ background-color:inherit;
+ outline:0;
+ padding-right:24px !important
+}
+button img,.button img {
+ cursor:pointer
+}
+input[type='checkbox'].radio,input[type='radio'].radio,input[type='checkbox'].checkbox,input[type='radio'].checkbox {
+ position:absolute;
+ left:-10000px;
+ top:auto;
+ width:1px;
+ height:1px;
+ overflow:hidden
+}
+#header {
+ color: white;
+}
+h2 {
+ font-size:20px;
+ font-weight:300;
+ margin-bottom:12px;
+ line-height:140%
+}
+h3 {
+ font-size:15px;
+ font-weight:300;
+ margin:12px 0
+}
+em {
+ font-style:normal;
+ -ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=50)';
+ opacity:0.5
+}
+dl {
+ padding:12px 0
+}
+dt,dd {
+ display:inline-block;
+ padding:12px;
+ padding-left:0
+}
+dt {
+ width:130px;
+ white-space:nowrap;
+ text-align:right
+}
+kbd {
+ padding:4px 10px;
+ border:1px solid #ccc;
+ box-shadow:0 1px 0 rgba(0, 0, 0, .2);
+ border-radius:3px;
+ display:inline-block;
+ white-space:nowrap
+}
+
+hr { border: solid 1px white; }
+
+#ncp-logo { margin-top: 24px; }
+
+#loading-gif { display: none; }
+
+#ncp-pwd,#nc-pwd{ width:30em; }
+
+img { vertical-align: middle; }
+
+.info {
+ text-shadow: 0 0 2px rgba(0, 0, 0, .4);
+ font-size: 80%;
+}
+
+.info a {
+ font-weight: 600;
+}
+
+.table-wrapper {
+ width: 80%;
+ max-width: 450px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.table-wrapper table {
+ width: 100%;
+ max-width: 450px;
+ margin: 0 auto;
+}
+
+.table-wrapper input[type='text'], .table-wrapper input[type='password'] {
+ width: 90%;
+}
diff --git a/ncp-web/decrypt/JS.js b/ncp-web/decrypt/JS.js
new file mode 100644
index 00000000..91d6149c
--- /dev/null
+++ b/ncp-web/decrypt/JS.js
@@ -0,0 +1,81 @@
+///
+// NextCloudPi Web Panel javascript library
+//
+// Copyleft 2017 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
+// GPL licensed (see end of file) * Use at your own risk!
+//
+// More at https://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/
+///
+
+var MINI = require('minified');
+var $ = MINI.$, $$ = MINI.$$, EE = MINI.EE;
+
+function errorMsg()
+{
+ $('#error-box').fill("Something went wrong. Try refreshing the page");
+}
+
+function decrypt_ok_cb(result)
+{
+ var ret = $.parseJSON(result);
+ $('#loading-gif').hide();
+ if ( ret.token )
+ $('#csrf-token').set( { value: ret.token } );
+ if ( ret.ret == '0' ) {
+ $('#error-box').fill("OK");
+ var url = window.location.protocol + '//' + window.location.hostname;
+ window.location.replace( url );
+ } else {
+ $('#error-box').fill("Password error");
+ $('#decrypt-btn').show();
+ }
+}
+
+function decrypt()
+{
+ // request
+ $.request('post', '../ncp-launcher.php', { action: 'launch',
+ ref : 'nc-encrypt',
+ config: '{ "ACTIVE": "yes", "PASSWORD":"' + $('#encryption-pass').get('.value') + '" }',
+ csrf_token: $('#csrf-token').get('.value') }
+ ).then(decrypt_ok_cb).error(errorMsg);
+}
+
+// Show password button
+$( '.pwd-btn' ).on('click', function(e)
+ {
+ var input = this.trav('previousSibling', 1);
+ if ( input.get('.type') == 'password' )
+ input.set('.type', 'text');
+ else if ( input.get('.type') == 'text' )
+ input.set('.type', 'password');
+ });
+
+$(function()
+{
+ $('#decrypt-btn').on('click', function(e)
+ {
+ $('#decrypt-btn').hide();
+ $('#loading-gif').set( { $display: 'inline' } );
+ decrypt();
+ } );
+
+ $$('#encryption-pass').focus();
+} );
+
+// License
+//
+// This script is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This script is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this script; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
diff --git a/ncp-web/decrypt/index.php b/ncp-web/decrypt/index.php
new file mode 100644
index 00000000..795b1287
--- /dev/null
+++ b/ncp-web/decrypt/index.php
@@ -0,0 +1,92 @@
+<?php
+ // disallow once unlocked
+ exec("a2query -s ncp-activation", $output, $ret);
+ if ($ret != 0) {
+ http_response_code(404);
+ exit();
+ }
+ ini_set('session.cookie_httponly', 1);
+ if (isset($_SERVER['HTTPS']))
+ ini_set('session.cookie_secure', 1);
+ session_start();
+
+ // security headers
+ header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; object-src 'self';");
+ header("X-XSS-Protection: 1; mode=block");
+ header("X-Content-Type-Options: nosniff");
+ header("X-Robots-Tag: none");
+ header("X-Permitted-Cross-Domain-Policies: none");
+ header("X-Frame-Options: DENY");
+ header("Cache-Control: no-cache");
+ header('Pragma: no-cache');
+ header('Expires: -1');
+?>
+<!DOCTYPE html>
+<html class="ng-csp" data-placeholder-focus="false" lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <meta charset="utf-8">
+ <title> Unlock NextCloudPi </title>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="referrer" content="never">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
+ <meta http-equiv="cache-control" content="no-cache">
+ <meta http-equiv="pragma" content="no-cache">
+ <link rel="icon" type="image/png" href="../img/favicon.png"/>
+ <link rel="stylesheet" href="CSS.css">
+</head>
+<body id="body-login">
+ <noscript>
+ <div id="nojavascript">
+ <div>
+ This application requires JavaScript for correct operation. Please <a href="https://www.enable-javascript.com/" target="_blank" rel="noreferrer noopener">enable JavaScript</a> and reload the page. </div>
+ </div>
+ </noscript>
+ <div class="wrapper">
+ <div class="v-align">
+ <header role="banner">
+ <div id="header">
+ <img id="ncp-logo" src="../img/ncp-logo.svg">
+<?php
+ echo <<<HTML
+ <h1>NextCloudPi</h1>
+ <p>Encrypted instance</p>
+
+ <div id="decrypt-config-box" class="content-box table-wrapper">
+ <form>
+ <table><tbody>
+ <tr>
+ <td>
+ <input type="password" id="encryption-pass" name="Password" class="directory" default="" placeholder="password" size="40">
+ &nbsp;
+ <img class="pwd-btn" title="show password" src="../img/toggle-white.svg">
+ </td>
+ </tr>
+ </tbody></table>
+
+ <div class="config-button-wrapper">
+ <button id="decrypt-btn" type="submit" class="config-button">Decrypt</button>
+ <img id="loading-gif" src="../img/loading-small.gif">
+ <div class="circle-retstatus icon-red-circle"></div>
+ <div id="error-box"></div>
+ </div>
+ </form>
+ </div>
+HTML;
+?>
+ </div>
+ </header>
+ </div>
+ </div>
+ <footer role="contentinfo">
+ <p class="info">
+ <a href="https://nextcloudpi.com" target="_blank" rel="noreferrer noopener">NextCloudPi</a> – Keep your data close</p>
+ </footer>
+ <?php
+ include('../csrf.php');
+ echo '<input type="hidden" id="csrf-token" name="csrf-token" value="' . getCSRFToken() . '"/>';
+ ?>
+ <script src="../js/minified.js"></script>
+ <script src="JS.js"></script>
+</body>
+</html>
diff --git a/ncp-web/img/toggle-white.svg b/ncp-web/img/toggle-white.svg
new file mode 100644
index 00000000..dbfee9a5
--- /dev/null
+++ b/ncp-web/img/toggle-white.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ viewbox="0 0 16 16"
+ width="16"
+ height="16"
+ id="svg4"
+ sodipodi:docname="toggle-white.svg"
+ inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1080"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="14.75"
+ inkscape:cx="8.1016949"
+ inkscape:cy="7.9661017"
+ inkscape:window-x="1440"
+ inkscape:window-y="1087"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4"
+ inkscape:pagecheckerboard="0" />
+ <path
+ opacity="0.5"
+ d="M8 3C4.89 3 2.073 4.72 0 7.5 2.073 10.28 4.89 12 8 12c3.11 0 5.927-1.72 8-4.5C13.927 4.72 11.11 3 8 3zm0 1.5a3 3 0 1 1 0 6 3 3 0 0 1 0-6zM8 6a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z"
+ id="path2"
+ style="fill:#ffffff;fill-opacity:1;opacity:1" />
+</svg>
diff --git a/ncp-web/index.php b/ncp-web/index.php
index 361f4210..21ce5475 100644
--- a/ncp-web/index.php
+++ b/ncp-web/index.php
@@ -8,15 +8,45 @@
More at https://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/
**/
+ob_start();
+
+// check for encrypted data to present unlock dialog
+exec("bash -c 'source /usr/local/etc/library.sh; needs_decrypt'", $output, $ret);
+if ($ret == 0) {
+ header("Location: decrypt");
+ exit();
+}
// redirect to activation first time
-ob_start();
exec("a2query -s ncp-activation", $output, $ret);
if ($ret == 0) {
header("Location: activate");
exit();
}
+ini_set('session.cookie_httponly', 1);
+if (isset($_SERVER['HTTPS']))
+ ini_set('session.cookie_secure', 1);
+session_start();
+
+include('elements.php');
+$modules_path = '/usr/local/etc/ncp-config.d/';
+$l10nDir = "l10n";
+
+// security headers
+header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; object-src 'self';");
+header("X-XSS-Protection: 1; mode=block");
+header("X-Content-Type-Options: nosniff");
+header("X-Robots-Tag: none");
+header("X-Permitted-Cross-Domain-Policies: none");
+header("X-Frame-Options: DENY");
+header("Cache-Control: no-cache");
+header('Pragma: no-cache');
+header('Expires: -1');
+
+// HTTP2 push headers
+header("Link: </js/minified.js>; rel=preload; as=script;,</js/ncp.js>; rel=preload; as=script;,</css/ncp.css>; rel=preload; as=style;,</img/ncp-logo.svg>; rel=preload; as=image;, </img/loading-small.gif>; rel=preload; as=image;, rel=preconnect href=ncp-launcher.php;");
+
?>
<!DOCTYPE html>
@@ -28,31 +58,6 @@ if ($ret == 0) {
<meta name="referrer" content="never">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
<meta name="mobile-web-app-capable" content="yes">
-<?php
- ini_set('session.cookie_httponly', 1);
- if (isset($_SERVER['HTTPS']))
- ini_set('session.cookie_secure', 1);
- session_start();
-
- include('elements.php');
- $modules_path = '/usr/local/etc/ncp-config.d/';
- $l10nDir = "l10n";
-
- // security headers
- header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; object-src 'self';");
- header("X-XSS-Protection: 1; mode=block");
- header("X-Content-Type-Options: nosniff");
- header("X-Robots-Tag: none");
- header("X-Permitted-Cross-Domain-Policies: none");
- header("X-Frame-Options: DENY");
- header("Cache-Control: no-cache");
- header('Pragma: no-cache');
- header('Expires: -1');
-
- // HTTP2 push headers
- header("Link: </js/minified.js>; rel=preload; as=script;,</js/ncp.js>; rel=preload; as=script;,</css/ncp.css>; rel=preload; as=style;,</img/ncp-logo.svg>; rel=preload; as=image;, </img/loading-small.gif>; rel=preload; as=image;, rel=preconnect href=ncp-launcher.php;");
-
- ?>
<link rel="icon" type="image/png" href="img/favicon.png"/>
<link rel="stylesheet" href="css/ncp.css">
</head>