[unencrypt] Decrypt-in-place

Anyone fancy some beta testing?

Here's the draft code for 'unencrypt.sh'

Code:
#!/bin/sh

#need to specify paths when running from cron
LSOF=/mod/bin/lsof
GREP=/mod/bin/busybox/grep
DIRNAME=/mod/bin/busybox/dirname
BASENAME=/mod/bin/busybox/basename
MV=/mod/bin/busybox/mv
WGET=/mod/bin/busybox/wget
HMT=/mod/bin/hmt
SQLITE3=/mod/bin/sqlite3
ECHO=/mod/bin/busybox/echo
RM=/mod/bin/busybox/rm
PS=/mod/bin/busybox/ps
WC=/mod/bin/busybox/wc
OPKG=/bin/opkg
EXPR=/mod/bin/busybox/expr

on_hangup ()
{
        $ECHO 'Interrupted by user'
        exit
}

trap on_hangup 2

# How do we deal with auto-unprotect - make it a prereq?

#Remove the trailing slash if there is one
targetpath=${1%/}

if [ ! -n "$targetpath" ]; then
        $ECHO "Humax HDR-T2 decryption utility"
        $ECHO "Version 0.0.1 - Danger Will Robinson!"
        $ECHO "Needs hmt 1.1.0 to work"
        $ECHO
        $ECHO "Gradually works its way through your videos and decrypts them"
        $ECHO
        $ECHO "Target path needed"
        exit
fi

#You need this or the for loop gets confused by spaces
IFS=$'\n'

# Stop the process running more than once at a time
# Warning - wc here returns one more line than it should so the count is 2 not 1
# Yes, I could have used pgrep, but it's one fewer dependancy
pscount=`$PS -w | $GREP "$0" | $GREP -v grep | grep -v '/bin/sh -c' | $WC -l`
$ECHO "pscount = $pscount"
if [ $pscount -gt 3 ]; then
        $ECHO "Unencrypt process already running - exiting"
        exit
fi

host='127.0.0.1'

#What about standby? Can this be tweaked on the fly?

# You really don't want to run this if you have HD content and you aren't running auto-unprotect
AP=`$OPKG list-installed | $GREP auto-unprotect`

if [ "$AP" = "" ]; then
        $ECHO "Auto-unprotect isn't running"
        exit
fi

#pwrdwn=`$SQLITE3 /var/lib/humaxtv/setup.db "Select itemvalue from tbl_menuconfig where itemName like 'AUTOMATIC_POWER_DOWN'"`

#$ECHO "Auto Power Off is set to: $pwrdwn"

#pwrstby=`$SQLITE3 /var/lib/humaxtv/setup.db "Select itemvalue from tbl_menuconfig where itemName like 'PWR_SAVING_ON_STANDBY'" `

#$ECHO "Power Saving In Standby is set to: $pwrstby"

#For each of the recorded programmes...
for line in `$SQLITE3 /mnt/hd2/dms_cds.db "select mediaID,folder from tblMedia"`
do
        sep=`$EXPR index "$line" \|` #There is a '|' separator between the fields
        mediaID="${line:0:$(($sep-1))}"
        filename="${line:$sep}"
        filename=${filename%.ts}
        dir=`$DIRNAME $filename`
        file=`$BASENAME $filename`

        # Only process files, not directories
        # and only directories that match the command line
        if [ "$filename" != "(NULL)" ] && [ `$EXPR match "/media/$dir" "$targetpath"` -gt 0 ]; then
                cd "/media/$dir"
                $ECHO "Processing \"$filename\", Media ID is $mediaID"
                url="http://$host:9000/web/media/$mediaID.TS"
                encrypted=`$HMT $file.hmt | $GREP '^Flags.*ODEncrypted'`

                if [ "$encrypted" ]; then

                        # Check that port 9000 is open and exit if not
                        # Needs to be implemented

                        #Get rid of any old files from a previous run that failed
                        if [ -f "$mediaID.TS" ]; then
                                $RM "$mediaID.TS"
                        fi

                        $ECHO "Getting $url"

                        $WGET $url

                        #The copy can fail - only copy and process if the file actually exists
                        if [ -f "$mediaID.TS" ]; then

                                # Need to check that the main file is not being modified
                                inuse=`$LSOF | $GREP "$file.ts"`
                                if [ "$inuse" == "" ]; then

                                        $MV $mediaID.TS $file.ts
                                        $HMT -encrypted $file.hmt
                                fi

                                # Exit after each successful decryption
                                exit
                        else
                                echo "$file is in use, skipping"
                        fi
                fi
        fi
done

Because of the risks of losing recordings, I've tried to predict a lot of potential issues and to build in the appropriate checks and balances. Certainly, when tested on a given subdirectory, it has successfully decrypted the contents, so it seems safe enough to be let loose on a wider audience.

The script needs a directory to work on and each time it is run, it will decrypt a file. It will not run 2 copies simultaneously, so trying to run it once every 15 minutes should be fine, even if decrypting HD programmes can take up to half an hour (or more).

To set this up, first take a modded HDR-T2 and install the cron, auto-unprotect and hmt utilities (most recent versions please) and save the script somewhere safe, like /mod/test.

I suggest that, for initial tests, you run it from the command line against a test directory, e.g.

Code:
sh /mod/test/unencrypt.sh /media/My\ Video/***your test directory here***/

But once you are confident that gerbils won't explode and that it won't rain marsupials on your firstborn (and that your precious collection of QVC highlights is safe), you can move to running it from cron.

Here's my crontab entry

Code:
0,15,30,45 * * * * /mod/test/unencrypt.sh /media/My\ Video/***your test directory here***/ > /mod/tmp/unencrypt.log 2>&1

Add the above line to '/mod/var/spool/cron/crontabs/root', giving it the name of the directory where you want to run your tests in the obvious place. Then, run the command

Code:
/mod/etc/init.d/S01crond restart

As the code says, "This is version 0.0.1 - Danger Will Robinson!" Please don't dabble unless you want to undertake a little risk, but hopefully the rewards will more than outweigh the risks.
 
But once you are confident that gerbils won't explode and that it won't rain marsupials on your firstborn (and that your precious collection of QVC highlights is safe)...
:D

I can't say I understand much of the last post, but I like the cut of your jib!
 
Is there any progress on a packaged automates decrypt in place? At the moment I'm having to do each file individually via the web interface
 
To package it up, I need to write a script that will update the crontab and restart the cron service, so that it can be safely tested on a smaller directory and not just set the script loose on ALL videos. I'm working on some different stuff at the moment but will get stuck in again later.
 
There's a package on its way to the repository, called "unencrypt"

Once it is installed, run unencryptsetup and give it the name of the directory that you want to experiment with, e.g.

Code:
unencryptsetup "Bob's Videos"

This will then update the cron table and schedule the program to run every 15 minutes. Every time it runs, it will check that there isn't already another job running and then decrypt the first encrypted file that it finds in the directory you specified, therefore gradually working its way through your files.

You can specify the directory with or without /mnt/hd2 or /media at the start, but the directory MUST be enclosed in quotes if it contains spaces or characters like ' - to be safe, just make sure that you always use quotes. If, after all the checks, the directory doesn't exist, the setup program will tell you there is a problem and exit, leaving the setup unchanged.

If you don't specify a directory, it will default to decrypting all of your recordings - this is beta code so I recommend that you record some sacrificial programmes, bung them in a directory and check that it works before taking that step.

Let me know how you get on!
 
will it stop when all files are done or will it keep checking indefinitely?

It'll keep checking indefinitely, but that's to account for new recordings. The program itself runs once every 15 minutes and just exits if there are no new recordings, so it shouldn't be a big overhead.
 
and if i tell it to check another directory, does it stop checking the original directory?

For the moment, the script will only process what is under the directory specified, or all recordings. I'd need to do some digging to work out how to send multiple directories to the script from the crontab.
 
For the moment, the script will only process what is under the directory specified, or all recordings. I'd need to do some digging to work out how to send multiple directories to the script from the crontab.
Multiple crontab entries would be fine..
 
Multiple crontab entries would be fine..

Yes, but the logic would mean that one directory would need to complete decryption before the other one started. In a lot of circumstances that would be OK, but I'm sure that it could be a problem for others.
 
is there a way of terminating this if we dont want it to run any more?

The simplest way to do it is to uninstall the package which will remove the crontab entries. If you want to stop it manually, then you need to edit the crontab (/mod/var/spool/cron/crontabs/root) to remove all references to /mod/sbin/unencrypt and then restart the cron services (/mod/etc/init.d/S01crontab restart).

If people want it, I could add a command line option to the setup script that wipes the crontab.
 
I have added a 'disable' option to unencryptsetup, as well as removing the line from cron when uninstalling.

Version 0.1.1 is now on its way to the repository.
 
Is the root of the folder path "My Video"? IE when I specify the folder, do I just need to specify the subfolder of "My Video" - like unencryptsetup "QI" rather than unencryptsetup "Media\My Video\QI"

Thanks.
 
You can specify either the full path, or the name of the folder under "My Video". If you don't specify a path then it will process everything in and under "My Video".
 
Back
Top