File size: 4,005 Bytes
31c8c9e
 
ba92183
31c8c9e
ba92183
31c8c9e
ba92183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2d68192
 
 
ba92183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31c8c9e
 
ba92183
 
31c8c9e
ba92183
 
 
 
 
31c8c9e
ba92183
 
 
 
2d68192
ba92183
31c8c9e
 
 
 
ba92183
31c8c9e
ba92183
31c8c9e
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import argparse
import requests
import sys
import json
from datetime import datetime

# ==========================================
# CONFIGURATION
# ==========================================
API_URL = "https://valent-p-qecho.hf.space" 
# ==========================================

def print_error(msg):
    print(f"[-] ERROR: {msg}")

def print_success(msg):
    print(f"[+] {msg}")

def print_info(msg):
    print(f"[*] {msg}")

def cmd_send(args):
    payload = {
        "group_name": args.group,
        "password": args.key,
        "data": args.msg
    }
    
    try:
        print_info(f"Encrypting and sending to channel '{args.group}'...")
        response = requests.post(f"{API_URL}/store", json=payload)
        
        if response.status_code == 200:
            data = response.json()
            print_success(f"Transmission Complete.")
            print(f"    ID: {data.get('uuid')}")
        else:
            print_error(f"Server returned {response.status_code}")
            print(response.text)
            
    except requests.exceptions.ConnectionError:
        print_error("Could not connect to server. Check your API_URL.")

def cmd_get(args):
    payload = {
        "group_name": args.group,
        "password": args.key,
        "password": args.key,
        "burn": args.burn,
        "limit": args.limit
    }
    
    try:
        print_info(f"Authenticating with Twin-Key for '{args.group}'...")
        response = requests.post(f"{API_URL}/retrieve", json=payload)
        
        if response.status_code == 200:
            data = response.json()
            messages = data.get("messages", [])
            
            if not messages:
                print("    [!] No messages found (or invalid credentials).")
                return

            print_success(f"Retrieved {len(messages)} record(s):\n")
            
            for msg in messages:
                # Handle system messages (like "Burned X messages")
                if 'system_info' in msg:
                    print(f"    >>> SYSTEM: {msg['system_info']}")
                    continue

                # Handle standard messages
                ts = msg.get('timestamp', 'Unknown Time')
                content = msg.get('content', '')
                msg_id = msg.get('id', '')
                
                print(f"    [{ts}] ID: {msg_id[:8]}...")
                print(f"    DATA: {content}")
                print("-" * 40)
                
            if args.burn:
                print_info("Burn sequence complete. Data destroyed on server.")
                
        else:
            print_error(f"Server returned {response.status_code}")
            print(response.text)

    except requests.exceptions.ConnectionError:
        print_error("Could not connect to server. Check your API_URL.")

def main():
    parser = argparse.ArgumentParser(description="QEcho: Zero-Knowledge Dead Drop Interface")
    subparsers = parser.add_subparsers(dest="command", required=True)

    # --- SEND COMMAND ---
    send_parser = subparsers.add_parser("send", help="Encrypt and upload data")
    send_parser.add_argument("--group", required=True, help="Channel/Topic Name")
    send_parser.add_argument("--key", required=True, help="Secret Password")
    send_parser.add_argument("--msg", required=True, help="The data/message to store")

    # --- GET COMMAND ---
    get_parser = subparsers.add_parser("get", help="Retrieve and decrypt data")
    get_parser.add_argument("--group", required=True, help="Channel/Topic Name")
    get_parser.add_argument("--key", required=True, help="Secret Password")
    get_parser.add_argument("--limit", type=int, default=100, help="Max number of messages to retrieve")
    get_parser.add_argument("--burn", action="store_true", help="Delete messages from server after reading")

    args = parser.parse_args()

    if args.command == "send":
        cmd_send(args)
    elif args.command == "get":
        cmd_get(args)

if __name__ == "__main__":
    main()