| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- #!/usr/bin/env python3
- """
- Simple script to add a key to the emergency access server
- Takes an existing key file, copies it to the configured directory, and adds it to config
- """
- import json
- import os
- import sys
- import shutil
- import secrets
- import hashlib
- import argparse
- from pathlib import Path
- def generate_password_hash(password: str) -> str:
- """Generate password hash using PBKDF2 with SHA-256"""
- salt = secrets.token_hex(16)
- password_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100000)
- return f"{salt}:{password_hash.hex()}"
- def generate_secure_password(length: int = 32) -> str:
- """Generate a secure password"""
- import string
- alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
- return ''.join(secrets.choice(alphabet) for _ in range(length))
- def load_config(config_path: str):
- """Load configuration file"""
- with open(config_path, 'r') as f:
- return json.load(f)
- def save_config(config, config_path: str):
- """Save configuration file"""
- with open(config_path, 'w') as f:
- json.dump(config, f, indent=2)
- def copy_key_file(source_path: str, dest_path: str):
- """Copy key file to destination with proper permissions"""
- # Create destination directory if needed
- dest_dir = os.path.dirname(dest_path)
- os.makedirs(dest_dir, exist_ok=True)
- # Copy file
- shutil.copy2(source_path, dest_path)
- # Set secure permissions
- os.chmod(dest_path, 0o600)
- # Try to set ownership to emergency-access user if running as root
- if os.geteuid() == 0: # Running as root
- try:
- import pwd, grp
- user = pwd.getpwnam('emergency-access')
- group = grp.getgrnam('emergency-access')
- os.chown(dest_path, user.pw_uid, group.gr_gid)
- print(f"✅ Copied key file with emergency-access ownership: {dest_path}")
- except (KeyError, OSError):
- print(f"✅ Copied key file: {dest_path}")
- print(f"⚠️ Run: sudo chown emergency-access:emergency-access {dest_path}")
- else:
- print(f"✅ Copied key file: {dest_path}")
- print(f"⚠️ Run: sudo chown emergency-access:emergency-access {dest_path}")
- def main():
- parser = argparse.ArgumentParser(description="Add a key to emergency access server")
- parser.add_argument('key_id', help='Key identifier (e.g., backup, master)')
- parser.add_argument('key_file', help='Path to existing key file')
- parser.add_argument('backends', help='Comma-separated notification backends')
- parser.add_argument('--config', default='config.json', help='Config file path')
- parser.add_argument('--dest-dir', default='/etc/emergency-access', help='Destination directory')
- parser.add_argument('--password', help='Password (generated if not provided)')
- parser.add_argument('--message', help='Custom notification message')
- args = parser.parse_args()
- # Check if source key file exists
- if not os.path.exists(args.key_file):
- print(f"❌ Key file not found: {args.key_file}")
- sys.exit(1)
- # Load config
- try:
- config = load_config(args.config)
- except FileNotFoundError:
- print(f"❌ Config file not found: {args.config}")
- sys.exit(1)
- # Check if key already exists
- if args.key_id in config.get('keys', {}):
- print(f"❌ Key '{args.key_id}' already exists")
- sys.exit(1)
- # Generate password if not provided
- if args.password:
- password = args.password
- else:
- password = generate_secure_password()
- print(f"🔑 Generated password: {password}")
- # Set up paths and config
- dest_file = os.path.join(args.dest_dir, f"{args.key_id}-key.txt")
- route = f"/emergency-key-{args.key_id}"
- username = f"emergency_{args.key_id}"
- password_hash = generate_password_hash(password)
- backends = [b.strip() for b in args.backends.split(',')]
- message = args.message or f"🚨 EMERGENCY: Key {args.key_id} accessed from server"
- # Copy key file
- copy_key_file(args.key_file, dest_file)
- # Add to config
- if 'keys' not in config:
- config['keys'] = {}
- config['keys'][args.key_id] = {
- 'route': route,
- 'file': dest_file,
- 'username': username,
- 'password_hash': password_hash,
- 'backends': backends,
- 'message': message
- }
- # Save config
- save_config(config, args.config)
- print(f"✅ Added key '{args.key_id}' to configuration")
- print(f" Route: {route}")
- print(f" Username: {username}")
- print(f" Password: {password}")
- print(f" Backends: {', '.join(backends)}")
- if __name__ == '__main__':
- main()
|