#!/usr/bin/env python3 """Silent attended current-source and governed provider history recovery proof.""" import argparse import configparser import hmac from urllib.parse import urlsplit,unquote from datetime import datetime,timezone import hashlib import importlib.util import json import os from pathlib import Path import subprocess import tempfile import uuid from root_grant_attended import Bao, RECORD_ID, atomic_json, check_baseline, digest, require_attended from migrate_nextcloud_backup_account import HOST, OPERATOR_PATH, LANE, quota, request VALIDATOR_DIGEST='9156e399c8d92a45b817bfc3738c89843487ce57e1718ed747f804f95cc719bb' SCHEMA_DIGEST='bb6cd6da5dc48eddcf118ae78c2cacfafd5f860098fd8a8368fe6bc845776d07' def checked_bundle(state_path, validator): state=json.loads(state_path.read_text()) if state.get('pending') or validator.validate(state['document']) or state['record_id']!=RECORD_ID or digest(state['document'])!=state['digest']: raise ValueError('retained_state_invalid') history=[] for path in sorted((state_path.parent/'history').glob('*.json')): if path.is_symlink() or path.stat().st_size>262144: raise ValueError('history_invalid') receipt=json.loads(path.read_text()) if validator.validate(receipt['document']) or receipt['record_id']!=RECORD_ID or receipt['digest']!=digest(receipt['document']): raise ValueError('history_invalid') history.append(receipt) if state not in history: raise ValueError('latest_history_missing') return state,json.dumps({'baseline':state,'history':history},sort_keys=True,separators=(',',':')).encode() def historical_config_comparison(config_path, values): if not config_path.exists(): return {"historical_config_present":False,"historical_share_matches_current_lane":None} try: config=configparser.ConfigParser(interpolation=None) config.read(config_path) remote=config['nextcloud-backup'] candidates=[remote.get('user','')]+unquote(urlsplit(remote.get('url','')).path).split('/') matched=any(hmac.compare_digest(value,values['NC_WEBDAV_TOKEN']) for value in candidates if value) return {"historical_config_present":True,"historical_share_matches_current_lane":matched, "historical_credential_status":"current-lane-incident" if matched else "historical-owner-and-revocation-unverified"} except Exception: return {"historical_config_present":True,"historical_share_matches_current_lane":None, "historical_credential_status":"comparison-unavailable"} def roundtrip(bundle, lane, operator, network=request, get_quota=quota): values=lane['data'] if operator['BACKUP_USERNAME']!='Backup': raise ValueError('governed_owner_mismatch') auth=(operator['BACKUP_USERNAME'],operator['BACKUP_PASSWORD']) upload=values['NC_WEBDAV_URL'] if not upload.startswith(HOST+'/public.php/dav/filesdrop/') or values['NC_WEBDAV_TOKEN']!=upload.rsplit('/',1)[-1]: raise ValueError('current_lane_contract_mismatch') key=(values['AGE_PRIVATE_KEY'].strip()+'\n').encode() def process(command,payload): result=subprocess.run(command,input=payload,capture_output=True,timeout=30) if result.returncode: raise ValueError('protected_process_failed') return result.stdout recipient=process(['age-keygen','-y','/dev/stdin'],key).decode().strip() encrypted=process(['age','-r',recipient],bundle) if len(encrypted)>1048576 or get_quota(auth)['available_bytes']