Last active
March 25, 2020 00:14
-
-
Save djfdyuruiry/0b0795e6b61bd9cf6567ea64e32bfc4a to your computer and use it in GitHub Desktop.
Get a password hash that you can store in the Transmission Daemon settings JSON file: `./hash-transmission-daemon-password.py --help` - supports reading password from a file, stdin and outputting hash to a file
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
#! /usr/bin/env python3 | |
from argparse import ArgumentParser | |
from getpass import getpass | |
from hashlib import sha1 | |
from itertools import chain | |
from random import choices | |
from sys import stdin | |
SALT_LENGTH = 8 | |
def characterRange(lower, upper): | |
for c in range(ord(lower), ord(upper) + 1): | |
yield chr(c) | |
def hashPassword(password, salt): | |
hash = sha1() | |
hash.update(password.encode("utf-8")) | |
hash.update(salt.encode("utf-8")) | |
tranmissionHash = hash.hexdigest() | |
return tranmissionHash | |
def generateSalt(saltCharacters): | |
return "".join(choices(saltCharacters, k = SALT_LENGTH)) | |
def readPassword(beQuiet, readFromStdIn, passwordFilePath): | |
if passwordFilePath: | |
# read from file | |
with open(passwordFilePath) as inFile: | |
return inFile.readline() | |
if readFromStdIn: | |
# read from stdin | |
return stdin.readline() | |
passwordPrompt = "Transmission Password: " | |
if beQuiet: | |
passwordPrompt = "" | |
# read from user input | |
return getpass(prompt = passwordPrompt) | |
def hashTransmissionPassword(beQuiet, readFromStdIn, passwordFilePath, outputFilePath): | |
saltCharacters = list( | |
chain( | |
characterRange("0", "9"), | |
characterRange("a", "z"), | |
characterRange("A", "Z"), | |
[ ".", "/" ] | |
) | |
) | |
password = readPassword(beQuiet, readFromStdIn, passwordFilePath) | |
salt = generateSalt(saltCharacters) | |
passwordHash = hashPassword(password, salt) | |
if not beQuiet: | |
print("Transmission Hash: ", end = "") | |
transmissionHash = f"{{{passwordHash}{salt}" | |
if outputFilePath: | |
with open(outputFilePath, mode = "w") as outFile: | |
outFile.write(transmissionHash) | |
else: | |
print(transmissionHash) | |
def main(): | |
argParser = ArgumentParser(description = "Hash passwords for use with the Transmission Daemon") | |
argParser.add_argument( | |
"--quiet", "-q", | |
action = "store_true", | |
help = "Don't print any prompts, just the resulting hash" | |
) | |
argParser.add_argument( | |
"--stdin", "-s", | |
action = "store_true", | |
help = "Read password from standard in" | |
) | |
argParser.add_argument( | |
"--password-file", "-p", | |
help = "Read password from input file (--stdin/-s is ignored)" | |
) | |
argParser.add_argument( | |
"--output-file", "-o", | |
help = "Write hash to output file" | |
) | |
args = argParser.parse_args() | |
hashTransmissionPassword( | |
args.quiet, | |
args.stdin, | |
args.password_file, | |
args.output_file | |
) | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment