[wip] v2 support code (#13)

This commit is contained in:
r4sas
2019-06-02 14:04:38 +00:00
parent 1ff6e721c7
commit f7fae450a0
5 changed files with 363 additions and 142 deletions

View File

@@ -1,14 +1,7 @@
import json, hashlib, os, sys
import pbincli.actions
from sjcl import SJCL
from base64 import b64encode, b64decode
from pbincli.utils import PBinCLIException
from sys import exit
from pbincli.format import Paste
def send(args, api_client):
from pbincli.utils import check_readable, compress, path_leaf
from mimetypes import guess_type
if not args.notext:
if args.text:
text = args.text
@@ -16,202 +9,159 @@ def send(args, api_client):
text = args.stdin.read()
elif not args.file:
print("Nothing to send!")
sys.exit(1)
exit(1)
else:
text = ""
# Formatting request
request = {'expire':args.expire,'formatter':args.format,'burnafterreading':int(args.burn),'opendiscussion':int(args.discus)}
passphrase = b64encode(os.urandom(32))
if args.debug: print("Passphrase:\t{}".format(passphrase))
paste = Paste(args.debug)
paste.setVersion(api_client.getVersion())
paste.setText(text)
# If we set PASSWORD variable
if args.password:
digest = hashlib.sha256(args.password.encode("UTF-8")).hexdigest()
password = passphrase + digest.encode("UTF-8")
else:
password = passphrase
if args.debug: print("Password:\t{}".format(password))
# Encrypting text
cipher = SJCL().encrypt(compress(text.encode('utf-8')), password, mode='gcm')
# TODO: should be implemented in upstream
for k in ['salt', 'iv', 'ct']: cipher[k] = cipher[k].decode()
request['data'] = json.dumps(cipher, ensure_ascii=False).replace(' ','')
paste.setPassword(args.password)
# If we set FILE variable
if args.file:
check_readable(args.file)
with open(args.file, "rb") as f:
contents = f.read()
f.close()
mime = guess_type(args.file, strict=False)[0]
paste.setAttachment(args.file)
# MIME fallback
if not mime: mime = "application/octet-stream"
paste.encrypt(
formatter = args.format,
burnafterreading = args.burn,
discussion = args.discus,
expiration = args.expire)
if args.debug: print("Filename:\t{}\nMIME-type:\t{}".format(path_leaf(args.file), mime))
file = "data:" + mime[0] + ";base64," + b64encode(contents).decode()
filename = path_leaf(args.file)
cipherfile = SJCL().encrypt(compress(file.encode('utf-8')), password, mode='gcm')
# TODO: should be implemented in upstream
for k in ['salt', 'iv', 'ct']: cipherfile[k] = cipherfile[k].decode()
cipherfilename = SJCL().encrypt(compress(filename.encode('utf-8')), password, mode='gcm')
for k in ['salt', 'iv', 'ct']: cipherfilename[k] = cipherfilename[k].decode()
request['attachment'] = json.dumps(cipherfile, ensure_ascii=False).replace(' ','')
request['attachmentname'] = json.dumps(cipherfilename, ensure_ascii=False).replace(' ','')
request = paste.getJSON()
if args.debug: print("Request:\t{}".format(request))
# If we use dry option, exit now
if args.dry: sys.exit(0)
if args.dry: exit(0)
result = api_client.post(request)
if args.debug: print("Response:\t{}\n".format(result))
try:
result = json.loads(result)
except ValueError as e:
print("PBinCLI Error: {}".format(e))
sys.exit(1)
if 'status' in result and not result['status']:
print("Paste uploaded!\nPasteID:\t{}\nPassword:\t{}\nDelete token:\t{}\n\nLink:\t\t{}?{}#{}".format(result['id'], passphrase.decode(), result['deletetoken'], api_client.server, result['id'], passphrase.decode()))
passphrase = paste.getHash()
print("Paste uploaded!\nPasteID:\t{}\nPassword:\t{}\nDelete token:\t{}\n\nLink:\t\t{}?{}#{}".format(
result['id'],
passphrase,
result['deletetoken'],
api_client.server,
result['id'],
passphrase))
elif 'status' in result and result['status']:
print("Something went wrong...\nError:\t\t{}".format(result['message']))
sys.exit(1)
exit(1)
else:
print("Something went wrong...\nError: Empty response.")
sys.exit(1)
exit(1)
def get(args, api_client):
from pbincli.utils import check_writable, decompress
from pbincli.utils import check_writable
pasteid, passphrase = args.pasteinfo.split("#")
try:
pasteid, passphrase = args.pasteinfo.split("#")
except ValueError as err:
print("PBinCLI error: provided info hasn't contain valid PasteID#Passphrase string")
exit(1)
if pasteid and passphrase:
if args.debug: print("PasteID:\t{}\nPassphrase:\t{}".format(pasteid, passphrase))
if not (pasteid and passphrase):
print("PBinCLI error: Incorrect request")
exit(1)
if args.password:
digest = hashlib.sha256(args.password.encode("UTF-8")).hexdigest()
password = passphrase + digest.encode("UTF-8")
else:
password = passphrase
if args.debug: print("PasteID:\t{}\nPassphrase:\t{}".format(pasteid, passphrase))
paste = Paste()
if args.password:
paste.setPassword(args.password)
if args.debug: print("Password:\t{}".format(password))
result = api_client.get(pasteid)
else:
print("PBinCLI error: Incorrect request")
sys.exit(1)
result = api_client.get(pasteid)
if args.debug: print("Response:\t{}\n".format(result))
try:
result = json.loads(result)
except ValueError as e:
print("PBinCLI Error: {}".format(e))
sys.exit(1)
if 'status' in result and not result['status']:
print("Paste received! Text inside:")
data = json.loads(result['data'])
print("Paste received!")
if args.debug: print("Text:\t{}\n".format(data))
version = result['v'] if 'v' in result else 1
paste.setVersion(version)
if version == 2:
if args.debug: print("Message:\t{}\nAuthentication data:\t{}".format(result['ct'], result['adata']))
text = SJCL().decrypt(data, password)
paste.setHash(passphrase)
paste.loadJSON(result)
paste.decrypt()
text = paste.getText()
if args.debug: print("Decoded text size: {}\n".format(len(text)))
if len(text):
print("{}\n".format(decompress(text.decode())))
check_writable("paste.txt")
with open("paste.txt", "wb") as f:
f.write(decompress(text.decode()))
f.close
if 'attachment' in result and 'attachmentname' in result:
print("Found file, attached to paste. Decoding it and saving")
cipherfile = json.loads(result['attachment'])
cipherfilename = json.loads(result['attachmentname'])
if args.debug: print("Name:\t{}\nData:\t{}".format(cipherfilename, cipherfile))
attachmentf = SJCL().decrypt(cipherfile, password)
attachmentname = SJCL().decrypt(cipherfilename, password)
attachment = decompress(attachmentf.decode('utf-8')).decode('utf-8').split(',', 1)[1]
file = b64decode(attachment)
filename = decompress(attachmentname.decode('utf-8')).decode('utf-8')
print("Filename:\t{}\n".format(filename))
if args.debug: print("{}\n".format(text.decode()))
filename = "paste-" + pasteid + ".txt"
print("Found text in paste. Saving it to {}".format(filename))
check_writable(filename)
with open(filename, "wb") as f:
f.write(file)
f.write(text)
f.close
if 'burnafterreading' in result['meta'] and result['meta']['burnafterreading']:
attachment, attachment_name = paste.getAttachment()
if attachment:
print("Found file, attached to paste. Saving it to {}\n".format(attachment_name))
check_writable(attachment_name)
with open(attachment_name, "wb") as f:
f.write(attachment)
f.close
if version == 1 and 'meta' in result and 'burnafterreading' in result['meta'] and result['meta']['burnafterreading']:
print("Burn afrer reading flag found. Deleting paste...")
result = api_client.delete(pasteid, 'burnafterreading')
result = api_client.delete(json_encode({'pasteid':pasteid,'deletetoken':'burnafterreading'}))
if args.debug: print("Delete response:\t{}\n".format(result))
try:
result = json.loads(result)
except ValueError as e:
print("PBinCLI Error: {}".format(e))
sys.exit(1)
if 'status' in result and not result['status']:
print("Paste successfully deleted!")
elif 'status' in result and result['status']:
print("Something went wrong...\nError:\t\t{}".format(result['message']))
sys.exit(1)
exit(1)
else:
print("Something went wrong...\nError: Empty response.")
sys.exit(1)
exit(1)
elif 'status' in result and result['status']:
print("Something went wrong...\nError:\t\t{}".format(result['message']))
sys.exit(1)
exit(1)
else:
print("Something went wrong...\nError: Empty response.")
sys.exit(1)
exit(1)
def delete(args, api_client):
from pbincli.utils import json_encode
pasteid = args.paste
token = args.token
if args.debug: print("PasteID:\t{}\nToken:\t\t{}".format(pasteid, token))
result = api_client.delete(pasteid, token)
result = api_client.delete(json_encode({'pasteid':pasteid,'deletetoken':token}))
if args.debug: print("Response:\t{}\n".format(result))
try:
result = json.loads(result)
except ValueError as e:
print("PBinCLI Error: {}".format(e))
sys.exit(1)
if 'status' in result and not result['status']:
print("Paste successfully deleted!")
elif 'status' in result and result['status']:
print("Something went wrong...\nError:\t\t{}".format(result['message']))
sys.exit(1)
exit(1)
else:
print("Something went wrong...\nError: Empty response.")
sys.exit(1)
exit(1)