Your IP : 216.73.216.247


Current Path : /opt/cpanel/
Upload File :
Current File : //opt/cpanel/zarc_list_domains.py

import socket
import ssl
import struct
import uuid
import xml.etree.ElementTree as ET

EPP_HOST = "epp.zarc.net.za"
EPP_PORT = 700
EPP_USER = "enetworks"
EPP_PASS = "36ancerg9a2"

def frame(xml_string):
    xml_bytes = xml_string.encode('utf-8')
    return struct.pack("!I", len(xml_bytes) + 4) + xml_bytes

def read_response(sock):
    header = sock.recv(4)
    if not header:
        return None
    total_length = struct.unpack("!I", header)[0]
    data = b''
    while len(data) < total_length - 4:
        chunk = sock.recv(total_length - 4 - len(data))
        if not chunk:
            break
        data += chunk
    return data.decode('utf-8')

def build_login_xml():
    return f"""<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <login>
      <clID>{EPP_USER}</clID>
      <pw>{EPP_PASS}</pw>
      <options>
        <version>1.0</version>
        <lang>en</lang>
      </options>
      <svcs>
        <objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
        <objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
        <objURI>http://co.za/epp/extensions/cozadomain-1-0</objURI>
      </svcs>
    </login>
    <clTRID>{uuid.uuid4()}</clTRID>
  </command>
</epp>"""

def build_list_domains_xml():
    return f"""<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <info/>
    <extension>
      <coza:list xmlns:coza="http://co.za/epp/extensions/cozadomain-1-0">
        <coza:listDomains/>
      </coza:list>
    </extension>
    <clTRID>{uuid.uuid4()}</clTRID>
  </command>
</epp>"""

def parse_domain_list(xml_str):
    """Extract domains, expiry, and status."""
    ns = {
        'coza': 'http://co.za/epp/extensions/cozadomain-1-0',
        'domain': 'urn:ietf:params:xml:ns:domain-1.0',
        'epp': 'urn:ietf:params:xml:ns:epp-1.0'
    }
    root = ET.fromstring(xml_str)
    domains = []

    for d in root.findall('.//coza:domain', ns):
        name = d.find('coza:name', ns)
        exp = d.find('coza:expiryDate', ns)
        status = d.find('coza:status', ns)
        domains.append({
            'name': name.text if name is not None else '',
            'expiry': exp.text if exp is not None else '',
            'status': status.text if status is not None else ''
        })
    return domains

# ----- Main EPP Flow -----
def main():
    context = ssl.create_default_context()
    with socket.create_connection((EPP_HOST, EPP_PORT)) as tcp_sock:
        with context.wrap_socket(tcp_sock, server_hostname=EPP_HOST) as epp_sock:
            print("[+] Connected to ZARC via TLS")

            greeting = read_response(epp_sock)
            print("[i] Greeting received.")

            print("[*] Logging in...")
            epp_sock.sendall(frame(build_login_xml()))
            login_response = read_response(epp_sock)
            print("[i] Login OK.")

            print("[*] Sending listDomains request...")
            epp_sock.sendall(frame(build_list_domains_xml()))
            list_response = read_response(epp_sock)
            print("[i] Domain list response received.")

            domains = parse_domain_list(list_response)
            print(f"\n{'Domain':<35} {'Expiry Date':<20} {'Status'}")
            print("-" * 70)
            for d in domains:
                print(f"{d['name']:<35} {d['expiry']:<20} {d['status']}")
            print(f"\nTotal domains: {len(domains)}")

if __name__ == "__main__":
    main()