Last active
December 17, 2017 22:07
-
-
Save timbru31/cc2a323b88a652e6c850 to your computer and use it in GitHub Desktop.
replace (root) password of squashfs from openELEC/LibreELEC // HowTo: https://dustpla.net/NyvMK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | |
# # | |
# Tested with openELEC v4.0.6, v4.2.1, v5.0.8 and v6.0.0 # | |
# Tested with LibreELEC v7.90.002 # | |
# # | |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | |
# | |
# author: Tim "xGhOsTkiLLeRx" Brust | |
# license: CC BY-NC-SA 4.0 | |
# version: 0.4.10 | |
# date: 01/06/2017 | |
# description: replace (root) password of squashfs from openELEC or LibreELEC | |
# usage: ./openELEC [password] [device] [hash] [user] | |
# dependencies: ((python && pip && passlib) || mkpasswd), squashfs-tools | |
# | |
# | |
# THIS SCRIPT COMES WITH ZERO WARRANTY! | |
# I'M NOT RESPONSIBLE FOR ANY POTENTIAL DATA LOSS! | |
# ALWAYS CREATE BACKUPS! | |
# Configure colors, if available. | |
if [ -x /usr/bin/tput ] && tput setaf 1 >/dev/null 2>&1 | |
then | |
reset="$(/usr/bin/tput sgr 0)" | |
green="$(/usr/bin/tput bold)$(/usr/bin/tput setaf 2)" | |
red="$(/usr/bin/tput bold)$(/usr/bin/tput setaf 1)" | |
yellow="$(/usr/bin/tput bold)$(/usr/bin/tput setaf 3)" | |
else | |
reset= | |
green= | |
red= | |
yellow= | |
fi | |
# Functions | |
cleanUp() { | |
rm -rf /openelec | |
} | |
message() { | |
printf "%b$reset\n" "$1" | |
} | |
unmount() { | |
if [ "$mac" = false ] | |
then | |
umount /openelec/flash | |
else | |
diskutil unmountDisk /openelec/flash | |
fi | |
} | |
checkCommand() { | |
if [ "$?" != 0 ] | |
then | |
message "${red}The last command did not succeed. Aborting..." | |
exit 2 | |
fi | |
} | |
cdFailed() { | |
message "${red}The cd command failed. Aborting..." | |
exit 1 | |
} | |
# root check | |
if [ "$(id -u)" != 0 ] | |
then | |
message "${red}Please run this script as root" | |
exit 1 | |
fi | |
# Check if we are running on Mac OS X | |
if [ "$(uname)" = "Darwin" ] | |
then | |
mac=true | |
else | |
mac=false | |
fi | |
# python check | |
if command -v "mkpasswd" > /dev/null 2>&1 | |
then | |
mkpasswd=true | |
else | |
if ! command -v "python" > /dev/null 2>&1 || ! command -v "pip" > /dev/null 2>&1 || [ -z "$(pip show passlib)" ] | |
then | |
message "${red}Please install the package $yellow'python'$red, $yellow'pip'$red and $yellow'passlib'$red from https://passlib.readthedocs.io/en/stable/" | |
exit 1 | |
else | |
mkpasswd=false | |
fi | |
fi | |
# mksquashfs check | |
if ! command -v "mksquashfs" > /dev/null 2>&1 | |
then | |
if [ "$mac" = true ] | |
then | |
message "${red}Please install the package $yellow'squashfs'$red from Homebrew" | |
else | |
message "${red}Please install the package $yellow'squashfs-tools'$red to use mksquashfs" | |
fi | |
exit 1 | |
fi | |
# Ask if we are using BerryBoot | |
message "${red}Are you using BerryBoot? (y/N) $reset" | |
read -r berryboot | |
case "$berryboot" in | |
No|no|N|n|"") | |
berryboot=false | |
;; | |
*) | |
berryboot=true | |
;; | |
esac | |
# Check for password | |
if [ -z "$1" ] | |
then | |
message "${yellow}No arguments given, please feed me input!\n" | |
message "Please enter the password you want to use: " | |
read -r passwd | |
else | |
passwd=$1 | |
fi | |
# Check for device | |
if [ -z "$2" ] | |
then | |
message "Please specify the openELEC/LibreELEC device (e.g. sdb1 or disk2s1 for macOS): " | |
read -r device | |
else | |
device=$2 | |
fi | |
# Check for hash | |
if [ ! -z "$3" ] | |
then | |
hash=$3 | |
else | |
hash="sha-512" | |
fi | |
# Check for user | |
if [ ! -z "$4" ] | |
then | |
user=$4 | |
else | |
user="root" | |
fi | |
# Warning, better safe than sorry | |
message "${red}This script comes with zero warranty! Always backup your files! I'm not responsible for any data loss or damage!" | |
# Summary | |
message "${yellow}Will use the following password: $passwd" | |
message "${yellow}Will use the following device: $device \n" | |
# Check for permission | |
message "Are these information correct? (y/N) " | |
read -r continue | |
case "$continue" in | |
No|no|N|n|"") | |
message "${red}Aborting!" | |
exit 1 | |
;; | |
*) | |
message "${green}Let's rock!\n" | |
;; | |
esac | |
# Ask if we should remove old folders | |
message "Should a backup file be created in /openelec_backup ? (Y/n) " | |
read -r backup | |
case "$backup" in | |
Yes|y|Y|yes|"") | |
message "${yellow}Will make a backup of the current image!" | |
backup=true | |
;; | |
*) | |
message "${green}Backup of current image will be skipped" | |
remove=false | |
;; | |
esac | |
if [ ! -d /openelec_backup ] | |
then | |
mkdir /openelec_backup | |
fi | |
# Ask if we should remove old folders | |
message "Should the /openelec folders be removed after updating the password? (y/N) " | |
read -r remove | |
case "$remove" in | |
No|no|N|n|"") | |
message "${yellow}Old folders won't be removed!" | |
remove=false | |
;; | |
*) | |
message "${green}Old folders will be removed" | |
remove=true | |
;; | |
esac | |
# Remove folder | |
cd / || cdFailed | |
if [ -d /openelec ] | |
then | |
message "${yellow}Found existing /openelec folder" | |
if [ "$remove" = true ] | |
then | |
message "${yellow}Removing..." | |
cleanUp | |
message "${green}Done" | |
else | |
message "${yellow}You specified that old folder should not be removed." | |
message "${yellow}Please do this yourself now. Aborting..." | |
exit 1 | |
fi | |
fi | |
# Setup | |
message "${yellow}Making folders..." | |
mkdir /openelec | |
cd /openelec || cdFailed | |
mkdir flash newsquashfs | |
message "${green}Done\n" | |
# mount and copy squashfs | |
message "${yellow}Mounting openELEC/LibreELEC squashfs system..." | |
if [ "$mac" = false ] | |
then | |
mount /dev/"$device" /openelec/flash | |
else | |
if [ "$berryboot" = true ] | |
then | |
mount -t fuse-ext2 /dev/"$device" /openelec/flash | |
else | |
diskutil unmountDisk /dev/"$device" | |
mount -t msdos /dev/"$device" /openelec/flash | |
fi | |
fi | |
checkCommand | |
# set default filename | |
filename="SYSTEM" | |
if [ "$berryboot" = true ] | |
then | |
message "Listing the available files:" | |
ls /openelec/flash/images/ | |
message "Please specify the openELEC/LibreELEC file: " | |
read -r filename | |
# See if file exists | |
if [ ! -f /openelec/flash/images/"$filename" ] | |
then | |
message "${red}Whoops, your $filename file is not there! Please check" | |
message "${red}Leaving $device mounted!" | |
exit 1 | |
fi | |
dest=/openelec/flash/images/"$filename" | |
unsquashfs -d /openelec/original /openelec/flash/images/"$filename" | |
else | |
# See if SYSTEM exists | |
if [ ! -f /openelec/flash/"$filename" ] | |
then | |
message "${red}Whoops, your $filename file is not there! Please check" | |
message "${red}Leaving $device mounted!" | |
exit 1 | |
fi | |
dest=/openelec/flash/"$filename" | |
unsquashfs -d /openelec/original /openelec/flash/"$filename" | |
fi | |
checkCommand | |
message "${green}Done\n" | |
# Make a backup | |
message "${yellow}Making a backup..." | |
if [ "$backup" = true ] | |
then | |
# Unique pseudo timestamp | |
date=$(date +"%Y%m%d-%T") | |
cp "$dest" /openelec_backup/"$date"-"$filename" | |
fi | |
checkCommand | |
message "${green}Done\n" | |
# Create new password | |
message "${yellow}Generating a new password (SHA512, random salt)..." | |
if [ "$mkpasswd" = false ] | |
then | |
message "${yellow}Using python for password generation" | |
shadow_password=$(python -c "from passlib.hash import sha512_crypt; print sha512_crypt.encrypt('$passwd')") | |
else | |
salt=$(head -30 /dev/urandom | env LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1) | |
shadow_password=$(mkpasswd "$passwd" --salt="$salt" --method="$hash") | |
fi | |
checkCommand | |
message "${green}Done\n" | |
# Backup | |
message "${yellow}Making backup from /etc/shadow and replace password..." | |
cd /openelec/original/etc || cdFailed | |
mv shadow shadow.bak | |
# Replace second string for given user (default is root) | |
awk -v pw="$shadow_password" -F: 'BEGIN{OFS=":"}/'$user'/{gsub(/.*/,pw,$2)}1' shadow.bak > shadow | |
checkCommand | |
message "${green}Done\n" | |
# sed way | |
#sed -i.bak "/^$user:/ s/:[^:]*/:$shadow_password" | |
# Make new squashfs and unmount | |
message "${yellow}Making new squashfs, this might take a bit..." | |
mksquashfs /openelec/original/ /openelec/newsquashfs/"$filename" | |
checkCommand | |
message "${green}Done\n" | |
# Copy updated squashfs back | |
message "${yellow}Copying updated file back..." | |
cp /openelec/newsquashfs/"$filename" "$dest" | |
message "${green}Done\n" | |
# Clean | |
message "${yellow}Unmounting openelec flash and original again..." | |
unmount | |
if [ "$remove" = true ] | |
then | |
message "${yellow}Removing openelec folder again..." | |
cleanUp | |
message "${green}Done\n\n" | |
fi | |
message "${green}Your password was successfully updated. Please (unmount and) remove your device" | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment