Compare commits

...

3 Commits

Author SHA1 Message Date
scito
fb66c5f568 minor improvements 2020-12-21 19:52:55 +01:00
FrankAbagnaleJr
cc26f7b589 Option to save QR codes as PNG (#2)
* Generate QR code images

Now generates QR images instead of attempting to display the QR code in the console. Places them in a subdirectory of the current directory, entitled "qr"

* Update README.md

* Changes based on suggestions from scito

https://github.com/scito/extract_otp_secret_keys/pull/2#pullrequestreview-555264890

* Update extract_otp_secret_keys.py

Minor formatting changes and clarifications to help text

* Update extract_otp_secret_keys.py

Remove --qr argument, instead opting to respond to --printqr or --saveqr
2020-12-21 19:19:13 +01:00
scito
6068eb142c Fix #1: Quote otp.name 2020-11-14 13:15:06 +01:00
3 changed files with 29 additions and 7 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
qr/

View File

@@ -21,7 +21,7 @@ The protobuf package of Google for proto3 is required for running this script.
For printing QR codes, the qrcode module is required
pip install qrcode
pip install qrcode[pil]
## Technical background

View File

@@ -45,18 +45,23 @@ import argparse
import base64
import fileinput
import sys
from urllib.parse import parse_qs, urlencode, urlparse
from urllib.parse import parse_qs, urlencode, urlparse, quote
from os import path, mkdir
from re import sub, compile as rcompile
import generated_python.google_auth_pb2
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('--verbose', '-v', help='verbose output', action='store_true')
arg_parser.add_argument('--qr', '-q', help='print QR codes (otpauth://...)', action='store_true')
arg_parser.add_argument('--saveqr', '-s', help='save QR code(s) as images to the "qr" subfolder', action='store_true')
arg_parser.add_argument('--printqr', '-p', help='print QR code(s) as text to the terminal', action='store_true')
arg_parser.add_argument('infile', help='file or - for stdin (default: -) with "otpauth-migration://..." URLs separated by newlines, lines starting with # are ignored')
args = arg_parser.parse_args()
verbose = args.verbose
if args.qr:
saveqr = args.saveqr
printqr = args.printqr
if saveqr or printqr:
from qrcode import QRCode
# https://stackoverflow.com/questions/40226049/find-enums-listed-in-python-descriptor-for-protobuf
@@ -67,6 +72,12 @@ def get_enum_name_by_number(parent, field_name):
def convert_secret_from_bytes_to_base32_str(bytes):
return str(base64.b32encode(otp.secret), 'utf-8').replace('=', '')
def save_qr(data, name):
qr = QRCode()
qr.add_data(data)
img = qr.make_image(fill_color='black', back_color='white')
if verbose: print('Saving to {}'.format(name))
img.save(name)
def print_qr(data):
qr = QRCode()
@@ -85,7 +96,9 @@ for line in (line.strip() for line in fileinput.input(args.infile)):
if verbose: print(payload)
# pylint: disable=no-member
i = 0
for otp in payload.otp_parameters:
i += 1
print('\nName: {}'.format(otp.name))
secret = convert_secret_from_bytes_to_base32_str(otp.secret)
print('Secret: {}'.format(secret))
@@ -94,7 +107,15 @@ for line in (line.strip() for line in fileinput.input(args.infile)):
url_params = { 'secret': secret }
if otp.type == 1: url_params['counter'] = otp.counter
if otp.issuer: url_params['issuer'] = otp.issuer
otp_url = 'otpauth://{}/{}?'.format('totp' if otp.type == 2 else 'hotp', otp.name) + urlencode(url_params)
if args.qr:
otp_url = 'otpauth://{}/{}?'.format('totp' if otp.type == 2 else 'hotp', quote(otp.name)) + urlencode(url_params)
if saveqr:
if verbose: print(otp_url)
if not(path.exists('qr')): mkdir('qr')
pattern = rcompile(r'[\W_]+')
file_otp_name = pattern.sub('', otp.name)
file_otp_issuer = pattern.sub('', otp.issuer)
if not(file_otp_issuer): print_qr(otp_url)
if file_otp_issuer: save_qr(otp_url, 'qr/{}-{}-{}.png'.format(i, file_otp_name, file_otp_issuer))
if printqr:
if verbose: print(otp_url)
print_qr(otp_url)