add nc-encrypt

Signed-off-by: nachoparker <nacho@ownyourbits.com>
This commit is contained in:
nachoparker 2021-10-22 18:02:49 -06:00
parent 532a6a8bb6
commit 7b73d1db5f
15 changed files with 731 additions and 37 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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)"

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"
}
]
}

View File

@ -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');

259
ncp-web/decrypt/CSS.css Normal file
View File

@ -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%;
}

81
ncp-web/decrypt/JS.js Normal file
View File

@ -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

92
ncp-web/decrypt/index.php Normal file
View File

@ -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>

View File

@ -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>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -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>