Add files via upload

main
witchdocsec 2024-05-27 13:42:39 +01:00 committed by GitHub
parent 9e827831bb
commit 31b523e4cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 241 additions and 0 deletions

36
lib/banner.py Normal file
View File

@ -0,0 +1,36 @@
def banner():
print('''\033[49m \033[m
\033[49m \033[m
\033[49m \033[38;5;14;49m\033[49m \033[m
\033[49m \033[38;5;14;49m\033[38;5;14;48;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[m
\033[49m \033[38;5;14;49m\033[48;5;14m \033[38;5;14;49m\033[49m \033[m
\033[49m \033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[49m \033[49;38;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[m
\033[49m \033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[49m \033[49;38;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[m
\033[49m \033[38;5;14;49m\033[48;5;14m \033[49m \033[49;38;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[m
\033[49m \033[38;5;14;49m\033[48;5;14m \033[38;5;14;49m\033[49m \033[49;38;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[m
\033[49m \033[38;5;14;49m\033[48;5;14m \033[38;5;14;49m\033[49m \033[48;5;14m \033[49m \033[m
\033[49m \033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[38;5;14;49m\033[48;5;14m \033[38;5;14;48;5;14m\033[49m \033[m
\033[49m \033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[49m \033[38;5;14;49m\033[48;5;14m \033[38;5;14;49m\033[49m \033[38;5;14;49m\033[48;5;14m \033[38;5;14;48;5;14m\033[49m \033[m
\033[49m \033[48;5;14m \033[49;38;5;14m\033[49m \033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[49m \033[48;5;14m \033[38;5;14;49m\033[49m \033[49;38;5;14m\033[48;5;14m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[48;5;14m \033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[48;5;14m \033[49m \033[48;5;14m \033[38;5;14;49m\033[49m \033[49;38;5;14m\033[48;5;14m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[49;38;5;14m\033[48;5;14m \033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[49m \033[48;5;14m \033[49m \033[48;5;14m \033[49m \033[m
\033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[38;5;14;49m\033[48;5;14m \033[49m \033[48;5;14m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[49m \033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[38;5;14;49m\033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[49m \033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[38;5;14;49m\033[38;5;14;48;5;14m\033[38;5;14;49m\033[48;5;14m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[49;38;5;14m\033[38;5;14;48;5;14m\033[48;5;14m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[49;38;5;14m\033[48;5;14m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[49;38;5;14m\033[49m \033[m
\033[49m \033[m
\033[49m \033[m
''')
print('''
_____ _ _ _
| __ \\ | | /\\ | | | |
| |__) |_ _ ___ _____ _____ _ __ __| | / \\ | | ___| |__ ___ _ __ ___ _ _
| ___/ _` / __/ __\\ \\ /\\ / / _ \\| '__/ _` | / /\\ \\ | |/ __| '_ \\ / _ \\ '_ ` _ \\| | | |
| | | (_| \\__ \\__ \\\\ V V / (_) | | | (_| |/ ____ \\| | (__| | | | __/ | | | | | |_| |
|_| \\__,_|___/___/ \\_/\\_/ \\___/|_| \\__,_/_/ \\_\\_|\\___|_| |_|\\___|_| |_| |_|\\__, |
__/ |
|___/
''')

99
lib/db.py Normal file
View File

@ -0,0 +1,99 @@
#imports
from sqlalchemy import create_engine, Column, String, Integer
from sqlalchemy.orm import sessionmaker, declarative_base
from os.path import exists
from os import mkdir
from contextlib import contextmanager
#sql alchemy base for tables to inherit from
Base = declarative_base()
# Ensure the directory for the database exists
if not exists("db"):
mkdir("db")
# Define the Password model
class Password(Base):
__tablename__ = "Password"
domain = Column("domain", String, primary_key=True)
ccred = Column("ccred", String)
def __init__(self, domain, ccred):
self.domain = domain
self.ccred = ccred
# Database setup
engine = create_engine("sqlite:///db/creds.db")
Base.metadata.create_all(bind=engine)
Session = sessionmaker(bind=engine)
#manage context
@contextmanager
def get_session():
session = Session()
try:
yield session
session.commit()
except Exception as e:
session.rollback()
print(f"Database error: {e}")
finally:
session.close()
#store credential
def store(domain,ccred):
p = Password(domain,ccred)
with get_session() as session:
try:
session.add(p)
return "Stored credential"
except Exception as e:
return "Error storing password: {e}"
#load credemtial
def fetch(domain):
#with context manager
with get_session() as session:
#query passwords by domain
p = session.query(Password).filter(Password.domain == domain).first()
#if one is found
if p:
return p.ccred
#error
else:
return f"No cred found for '{domain}'"
def fetchall():
#with context manager
with get_session() as session:
#query passwords by domain
p = session.query(Password)
#if one is found
if p:
return p
#error
else:
return "No creds found"
#load credemtial
def update(domain,ccred):
#with context manager
with get_session() as session:
#query passwords by domain
p = session.query(Password).filter(Password.domain == domain).first()
#if one is found
if p:
p.ccred=ccred
return "updated credential"
#error
else:
return f"No cred found for '{domain}'"

23
lib/parse.py Normal file
View File

@ -0,0 +1,23 @@
import argparse
def parser():
parser = argparse.ArgumentParser(description="passwordalchemy args")
subparse=parser.add_subparsers(dest="command")
fetchparser=subparse.add_parser("fetch")
fetchparser.add_argument("-pk","--privatekey",required=True, help="path to private key pem file")
fetchparser.add_argument("-d", "--domain",required=True)
storeparser=subparse.add_parser("store")
storeparser.add_argument("-d", "--domain",required=True)
storeparser.add_argument("-p", "--password",required=True)
updateparser=subparse.add_parser("update")
updateparser.add_argument("-d", "--domain",required=True)
updateparser.add_argument("-p", "--password",required=True)
gkparser=subparse.add_parser("genkeys")
gkparser.add_argument("-pk","--privatekey")
gkparser.add_argument("-opk","--oldprivatekey")
args = parser.parse_args()
return args

83
passwordalchemy.py Normal file
View File

@ -0,0 +1,83 @@
import rsa
import base64
import lib.db
import lib.parse
import lib.banner
class mainfuncs:
#generate keyset. first or new
@staticmethod
def genkeys(args):
#generate keypair
(pubkey, privkey) = rsa.newkeys(900)
#if a key is already present
if args.oldprivatekey:
with open(args.oldprivatekey,"r") as pemfile:
oldprivatekey=rsa.PrivateKey._load_pkcs1_pem(pemfile.read())
#save public key
with open("pub.pem","w") as pemfile:
pemfile.write(pubkey._save_pkcs1_pem().decode("utf-8"))
#if path to save in not specified
if not args.privatekey:
print("save this pem to a secure location to decrypt your passwords. If you lose it you can't recover your credentials")
print(privkey._save_pkcs1_pem().decode("utf-8"))
print("you can copy and paste it. and leave the prompt blank")
args.privatekey=input("or we can save it for you here: ")
#save private key
with open(args.privatekey,"w") as pemfile:
pemfile.write(privkey._save_pkcs1_pem().decode("utf-8"))
#if a key is already present
if args.oldprivatekey:
creds=lib.db.fetchall()
#if creds are present
if creds:
for cred in creds:
with open(args.privatekey) as pemfile:
privkey=rsa.PrivateKey._load_pkcs1_pem(pemfile.read())
pcred=rsa.decrypt(base64.b64decode(cred.ccred),oldprivatekey).decode("utf-8")
ccred=base64.b64encode(rsa.encrypt(pcred.encode("utf-8"),pubkey)).decode("utf-8")
lib.db.update(cred.domain,ccred)
#fetch a credential
@staticmethod
def fetch(args):
#send to db library fetch function
ccred=lib.db.fetch(args.domain)
with open(args.privatekey) as pemfile:
#load rsa private key
privkey=rsa.PrivateKey._load_pkcs1_pem(pemfile.read())
#print credential
print(rsa.decrypt(base64.b64decode(ccred),privkey).decode("utf-8"))
#store a credential
@staticmethod
def store(args):
with open("pub.pem") as pemfile:
#load rsa public key
pubkey=rsa.PublicKey._load_pkcs1_pem(pemfile.read())
#encrypted credential
ccred=base64.b64encode(rsa.encrypt(args.password.encode("utf-8"),pubkey)).decode("utf-8")
#send to db library store function
print(lib.db.store(args.domain,ccred))
#update a credential
@staticmethod
def update(args):
with open("pub.pem") as pemfile:
#load rsa public key
pubkey=rsa.PublicKey._load_pkcs1_pem(pemfile.read())
#encrypted credential
ccred=base64.b64encode(rsa.encrypt(args.password.encode("utf-8"),pubkey)).decode("utf-8")
#send to db update store function
print(lib.db.update(args.domain,ccred))
if __name__ == "__main__":
#banner
lib.banner.banner()
#command line arguments
args=lib.parse.parser()
#get function name from arguments
if args.command:
command=getattr(mainfuncs,args.command)
#execute
command(args)