From af66cde5dd1bbd5462a281152ca7b87df9f50aa9 Mon Sep 17 00:00:00 2001 From: Andrey Arapov Date: Tue, 22 Sep 2015 10:27:25 +0200 Subject: [PATCH] Initial release --- ocdec.sh | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 ocdec.sh diff --git a/ocdec.sh b/ocdec.sh new file mode 100644 index 0000000..499b500 --- /dev/null +++ b/ocdec.sh @@ -0,0 +1,179 @@ +#!/usr/bin/env bash +#set -x +# Script: ocdec.sh +# Author: Andrey Arapov +# Email: andrey.arapov@nixaid.com +# +# Copyright (C) 2015 Andrey Arapov +# +# This program 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 3 of the License, or +# (at your option) any later version. +# +# This program 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 program. If not, see . +# +# +# +# Version: 1.0.0 - Initial release (22 September 2015) +# +# Tested with: +# - ownCloud 8.1.3 +# +# Limitations: +# - with some files (binary ones) it is running really slow +# +# +# === Usage notes +# +# Current directory should be the ownCloud data directory ! +# You can find it this way: +# grep -i datadirectory /srv/pathto/owncloud/config/config.php +# 'datadirectory' => '/srv/ownclouddata/', +# +# Make sure you have exported env. variable, e.g. +# export userLoginPass='s3cr3tpass' +# +# +# === Usage Example - Decrypt just 1 file +# +# export userLoginPass='s3cr3tpass' +# cd /srv/ownclouddata +# /tmp/ocdec.sh testuser1/files/secretfile.txt +# +# +# === Usage Example 2 - Decrypt Everything! +# +# 1. Create directory structure for decrypted data +# +# export USER=testuser1 +# export userLoginPass='s3cr3tpass' +# cd /srv/ownclouddata +# find ${USER}/files -type d |cut -sd / -f 2- |xargs -I@ mkdir -p "${USER}-DECRYPTED/@" +# +# +# 2. Decrypt the data +# +# cd /srv/ownclouddata +# find ${USER}/files -type f |xargs -I@ sh -c '/tmp/ocdec.sh "@" > "${USER}-DECRYPTED/$(echo @|cut -sd / -f 2-)"' +# +# Now all your data is decrypted & available at the ${USER}-DECRYPTED/ path ! +# +# + + +# Beginning of a script + +# +# Get User Private Key +# +# arg1: username +# arg2: password +function decryptUserPrivateKey() { + USER=$1 + userLoginPass=$2 + userPrivKeyPath="$USER/files_encryption/OC_DEFAULT_MODULE/$USER.privateKey" + if [ ! -r "$userPrivKeyPath" ]; then + echo "decryptUserPrivateKey():: File "$userPrivKeyPath" does not exist or not enough permissions! Aborting." + return 1 + fi + + encPrivKeyContentsALL="$(cat "$userPrivKeyPath")" + # Some non-GNU versions of sed do not support pattern matches. In that case use: perl -pne 's/(00iv00.*)?00iv00.*/$1 /' + encPrivKeyContentsBASE64="$( sed -r 's/^HBEGIN:.+:HEND-*//;s/(00iv00.*)?00iv00.*{16}xx/\1/' <(echo "${encPrivKeyContentsALL}") )" + plainPrivKeyIV="$( sed -r 's/^HBEGIN.*00iv00//;s/xx$//' <(echo "${encPrivKeyContentsALL}") )" + userLoginPassHEX=$(echo -n $userLoginPass |od -An -tx1 |tr -dc '[:xdigit:]') + plainPrivKeyIVHEX=$(echo -n $plainPrivKeyIV |od -An -tx1 |tr -dc '[:xdigit:]') + + echo "$( openssl enc -AES-256-CFB -d -nosalt -base64 -A -K $userLoginPassHEX -iv $plainPrivKeyIVHEX -in <(echo $encPrivKeyContentsBASE64) )" +} + +# +# Decrypt the file +# +# arg1: username +# arg2: path to an encrypted file (e.g. 'files/secretfile.txt' or 'files/Photos/Squirrel.jpg') +# arg3: user Private Key in plaintext +function decryptFile() { + USER="$1" + encFilePath="$2" + plainUserPrivKey="$3" + + if [ ! -r "${USER}/$encFilePath" ]; then + echo "decryptFile():: File "${USER}/$encFilePath" does not exist or not enough permissions! Aborting." + return 1 + fi + if ! grep -q "^HBEGIN:" "${USER}/$encFilePath"; then + echo "decryptFile():: File "${USER}/$encFilePath" does not seem to be encrypted! Aborting." + return 1 + fi + + # --- Get the FileKey --- + userFileShareKeyPath="${USER}/files_encryption/keys/${encFilePath}/OC_DEFAULT_MODULE/${USER}.shareKey" + encFileKeyPath="${USER}/files_encryption/keys/${encFilePath}/OC_DEFAULT_MODULE/fileKey" + + decUserFileShareKeyHEX="$( openssl rsautl -decrypt -inkey <(echo "$plainUserPrivKey") -in "$userFileShareKeyPath" |od -An -tx1 |tr -dc '[:xdigit:]' )" + if [ -z "$decUserFileShareKeyHEX" ];then echo "decryptFile():: The User Private Key is not good. Are you sure your ownCloud User Login password is correct?"; return 1; fi + + decFileKeyContent="$( openssl rc4 -d -in "$encFileKeyPath" -iv 0 -K $decUserFileShareKeyHEX )" + decFileKeyContentHEX="$( echo -n $decFileKeyContent |od -An -tx1 |tr -dc '[:xdigit:]' )" + # --- Get the FileKey --- + + # --- Decrypt the file --- + # TODO: to figure out how to speed-up the decryption process + encFileContentsALL="$(cat "${USER}/$encFilePath")" + encFileContentsNOHEAD=$(echo -n "$encFileContentsALL" | sed -r 's/^HBEGIN:.+:HEND-*//') + N=0 + for IV in $(echo -n "$encFileContentsNOHEAD" |grep -E -o '00iv00.{16}xx' |sed -r 's/^00iv00//;s/xx$//'); do + N=$[N+1] + encFileContentsBASE64=$(echo -n "$encFileContentsNOHEAD" |awk -F '00iv00................xx' -v N=$N '{print $N}') + plainFileIVHEX=$(echo -n "$IV" |od -An -tx1 |tr -dc '[:xdigit:]') + openssl enc -AES-256-CFB -d -nosalt -base64 -A -K $decFileKeyContentHEX -iv $plainFileIVHEX -in <(echo "$encFileContentsBASE64") + #php -r "echo openssl_decrypt('$encFileContentsBASE64', 'AES-256-CFB', '$decFileKeyContent', false, '$IV');" + done + # --- Decrypt the file --- +} + +# Get a username from the path (arg1) +USER="$(echo $1 |cut -sd / -f 1)" + +# Strip off the username from the path (arg1) +FILETD="$(echo $1 |cut -sd / -f 2-)" + +if [ ! -r "$USER" ]; then + echo "User directory cannot be found! Are you sure you are in ownCloud's data directory?" + exit 1 +fi + +if [ -z "$userLoginPass" ]; then + echo "Please set userLoginPass environment variable!" + exit 1 +fi + +if [ ! -r "$1" ]; then + echo "File specified $1 does not exist or not enough permissions to access it!" + exit 1 +fi + +# +# TODO: Add checks for available tools installed: openssl, sed, cat, od, tr, mawk +# + +# +# 1) Locate and decrypt User Private Key +# +# TODO: to decrypt User Private Key only once when running this script in a loop (decrypting multiple files) +plainUserPrivKey="$(decryptUserPrivateKey $USER $userLoginPass)"; + +# +# 2) Decrypt the shareKey, then the fileKey, then the file and output the plaintext +# +decryptFile $USER "$FILETD" "$plainUserPrivKey" + +# End of a script