Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions share/rpcauth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ RPC Tools

### [RPCAuth](/share/rpcauth) ###

Create login credentials for a JSON-RPC user.
```
usage: rpcauth.py [-h] username [password]

Usage:
Create login credentials for a JSON-RPC user

./rpcauth.py <username>
positional arguments:
username the username for authentication
password leave empty to generate a random password or specify "-" to
prompt for password

in which case the script will generate a password. To specify a custom password do:

./rpcauth.py <username> <password>
optional arguments:
-h, --help show this help message and exit
```
34 changes: 18 additions & 16 deletions share/rpcauth/rpcauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,44 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

import sys
import os
import base64
from argparse import ArgumentParser
from base64 import urlsafe_b64encode
from binascii import hexlify
from getpass import getpass
from os import urandom

import hmac

def generate_salt(size):
"""Create size byte hex salt"""
return hexlify(os.urandom(size)).decode()
return hexlify(urandom(size)).decode()

def generate_password():
"""Create 32 byte b64 password"""
return base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8')
return urlsafe_b64encode(urandom(32)).decode('utf-8')

def password_to_hmac(salt, password):
m = hmac.new(bytearray(salt, 'utf-8'), bytearray(password, 'utf-8'), 'SHA256')
return m.hexdigest()

def main():
if len(sys.argv) < 2:
sys.stderr.write('Please include username (and an optional password, will generate one if not provided) as an argument.\n')
sys.exit(0)
parser = ArgumentParser(description='Create login credentials for a JSON-RPC user')
parser.add_argument('username', help='the username for authentication')
parser.add_argument('password', help='leave empty to generate a random password or specify "-" to prompt for password', nargs='?')
args = parser.parse_args()

username = sys.argv[1]
if not args.password:
args.password = generate_password()
elif args.password == '-':
args.password = getpass()

# Create 16 byte hex salt
salt = generate_salt(16)
if len(sys.argv) > 2:
password = sys.argv[2]
else:
password = generate_password()
password_hmac = password_to_hmac(salt, password)
password_hmac = password_to_hmac(salt, args.password)

print('String to be appended to bitcoin.conf:')
print('rpcauth={0}:{1}${2}'.format(username, salt, password_hmac))
print('Your password:\n{0}'.format(password))
print('rpcauth={0}:{1}${2}'.format(args.username, salt, password_hmac))
print('Your password:\n{0}'.format(args.password))

if __name__ == '__main__':
main()