├── lib ├── currencies.json ├── __pycache__ │ ├── i18n.cpython-35.pyc │ ├── i18n.cpython-36.pyc │ ├── pem.cpython-35.pyc │ ├── util.cpython-35.pyc │ ├── util.cpython-36.pyc │ ├── x509.cpython-35.pyc │ ├── bitcoin.cpython-35.pyc │ ├── bitcoin.cpython-36.pyc │ ├── daemon.cpython-35.pyc │ ├── dnssec.cpython-35.pyc │ ├── network.cpython-35.pyc │ ├── plugins.cpython-35.pyc │ ├── plugins.cpython-36.pyc │ ├── rsakey.cpython-35.pyc │ ├── storage.cpython-35.pyc │ ├── storage.cpython-36.pyc │ ├── version.cpython-35.pyc │ ├── version.cpython-36.pyc │ ├── wallet.cpython-35.pyc │ ├── wallet.cpython-36.pyc │ ├── __init__.cpython-35.pyc │ ├── __init__.cpython-36.pyc │ ├── blockchain.cpython-35.pyc │ ├── commands.cpython-35.pyc │ ├── contacts.cpython-35.pyc │ ├── interface.cpython-35.pyc │ ├── keystore.cpython-35.pyc │ ├── keystore.cpython-36.pyc │ ├── mnemonic.cpython-35.pyc │ ├── mnemonic.cpython-36.pyc │ ├── verifier.cpython-35.pyc │ ├── verifier.cpython-36.pyc │ ├── coinchooser.cpython-35.pyc │ ├── coinchooser.cpython-36.pyc │ ├── segwit_addr.cpython-35.pyc │ ├── segwit_addr.cpython-36.pyc │ ├── synchronizer.cpython-35.pyc │ ├── synchronizer.cpython-36.pyc │ ├── transaction.cpython-35.pyc │ ├── transaction.cpython-36.pyc │ ├── exchange_rate.cpython-35.pyc │ ├── paymentrequest.cpython-35.pyc │ ├── paymentrequest.cpython-36.pyc │ ├── simple_config.cpython-35.pyc │ ├── paymentrequest_pb2.cpython-35.pyc │ └── paymentrequest_pb2.cpython-36.pyc ├── version.py ├── __init__.py ├── i18n.py ├── msqr.py ├── qrscanner.py ├── verifier.py ├── contacts.py └── segwit_addr.py ├── README.md ├── dns ├── __pycache__ │ ├── edns.cpython-35.pyc │ ├── flags.cpython-35.pyc │ ├── hash.cpython-35.pyc │ ├── inet.cpython-35.pyc │ ├── ipv4.cpython-35.pyc │ ├── ipv6.cpython-35.pyc │ ├── name.cpython-35.pyc │ ├── node.cpython-35.pyc │ ├── query.cpython-35.pyc │ ├── rcode.cpython-35.pyc │ ├── rdata.cpython-35.pyc │ ├── rrset.cpython-35.pyc │ ├── set.cpython-35.pyc │ ├── tsig.cpython-35.pyc │ ├── ttl.cpython-35.pyc │ ├── _compat.cpython-35.pyc │ ├── dnssec.cpython-35.pyc │ ├── entropy.cpython-35.pyc │ ├── message.cpython-35.pyc │ ├── opcode.cpython-35.pyc │ ├── __init__.cpython-35.pyc │ ├── exception.cpython-35.pyc │ ├── rdataclass.cpython-35.pyc │ ├── rdataset.cpython-35.pyc │ ├── rdatatype.cpython-35.pyc │ ├── renderer.cpython-35.pyc │ ├── resolver.cpython-35.pyc │ ├── tokenizer.cpython-35.pyc │ ├── wiredata.cpython-35.pyc │ └── reversename.cpython-35.pyc ├── rdtypes │ ├── IN │ │ ├── __pycache__ │ │ │ ├── A.cpython-35.pyc │ │ │ ├── AAAA.cpython-35.pyc │ │ │ └── __init__.cpython-35.pyc │ │ ├── KX.py │ │ ├── NSAP_PTR.py │ │ ├── __init__.py │ │ ├── A.py │ │ ├── AAAA.py │ │ ├── DHCID.py │ │ ├── NSAP.py │ │ ├── SRV.py │ │ ├── PX.py │ │ └── WKS.py │ ├── ANY │ │ ├── __pycache__ │ │ │ ├── DLV.cpython-35.pyc │ │ │ ├── DS.cpython-35.pyc │ │ │ ├── NS.cpython-35.pyc │ │ │ ├── SOA.cpython-35.pyc │ │ │ ├── TXT.cpython-35.pyc │ │ │ ├── CNAME.cpython-35.pyc │ │ │ ├── NSEC.cpython-35.pyc │ │ │ ├── NSEC3.cpython-35.pyc │ │ │ ├── RRSIG.cpython-35.pyc │ │ │ ├── DNSKEY.cpython-35.pyc │ │ │ ├── __init__.cpython-35.pyc │ │ │ └── NSEC3PARAM.cpython-35.pyc │ │ ├── DLV.py │ │ ├── CDS.py │ │ ├── DS.py │ │ ├── MX.py │ │ ├── NS.py │ │ ├── PTR.py │ │ ├── TXT.py │ │ ├── RT.py │ │ ├── SPF.py │ │ ├── AVC.py │ │ ├── DNAME.py │ │ ├── CDNSKEY.py │ │ ├── DNSKEY.py │ │ ├── CNAME.py │ │ ├── EUI48.py │ │ ├── EUI64.py │ │ ├── __init__.py │ │ ├── AFSDB.py │ │ ├── X25.py │ │ ├── CAA.py │ │ ├── HINFO.py │ │ ├── SSHFP.py │ │ ├── URI.py │ │ ├── TLSA.py │ │ ├── RP.py │ │ ├── NSEC3PARAM.py │ │ ├── ISDN.py │ │ ├── CERT.py │ │ ├── HIP.py │ │ └── SOA.py │ ├── __pycache__ │ │ ├── dsbase.cpython-35.pyc │ │ ├── nsbase.cpython-35.pyc │ │ ├── txtbase.cpython-35.pyc │ │ ├── __init__.cpython-35.pyc │ │ └── dnskeybase.cpython-35.pyc │ ├── __init__.py │ ├── euibase.py │ ├── nsbase.py │ ├── txtbase.py │ ├── dsbase.py │ ├── mxbase.py │ └── dnskeybase.py ├── hash.py ├── version.py ├── _compat.py ├── __init__.py ├── tsigkeyring.py ├── grange.py ├── ipv4.py ├── ttl.py ├── opcode.py ├── flags.py ├── e164.py ├── reversename.py ├── rcode.py ├── inet.py ├── rdataclass.py ├── namedict.py └── wiredata.py ├── jsonrpclib ├── __pycache__ │ ├── utils.cpython-35.pyc │ ├── __init__.cpython-35.pyc │ ├── config.cpython-35.pyc │ ├── history.cpython-35.pyc │ ├── jsonrpc.cpython-35.pyc │ ├── jsonclass.cpython-35.pyc │ ├── threadpool.cpython-35.pyc │ └── SimpleJSONRPCServer.cpython-35.pyc ├── __init__.py ├── history.py └── utils.py ├── requirements.txt └── brute.py /lib/currencies.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bip39-bruteforce 2 | Bruteforce bip39/49 wallets from seed 3 | -------------------------------------------------------------------------------- /dns/__pycache__/edns.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/edns.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/flags.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/flags.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/hash.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/hash.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/inet.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/inet.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/ipv4.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/ipv4.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/ipv6.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/ipv6.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/name.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/name.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/node.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/node.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/query.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/query.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/rcode.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/rcode.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/rdata.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/rdata.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/rrset.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/rrset.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/set.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/set.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/tsig.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/tsig.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/ttl.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/ttl.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/i18n.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/i18n.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/i18n.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/i18n.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/pem.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/pem.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/util.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/util.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/util.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/util.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/x509.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/x509.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/_compat.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/_compat.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/dnssec.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/dnssec.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/entropy.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/entropy.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/message.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/message.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/opcode.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/opcode.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/bitcoin.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/bitcoin.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/bitcoin.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/bitcoin.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/daemon.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/daemon.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/dnssec.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/dnssec.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/network.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/network.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/plugins.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/plugins.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/plugins.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/plugins.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/rsakey.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/rsakey.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/storage.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/storage.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/storage.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/storage.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/version.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/version.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/version.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/version.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/wallet.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/wallet.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/wallet.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/wallet.cpython-36.pyc -------------------------------------------------------------------------------- /dns/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/exception.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/exception.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/rdataclass.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/rdataclass.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/rdataset.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/rdataset.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/rdatatype.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/rdatatype.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/renderer.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/renderer.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/resolver.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/resolver.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/tokenizer.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/tokenizer.cpython-35.pyc -------------------------------------------------------------------------------- /dns/__pycache__/wiredata.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/wiredata.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/blockchain.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/blockchain.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/commands.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/commands.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/contacts.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/contacts.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/interface.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/interface.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/keystore.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/keystore.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/keystore.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/keystore.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/mnemonic.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/mnemonic.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/mnemonic.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/mnemonic.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/verifier.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/verifier.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/verifier.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/verifier.cpython-36.pyc -------------------------------------------------------------------------------- /dns/__pycache__/reversename.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/__pycache__/reversename.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/IN/__pycache__/A.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/IN/__pycache__/A.cpython-35.pyc -------------------------------------------------------------------------------- /jsonrpclib/__pycache__/utils.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/jsonrpclib/__pycache__/utils.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/coinchooser.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/coinchooser.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/coinchooser.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/coinchooser.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/segwit_addr.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/segwit_addr.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/segwit_addr.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/segwit_addr.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/synchronizer.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/synchronizer.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/synchronizer.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/synchronizer.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/transaction.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/transaction.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/transaction.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/transaction.cpython-36.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/DLV.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/DLV.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/DS.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/DS.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/NS.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/NS.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/SOA.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/SOA.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/TXT.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/TXT.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/IN/__pycache__/AAAA.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/IN/__pycache__/AAAA.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/__pycache__/dsbase.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/__pycache__/dsbase.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/__pycache__/nsbase.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/__pycache__/nsbase.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/__pycache__/txtbase.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/__pycache__/txtbase.cpython-35.pyc -------------------------------------------------------------------------------- /jsonrpclib/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/jsonrpclib/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /jsonrpclib/__pycache__/config.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/jsonrpclib/__pycache__/config.cpython-35.pyc -------------------------------------------------------------------------------- /jsonrpclib/__pycache__/history.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/jsonrpclib/__pycache__/history.cpython-35.pyc -------------------------------------------------------------------------------- /jsonrpclib/__pycache__/jsonrpc.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/jsonrpclib/__pycache__/jsonrpc.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/exchange_rate.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/exchange_rate.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/paymentrequest.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/paymentrequest.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/paymentrequest.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/paymentrequest.cpython-36.pyc -------------------------------------------------------------------------------- /lib/__pycache__/simple_config.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/simple_config.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/CNAME.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/CNAME.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/NSEC.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/NSEC.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/NSEC3.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/NSEC3.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/RRSIG.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/RRSIG.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /jsonrpclib/__pycache__/jsonclass.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/jsonrpclib/__pycache__/jsonclass.cpython-35.pyc -------------------------------------------------------------------------------- /jsonrpclib/__pycache__/threadpool.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/jsonrpclib/__pycache__/threadpool.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/DNSKEY.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/DNSKEY.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/IN/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/IN/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /dns/rdtypes/__pycache__/dnskeybase.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/__pycache__/dnskeybase.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/paymentrequest_pb2.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/paymentrequest_pb2.cpython-35.pyc -------------------------------------------------------------------------------- /lib/__pycache__/paymentrequest_pb2.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/lib/__pycache__/paymentrequest_pb2.cpython-36.pyc -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/dns/rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-35.pyc -------------------------------------------------------------------------------- /jsonrpclib/__pycache__/SimpleJSONRPCServer.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleimana/bip39-bruteforce/HEAD/jsonrpclib/__pycache__/SimpleJSONRPCServer.cpython-35.pyc -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | idna==2.6 2 | pyaes==1.6.1 3 | ecdsa==0.13 4 | pbkdf2==1.3 5 | hidapi==0.7.99.post21 6 | requests==2.18.4 7 | pycrypto==2.6.1 8 | python_cjson==1.2.1 9 | electrum==0 10 | protobuf==3.5.0.post1 11 | hid==0.1.1 12 | jnius==1.1.0 13 | matplotlib==2.1.1 14 | simplejson==3.13.2 15 | win_inet_pton==1.0.1 16 | -------------------------------------------------------------------------------- /lib/version.py: -------------------------------------------------------------------------------- 1 | ELECTRUM_VERSION = '3.0.2' # version of the client package 2 | PROTOCOL_VERSION = '1.1' # protocol version requested 3 | 4 | # The hash of the mnemonic seed must begin with this 5 | SEED_PREFIX = '01' # Standard wallet 6 | SEED_PREFIX_2FA = '101' # Two-factor authentication 7 | SEED_PREFIX_SW = '100' # Segwit wallet 8 | 9 | 10 | def seed_prefix(seed_type): 11 | if seed_type == 'standard': 12 | return SEED_PREFIX 13 | elif seed_type == 'segwit': 14 | return SEED_PREFIX_SW 15 | elif seed_type == '2fa': 16 | return SEED_PREFIX_2FA 17 | -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- 1 | from .version import ELECTRUM_VERSION 2 | from .util import format_satoshis, print_msg, print_error, set_verbosity 3 | from .wallet import Synchronizer, Wallet 4 | from .storage import WalletStorage 5 | from .coinchooser import COIN_CHOOSERS 6 | from .network import Network, pick_random_server 7 | from .interface import Connection, Interface 8 | from .simple_config import SimpleConfig, get_config, set_config 9 | from . import bitcoin 10 | from . import transaction 11 | from . import daemon 12 | from .transaction import Transaction 13 | from .plugins import BasePlugin 14 | from .commands import Commands, known_commands 15 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/DLV.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.dsbase 17 | 18 | 19 | class DLV(dns.rdtypes.dsbase.DSBase): 20 | 21 | """DLV record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/CDS.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.dsbase 17 | 18 | 19 | class CDS(dns.rdtypes.dsbase.DSBase): 20 | 21 | """CDS record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/DS.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.dsbase 17 | 18 | 19 | class DS(dns.rdtypes.dsbase.DSBase): 20 | 21 | """DS record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/MX.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.mxbase 17 | 18 | 19 | class MX(dns.rdtypes.mxbase.MXBase): 20 | 21 | """MX record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/NS.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.nsbase 17 | 18 | 19 | class NS(dns.rdtypes.nsbase.NSBase): 20 | 21 | """NS record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/PTR.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.nsbase 17 | 18 | 19 | class PTR(dns.rdtypes.nsbase.NSBase): 20 | 21 | """PTR record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/TXT.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.txtbase 17 | 18 | 19 | class TXT(dns.rdtypes.txtbase.TXTBase): 20 | 21 | """TXT record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/KX.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.mxbase 17 | 18 | 19 | class KX(dns.rdtypes.mxbase.UncompressedMX): 20 | 21 | """KX record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/RT.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.mxbase 17 | 18 | 19 | class RT(dns.rdtypes.mxbase.UncompressedDowncasingMX): 20 | 21 | """RT record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/NSAP_PTR.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.nsbase 17 | 18 | 19 | class NSAP_PTR(dns.rdtypes.nsbase.UncompressedNS): 20 | 21 | """NSAP-PTR record""" 22 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/SPF.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.txtbase 17 | 18 | 19 | class SPF(dns.rdtypes.txtbase.TXTBase): 20 | 21 | """SPF record 22 | 23 | @see: RFC 4408""" 24 | -------------------------------------------------------------------------------- /dns/rdtypes/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS rdata type classes""" 17 | 18 | __all__ = [ 19 | 'ANY', 20 | 'IN', 21 | 'euibase', 22 | 'mxbase', 23 | 'nsbase', 24 | ] 25 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/AVC.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2016 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.txtbase 17 | 18 | 19 | class AVC(dns.rdtypes.txtbase.TXTBase): 20 | 21 | """AVC record 22 | 23 | @see: U{http://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template}""" 24 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/DNAME.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.nsbase 17 | 18 | 19 | class DNAME(dns.rdtypes.nsbase.UncompressedNS): 20 | 21 | """DNAME record""" 22 | 23 | def to_digestable(self, origin=None): 24 | return self.target.to_digestable(origin) 25 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """Class IN rdata type classes.""" 17 | 18 | __all__ = [ 19 | 'A', 20 | 'AAAA', 21 | 'APL', 22 | 'DHCID', 23 | 'KX', 24 | 'NAPTR', 25 | 'NSAP', 26 | 'NSAP_PTR', 27 | 'PX', 28 | 'SRV', 29 | 'WKS', 30 | ] 31 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/CDNSKEY.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.dnskeybase 17 | from dns.rdtypes.dnskeybase import flags_to_text_set, flags_from_text_set 18 | 19 | 20 | __all__ = ['flags_to_text_set', 'flags_from_text_set'] 21 | 22 | 23 | class CDNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase): 24 | 25 | """CDNSKEY record""" 26 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/DNSKEY.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.dnskeybase 17 | from dns.rdtypes.dnskeybase import flags_to_text_set, flags_from_text_set 18 | 19 | 20 | __all__ = ['flags_to_text_set', 'flags_from_text_set'] 21 | 22 | 23 | class DNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase): 24 | 25 | """DNSKEY record""" 26 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/CNAME.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.nsbase 17 | 18 | 19 | class CNAME(dns.rdtypes.nsbase.NSBase): 20 | 21 | """CNAME record 22 | 23 | Note: although CNAME is officially a singleton type, dnspython allows 24 | non-singleton CNAME rdatasets because such sets have been commonly 25 | used by BIND and other nameservers for load balancing.""" 26 | -------------------------------------------------------------------------------- /dns/hash.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """Hashing backwards compatibility wrapper""" 17 | 18 | import hashlib 19 | 20 | 21 | hashes = {} 22 | hashes['MD5'] = hashlib.md5 23 | hashes['SHA1'] = hashlib.sha1 24 | hashes['SHA224'] = hashlib.sha224 25 | hashes['SHA256'] = hashlib.sha256 26 | hashes['SHA384'] = hashlib.sha384 27 | hashes['SHA512'] = hashlib.sha512 28 | 29 | 30 | def get(algorithm): 31 | return hashes[algorithm.upper()] 32 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/EUI48.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Red Hat, Inc. 2 | # Author: Petr Spacek 3 | # 4 | # Permission to use, copy, modify, and distribute this software and its 5 | # documentation for any purpose with or without fee is hereby granted, 6 | # provided that the above copyright notice and this permission notice 7 | # appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | 17 | import dns.rdtypes.euibase 18 | 19 | 20 | class EUI48(dns.rdtypes.euibase.EUIBase): 21 | 22 | """EUI48 record 23 | 24 | @ivar fingerprint: 48-bit Extended Unique Identifier (EUI-48) 25 | @type fingerprint: string 26 | @see: rfc7043.txt""" 27 | 28 | byte_len = 6 # 0123456789ab (in hex) 29 | text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab 30 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/EUI64.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Red Hat, Inc. 2 | # Author: Petr Spacek 3 | # 4 | # Permission to use, copy, modify, and distribute this software and its 5 | # documentation for any purpose with or without fee is hereby granted, 6 | # provided that the above copyright notice and this permission notice 7 | # appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | 17 | import dns.rdtypes.euibase 18 | 19 | 20 | class EUI64(dns.rdtypes.euibase.EUIBase): 21 | 22 | """EUI64 record 23 | 24 | @ivar fingerprint: 64-bit Extended Unique Identifier (EUI-64) 25 | @type fingerprint: string 26 | @see: rfc7043.txt""" 27 | 28 | byte_len = 8 # 0123456789abcdef (in hex) 29 | text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab-cd-ef 30 | -------------------------------------------------------------------------------- /jsonrpclib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -- Content-Encoding: UTF-8 -- 3 | """ 4 | Aliases to ease access to jsonrpclib classes 5 | 6 | :authors: Josh Marshall, Thomas Calmant 7 | :copyright: Copyright 2017, Thomas Calmant 8 | :license: Apache License 2.0 9 | :version: 0.3.1 10 | 11 | .. 12 | 13 | Copyright 2017 Thomas Calmant 14 | 15 | Licensed under the Apache License, Version 2.0 (the "License"); 16 | you may not use this file except in compliance with the License. 17 | You may obtain a copy of the License at 18 | 19 | http://www.apache.org/licenses/LICENSE-2.0 20 | 21 | Unless required by applicable law or agreed to in writing, software 22 | distributed under the License is distributed on an "AS IS" BASIS, 23 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | See the License for the specific language governing permissions and 25 | limitations under the License. 26 | """ 27 | 28 | # Easy access to utility methods and classes 29 | from jsonrpclib.jsonrpc import Server, ServerProxy 30 | from jsonrpclib.jsonrpc import MultiCall, Fault, ProtocolError, AppError 31 | from jsonrpclib.jsonrpc import loads, dumps, load, dump 32 | from jsonrpclib.jsonrpc import jloads, jdumps 33 | import jsonrpclib.history as history 34 | import jsonrpclib.utils as utils 35 | -------------------------------------------------------------------------------- /dns/version.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """dnspython release version information.""" 17 | 18 | MAJOR = 1 19 | MINOR = 15 20 | MICRO = 0 21 | RELEASELEVEL = 0x0f 22 | SERIAL = 0 23 | 24 | if RELEASELEVEL == 0x0f: 25 | version = '%d.%d.%d' % (MAJOR, MINOR, MICRO) 26 | elif RELEASELEVEL == 0x00: 27 | version = '%d.%d.%dx%d' % \ 28 | (MAJOR, MINOR, MICRO, SERIAL) 29 | else: 30 | version = '%d.%d.%d%x%d' % \ 31 | (MAJOR, MINOR, MICRO, RELEASELEVEL, SERIAL) 32 | 33 | hexversion = MAJOR << 24 | MINOR << 16 | MICRO << 8 | RELEASELEVEL << 4 | \ 34 | SERIAL 35 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """Class ANY (generic) rdata type classes.""" 17 | 18 | __all__ = [ 19 | 'AFSDB', 20 | 'CDNSKEY', 21 | 'CDS', 22 | 'CERT', 23 | 'CNAME', 24 | 'DLV', 25 | 'DNAME', 26 | 'DNSKEY', 27 | 'DS', 28 | 'EUI48', 29 | 'EUI64', 30 | 'GPOS', 31 | 'HINFO', 32 | 'HIP', 33 | 'ISDN', 34 | 'LOC', 35 | 'MX', 36 | 'NS', 37 | 'NSEC', 38 | 'NSEC3', 39 | 'NSEC3PARAM', 40 | 'TLSA', 41 | 'PTR', 42 | 'RP', 43 | 'RRSIG', 44 | 'RT', 45 | 'SOA', 46 | 'SPF', 47 | 'SSHFP', 48 | 'TXT', 49 | 'X25', 50 | ] 51 | -------------------------------------------------------------------------------- /dns/_compat.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import decimal 3 | from decimal import Context 4 | 5 | if sys.version_info > (3,): 6 | long = int 7 | xrange = range 8 | else: 9 | long = long # pylint: disable=long-builtin 10 | xrange = xrange # pylint: disable=xrange-builtin 11 | 12 | # unicode / binary types 13 | if sys.version_info > (3,): 14 | text_type = str 15 | binary_type = bytes 16 | string_types = (str,) 17 | unichr = chr 18 | def maybe_decode(x): 19 | return x.decode() 20 | def maybe_encode(x): 21 | return x.encode() 22 | else: 23 | text_type = unicode # pylint: disable=unicode-builtin, undefined-variable 24 | binary_type = str 25 | string_types = ( 26 | basestring, # pylint: disable=basestring-builtin, undefined-variable 27 | ) 28 | unichr = unichr # pylint: disable=unichr-builtin 29 | def maybe_decode(x): 30 | return x 31 | def maybe_encode(x): 32 | return x 33 | 34 | 35 | def round_py2_compat(what): 36 | """ 37 | Python 2 and Python 3 use different rounding strategies in round(). This 38 | function ensures that results are python2/3 compatible and backward 39 | compatible with previous py2 releases 40 | :param what: float 41 | :return: rounded long 42 | """ 43 | d = Context( 44 | prec=len(str(long(what))), # round to integer with max precision 45 | rounding=decimal.ROUND_HALF_UP 46 | ).create_decimal(str(what)) # str(): python 2.6 compat 47 | return long(d) 48 | -------------------------------------------------------------------------------- /dns/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009, 2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """dnspython DNS toolkit""" 17 | 18 | __all__ = [ 19 | 'dnssec', 20 | 'e164', 21 | 'edns', 22 | 'entropy', 23 | 'exception', 24 | 'flags', 25 | 'hash', 26 | 'inet', 27 | 'ipv4', 28 | 'ipv6', 29 | 'message', 30 | 'name', 31 | 'namedict', 32 | 'node', 33 | 'opcode', 34 | 'query', 35 | 'rcode', 36 | 'rdata', 37 | 'rdataclass', 38 | 'rdataset', 39 | 'rdatatype', 40 | 'renderer', 41 | 'resolver', 42 | 'reversename', 43 | 'rrset', 44 | 'set', 45 | 'tokenizer', 46 | 'tsig', 47 | 'tsigkeyring', 48 | 'ttl', 49 | 'rdtypes', 50 | 'update', 51 | 'version', 52 | 'wiredata', 53 | 'zone', 54 | ] 55 | -------------------------------------------------------------------------------- /dns/tsigkeyring.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """A place to store TSIG keys.""" 17 | 18 | from dns._compat import maybe_decode, maybe_encode 19 | 20 | import base64 21 | 22 | import dns.name 23 | 24 | 25 | def from_text(textring): 26 | """Convert a dictionary containing (textual DNS name, base64 secret) pairs 27 | into a binary keyring which has (dns.name.Name, binary secret) pairs. 28 | @rtype: dict""" 29 | 30 | keyring = {} 31 | for keytext in textring: 32 | keyname = dns.name.from_text(keytext) 33 | secret = base64.decodestring(maybe_encode(textring[keytext])) 34 | keyring[keyname] = secret 35 | return keyring 36 | 37 | 38 | def to_text(keyring): 39 | """Convert a dictionary containing (dns.name.Name, binary secret) pairs 40 | into a text keyring which has (textual DNS name, base64 secret) pairs. 41 | @rtype: dict""" 42 | 43 | textring = {} 44 | for keyname in keyring: 45 | keytext = maybe_decode(keyname.to_text()) 46 | secret = maybe_decode(base64.encodestring(keyring[keyname])) 47 | textring[keytext] = secret 48 | return textring 49 | -------------------------------------------------------------------------------- /brute.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python3 2 | import sys 3 | from lib.keystore import from_bip39_seed 4 | from lib.storage import WalletStorage 5 | from lib.wallet import Standard_Wallet 6 | from itertools import permutations 7 | 8 | seed_words = '' 9 | address = '' 10 | start_index = 1250 11 | dictionary = '' 12 | attack_type = 2 #[0=>'pin_sequential', 1=>'pin_permutation', 2=>'dictionary'] 13 | 14 | def _create_standard_wallet(ks): 15 | gap_limit = 1 # make tests run faster 16 | store = WalletStorage('if_this_exists_mocking_failed_648151893') 17 | store.put('keystore', ks.dump()) 18 | store.put('gap_limit', gap_limit) 19 | w = Standard_Wallet(store) 20 | w.synchronize() 21 | return w 22 | 23 | 24 | def check_bip39_seed_bip49_p2sh_segwit(password, index): 25 | ks = from_bip39_seed(seed_words, password, "m/49'/0'/0'") 26 | w = _create_standard_wallet(ks) 27 | addr = w.get_receiving_addresses()[0] 28 | 29 | if (addr == address): 30 | print(index + '\t PASSWORD FOUND: ' + password) 31 | return True 32 | else: 33 | print(index + '\t' + str(addr) + '\t' + password) 34 | return False 35 | 36 | def readDic (dic): 37 | with open(dic) as f: 38 | content = f.readlines() 39 | content = [x.strip() for x in content] 40 | return content 41 | 42 | if (attack_type == 0): 43 | for i in range(0, 9999): 44 | pwd = str(i).zfill(4) 45 | print() 46 | # check_bip39_seed_bip49_p2sh_segwit(str(pwd),str(i)) 47 | 48 | elif(attack_type == 1): 49 | pin = '1 2 3 4 5 6 7 8 9' 50 | words = pin.split() 51 | i = 0 52 | for p in permutations(words, 9): 53 | i = i + 1 54 | if (i < start_index): 55 | continue 56 | pwd = "".join(str(x) for x in p) 57 | check_bip39_seed_bip49_p2sh_segwit(str(pwd), str(i)) 58 | 59 | elif(attack_type == 2): 60 | w = readDic('bip39list.txt') 61 | for i in range(0, 2048): 62 | check_bip39_seed_bip49_p2sh_segwit(str(w[i]), str(i)) 63 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/A.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.exception 17 | import dns.ipv4 18 | import dns.rdata 19 | import dns.tokenizer 20 | 21 | 22 | class A(dns.rdata.Rdata): 23 | 24 | """A record. 25 | 26 | @ivar address: an IPv4 address 27 | @type address: string (in the standard "dotted quad" format)""" 28 | 29 | __slots__ = ['address'] 30 | 31 | def __init__(self, rdclass, rdtype, address): 32 | super(A, self).__init__(rdclass, rdtype) 33 | # check that it's OK 34 | dns.ipv4.inet_aton(address) 35 | self.address = address 36 | 37 | def to_text(self, origin=None, relativize=True, **kw): 38 | return self.address 39 | 40 | @classmethod 41 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 42 | address = tok.get_identifier() 43 | tok.get_eol() 44 | return cls(rdclass, rdtype, address) 45 | 46 | def to_wire(self, file, compress=None, origin=None): 47 | file.write(dns.ipv4.inet_aton(self.address)) 48 | 49 | @classmethod 50 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 51 | address = dns.ipv4.inet_ntoa(wire[current: current + rdlen]).decode() 52 | return cls(rdclass, rdtype, address) 53 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/AFSDB.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.rdtypes.mxbase 17 | 18 | 19 | class AFSDB(dns.rdtypes.mxbase.UncompressedDowncasingMX): 20 | 21 | """AFSDB record 22 | 23 | @ivar subtype: the subtype value 24 | @type subtype: int 25 | @ivar hostname: the hostname name 26 | @type hostname: dns.name.Name object""" 27 | 28 | # Use the property mechanism to make "subtype" an alias for the 29 | # "preference" attribute, and "hostname" an alias for the "exchange" 30 | # attribute. 31 | # 32 | # This lets us inherit the UncompressedMX implementation but lets 33 | # the caller use appropriate attribute names for the rdata type. 34 | # 35 | # We probably lose some performance vs. a cut-and-paste 36 | # implementation, but this way we don't copy code, and that's 37 | # good. 38 | 39 | def get_subtype(self): 40 | return self.preference 41 | 42 | def set_subtype(self, subtype): 43 | self.preference = subtype 44 | 45 | subtype = property(get_subtype, set_subtype) 46 | 47 | def get_hostname(self): 48 | return self.exchange 49 | 50 | def set_hostname(self, hostname): 51 | self.exchange = hostname 52 | 53 | hostname = property(get_hostname, set_hostname) 54 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/AAAA.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.exception 17 | import dns.inet 18 | import dns.rdata 19 | import dns.tokenizer 20 | 21 | 22 | class AAAA(dns.rdata.Rdata): 23 | 24 | """AAAA record. 25 | 26 | @ivar address: an IPv6 address 27 | @type address: string (in the standard IPv6 format)""" 28 | 29 | __slots__ = ['address'] 30 | 31 | def __init__(self, rdclass, rdtype, address): 32 | super(AAAA, self).__init__(rdclass, rdtype) 33 | # check that it's OK 34 | dns.inet.inet_pton(dns.inet.AF_INET6, address) 35 | self.address = address 36 | 37 | def to_text(self, origin=None, relativize=True, **kw): 38 | return self.address 39 | 40 | @classmethod 41 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 42 | address = tok.get_identifier() 43 | tok.get_eol() 44 | return cls(rdclass, rdtype, address) 45 | 46 | def to_wire(self, file, compress=None, origin=None): 47 | file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.address)) 48 | 49 | @classmethod 50 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 51 | address = dns.inet.inet_ntop(dns.inet.AF_INET6, 52 | wire[current: current + rdlen]) 53 | return cls(rdclass, rdtype, address) 54 | -------------------------------------------------------------------------------- /dns/grange.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS GENERATE range conversion.""" 17 | 18 | import dns 19 | 20 | 21 | def from_text(text): 22 | """Convert the text form of a range in a GENERATE statement to an 23 | integer. 24 | 25 | @param text: the textual range 26 | @type text: string 27 | @return: The start, stop and step values. 28 | @rtype: tuple 29 | """ 30 | # TODO, figure out the bounds on start, stop and step. 31 | 32 | step = 1 33 | cur = '' 34 | state = 0 35 | # state 0 1 2 3 4 36 | # x - y / z 37 | 38 | if text and text[0] == '-': 39 | raise dns.exception.SyntaxError("Start cannot be a negative number") 40 | 41 | for c in text: 42 | if c == '-' and state == 0: 43 | start = int(cur) 44 | cur = '' 45 | state = 2 46 | elif c == '/': 47 | stop = int(cur) 48 | cur = '' 49 | state = 4 50 | elif c.isdigit(): 51 | cur += c 52 | else: 53 | raise dns.exception.SyntaxError("Could not parse %s" % (c)) 54 | 55 | if state in (1, 3): 56 | raise dns.exception.SyntaxError() 57 | 58 | if state == 2: 59 | stop = int(cur) 60 | 61 | if state == 4: 62 | step = int(cur) 63 | 64 | assert step >= 1 65 | assert start >= 0 66 | assert start <= stop 67 | # TODO, can start == stop? 68 | 69 | return (start, stop, step) 70 | -------------------------------------------------------------------------------- /dns/ipv4.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """IPv4 helper functions.""" 17 | 18 | import struct 19 | 20 | import dns.exception 21 | from ._compat import binary_type 22 | 23 | def inet_ntoa(address): 24 | """Convert an IPv4 address in network form to text form. 25 | 26 | @param address: The IPv4 address 27 | @type address: string 28 | @returns: string 29 | """ 30 | if len(address) != 4: 31 | raise dns.exception.SyntaxError 32 | if not isinstance(address, bytearray): 33 | address = bytearray(address) 34 | return (u'%u.%u.%u.%u' % (address[0], address[1], 35 | address[2], address[3])).encode() 36 | 37 | def inet_aton(text): 38 | """Convert an IPv4 address in text form to network form. 39 | 40 | @param text: The IPv4 address 41 | @type text: string 42 | @returns: string 43 | """ 44 | if not isinstance(text, binary_type): 45 | text = text.encode() 46 | parts = text.split(b'.') 47 | if len(parts) != 4: 48 | raise dns.exception.SyntaxError 49 | for part in parts: 50 | if not part.isdigit(): 51 | raise dns.exception.SyntaxError 52 | if len(part) > 1 and part[0] == '0': 53 | # No leading zeros 54 | raise dns.exception.SyntaxError 55 | try: 56 | bytes = [int(part) for part in parts] 57 | return struct.pack('BBBB', *bytes) 58 | except: 59 | raise dns.exception.SyntaxError 60 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/DHCID.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import base64 17 | 18 | import dns.exception 19 | 20 | 21 | class DHCID(dns.rdata.Rdata): 22 | 23 | """DHCID record 24 | 25 | @ivar data: the data (the content of the RR is opaque as far as the 26 | DNS is concerned) 27 | @type data: string 28 | @see: RFC 4701""" 29 | 30 | __slots__ = ['data'] 31 | 32 | def __init__(self, rdclass, rdtype, data): 33 | super(DHCID, self).__init__(rdclass, rdtype) 34 | self.data = data 35 | 36 | def to_text(self, origin=None, relativize=True, **kw): 37 | return dns.rdata._base64ify(self.data) 38 | 39 | @classmethod 40 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 41 | chunks = [] 42 | while 1: 43 | t = tok.get().unescape() 44 | if t.is_eol_or_eof(): 45 | break 46 | if not t.is_identifier(): 47 | raise dns.exception.SyntaxError 48 | chunks.append(t.value.encode()) 49 | b64 = b''.join(chunks) 50 | data = base64.b64decode(b64) 51 | return cls(rdclass, rdtype, data) 52 | 53 | def to_wire(self, file, compress=None, origin=None): 54 | file.write(self.data) 55 | 56 | @classmethod 57 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 58 | data = wire[current: current + rdlen].unwrap() 59 | return cls(rdclass, rdtype, data) 60 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/NSAP.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import binascii 17 | 18 | import dns.exception 19 | import dns.rdata 20 | import dns.tokenizer 21 | 22 | 23 | class NSAP(dns.rdata.Rdata): 24 | 25 | """NSAP record. 26 | 27 | @ivar address: a NASP 28 | @type address: string 29 | @see: RFC 1706""" 30 | 31 | __slots__ = ['address'] 32 | 33 | def __init__(self, rdclass, rdtype, address): 34 | super(NSAP, self).__init__(rdclass, rdtype) 35 | self.address = address 36 | 37 | def to_text(self, origin=None, relativize=True, **kw): 38 | return "0x%s" % binascii.hexlify(self.address).decode() 39 | 40 | @classmethod 41 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 42 | address = tok.get_string() 43 | tok.get_eol() 44 | if address[0:2] != '0x': 45 | raise dns.exception.SyntaxError('string does not start with 0x') 46 | address = address[2:].replace('.', '') 47 | if len(address) % 2 != 0: 48 | raise dns.exception.SyntaxError('hexstring has odd length') 49 | address = binascii.unhexlify(address.encode()) 50 | return cls(rdclass, rdtype, address) 51 | 52 | def to_wire(self, file, compress=None, origin=None): 53 | file.write(self.address) 54 | 55 | @classmethod 56 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 57 | address = wire[current: current + rdlen].unwrap() 58 | return cls(rdclass, rdtype, address) 59 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/X25.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | 18 | import dns.exception 19 | import dns.rdata 20 | import dns.tokenizer 21 | from dns._compat import text_type 22 | 23 | 24 | class X25(dns.rdata.Rdata): 25 | 26 | """X25 record 27 | 28 | @ivar address: the PSDN address 29 | @type address: string 30 | @see: RFC 1183""" 31 | 32 | __slots__ = ['address'] 33 | 34 | def __init__(self, rdclass, rdtype, address): 35 | super(X25, self).__init__(rdclass, rdtype) 36 | if isinstance(address, text_type): 37 | self.address = address.encode() 38 | else: 39 | self.address = address 40 | 41 | def to_text(self, origin=None, relativize=True, **kw): 42 | return '"%s"' % dns.rdata._escapify(self.address) 43 | 44 | @classmethod 45 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 46 | address = tok.get_string() 47 | tok.get_eol() 48 | return cls(rdclass, rdtype, address) 49 | 50 | def to_wire(self, file, compress=None, origin=None): 51 | l = len(self.address) 52 | assert l < 256 53 | file.write(struct.pack('!B', l)) 54 | file.write(self.address) 55 | 56 | @classmethod 57 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 58 | l = wire[current] 59 | current += 1 60 | rdlen -= 1 61 | if l != rdlen: 62 | raise dns.exception.FormError 63 | address = wire[current: current + l].unwrap() 64 | return cls(rdclass, rdtype, address) 65 | -------------------------------------------------------------------------------- /dns/ttl.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS TTL conversion.""" 17 | 18 | import dns.exception 19 | from ._compat import long 20 | 21 | 22 | class BadTTL(dns.exception.SyntaxError): 23 | 24 | """DNS TTL value is not well-formed.""" 25 | 26 | 27 | def from_text(text): 28 | """Convert the text form of a TTL to an integer. 29 | 30 | The BIND 8 units syntax for TTLs (e.g. '1w6d4h3m10s') is supported. 31 | 32 | @param text: the textual TTL 33 | @type text: string 34 | @raises dns.ttl.BadTTL: the TTL is not well-formed 35 | @rtype: int 36 | """ 37 | 38 | if text.isdigit(): 39 | total = long(text) 40 | else: 41 | if not text[0].isdigit(): 42 | raise BadTTL 43 | total = long(0) 44 | current = long(0) 45 | for c in text: 46 | if c.isdigit(): 47 | current *= 10 48 | current += long(c) 49 | else: 50 | c = c.lower() 51 | if c == 'w': 52 | total += current * long(604800) 53 | elif c == 'd': 54 | total += current * long(86400) 55 | elif c == 'h': 56 | total += current * long(3600) 57 | elif c == 'm': 58 | total += current * long(60) 59 | elif c == 's': 60 | total += current 61 | else: 62 | raise BadTTL("unknown unit '%s'" % c) 63 | current = 0 64 | if not current == 0: 65 | raise BadTTL("trailing integer") 66 | if total < long(0) or total > long(2147483647): 67 | raise BadTTL("TTL should be between 0 and 2^31 - 1 (inclusive)") 68 | return total 69 | -------------------------------------------------------------------------------- /lib/i18n.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Electrum - lightweight Bitcoin client 4 | # Copyright (C) 2012 thomasv@gitorious 5 | # 6 | # Permission is hereby granted, free of charge, to any person 7 | # obtaining a copy of this software and associated documentation files 8 | # (the "Software"), to deal in the Software without restriction, 9 | # including without limitation the rights to use, copy, modify, merge, 10 | # publish, distribute, sublicense, and/or sell copies of the Software, 11 | # and to permit persons to whom the Software is furnished to do so, 12 | # subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | import gettext, os 26 | 27 | LOCALE_DIR = os.path.join(os.path.dirname(__file__), 'locale') 28 | language = gettext.translation('electrum', LOCALE_DIR, fallback = True) 29 | 30 | def _(x): 31 | global language 32 | return language.gettext(x) 33 | 34 | def set_language(x): 35 | global language 36 | if x: language = gettext.translation('electrum', LOCALE_DIR, fallback = True, languages=[x]) 37 | 38 | 39 | languages = { 40 | '':_('Default'), 41 | 'ar_SA':_('Arabic'), 42 | 'cs_CZ':_('Czech'), 43 | 'da_DK':_('Danish'), 44 | 'de_DE':_('German'), 45 | 'eo_UY':_('Esperanto'), 46 | 'el_GR':_('Greek'), 47 | 'en_UK':_('English'), 48 | 'es_ES':_('Spanish'), 49 | 'fr_FR':_('French'), 50 | 'hu_HU':_('Hungarian'), 51 | 'hy_AM':_('Armenian'), 52 | 'id_ID':_('Indonesian'), 53 | 'it_IT':_('Italian'), 54 | 'ja_JP':_('Japanese'), 55 | 'ky_KG':_('Kyrgyz'), 56 | 'lv_LV':_('Latvian'), 57 | 'nl_NL':_('Dutch'), 58 | 'no_NO':_('Norwegian'), 59 | 'pl_PL':_('Polish'), 60 | 'pt_BR':_('Brasilian'), 61 | 'pt_PT':_('Portuguese'), 62 | 'ro_RO':_('Romanian'), 63 | 'ru_RU':_('Russian'), 64 | 'sk_SK':_('Slovak'), 65 | 'sl_SI':_('Slovenian'), 66 | 'ta_IN':_('Tamil'), 67 | 'th_TH':_('Thai'), 68 | 'vi_VN':_('Vietnamese'), 69 | 'zh_CN':_('Chinese') 70 | } 71 | -------------------------------------------------------------------------------- /lib/msqr.py: -------------------------------------------------------------------------------- 1 | # from http://eli.thegreenplace.net/2009/03/07/computing-modular-square-roots-in-python/ 2 | 3 | def modular_sqrt(a, p): 4 | """ Find a quadratic residue (mod p) of 'a'. p 5 | must be an odd prime. 6 | 7 | Solve the congruence of the form: 8 | x^2 = a (mod p) 9 | And returns x. Note that p - x is also a root. 10 | 11 | 0 is returned is no square root exists for 12 | these a and p. 13 | 14 | The Tonelli-Shanks algorithm is used (except 15 | for some simple cases in which the solution 16 | is known from an identity). This algorithm 17 | runs in polynomial time (unless the 18 | generalized Riemann hypothesis is false). 19 | """ 20 | # Simple cases 21 | # 22 | if legendre_symbol(a, p) != 1: 23 | return 0 24 | elif a == 0: 25 | return 0 26 | elif p == 2: 27 | return p 28 | elif p % 4 == 3: 29 | return pow(a, (p + 1) // 4, p) 30 | 31 | # Partition p-1 to s * 2^e for an odd s (i.e. 32 | # reduce all the powers of 2 from p-1) 33 | # 34 | s = p - 1 35 | e = 0 36 | while s % 2 == 0: 37 | s //= 2 38 | e += 1 39 | 40 | # Find some 'n' with a legendre symbol n|p = -1. 41 | # Shouldn't take long. 42 | # 43 | n = 2 44 | while legendre_symbol(n, p) != -1: 45 | n += 1 46 | 47 | # Here be dragons! 48 | # Read the paper "Square roots from 1; 24, 51, 49 | # 10 to Dan Shanks" by Ezra Brown for more 50 | # information 51 | # 52 | 53 | # x is a guess of the square root that gets better 54 | # with each iteration. 55 | # b is the "fudge factor" - by how much we're off 56 | # with the guess. The invariant x^2 = ab (mod p) 57 | # is maintained throughout the loop. 58 | # g is used for successive powers of n to update 59 | # both a and b 60 | # r is the exponent - decreases with each update 61 | # 62 | x = pow(a, (s + 1) // 2, p) 63 | b = pow(a, s, p) 64 | g = pow(n, s, p) 65 | r = e 66 | 67 | while True: 68 | t = b 69 | m = 0 70 | for m in range(r): 71 | if t == 1: 72 | break 73 | t = pow(t, 2, p) 74 | 75 | if m == 0: 76 | return x 77 | 78 | gs = pow(g, 2 ** (r - m - 1), p) 79 | g = (gs * gs) % p 80 | x = (x * gs) % p 81 | b = (b * g) % p 82 | r = m 83 | 84 | def legendre_symbol(a, p): 85 | """ Compute the Legendre symbol a|p using 86 | Euler's criterion. p is a prime, a is 87 | relatively prime to p (if p divides 88 | a, then a|p = 0) 89 | 90 | Returns 1 if a has a square root modulo 91 | p, -1 otherwise. 92 | """ 93 | ls = pow(a, (p - 1) // 2, p) 94 | return -1 if ls == p - 1 else ls 95 | -------------------------------------------------------------------------------- /jsonrpclib/history.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -- Content-Encoding: UTF-8 -- 3 | """ 4 | The history module. 5 | 6 | :authors: Josh Marshall, Thomas Calmant 7 | :copyright: Copyright 2017, Thomas Calmant 8 | :license: Apache License 2.0 9 | :version: 0.3.1 10 | 11 | .. 12 | 13 | Copyright 2017 Thomas Calmant 14 | 15 | Licensed under the Apache License, Version 2.0 (the "License"); 16 | you may not use this file except in compliance with the License. 17 | You may obtain a copy of the License at 18 | 19 | http://www.apache.org/licenses/LICENSE-2.0 20 | 21 | Unless required by applicable law or agreed to in writing, software 22 | distributed under the License is distributed on an "AS IS" BASIS, 23 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | See the License for the specific language governing permissions and 25 | limitations under the License. 26 | """ 27 | 28 | # Module version 29 | __version_info__ = (0, 3, 1) 30 | __version__ = ".".join(str(x) for x in __version_info__) 31 | 32 | # Documentation strings format 33 | __docformat__ = "restructuredtext en" 34 | 35 | # ------------------------------------------------------------------------------ 36 | 37 | 38 | class History(object): 39 | """ 40 | This holds all the response and request objects for a 41 | session. A server using this should call "clear" after 42 | each request cycle in order to keep it from clogging 43 | memory. 44 | """ 45 | def __init__(self): 46 | """ 47 | Sets up members 48 | """ 49 | self.requests = [] 50 | self.responses = [] 51 | 52 | def add_response(self, response_obj): 53 | """ 54 | Adds a response to the history 55 | 56 | :param response_obj: Response content 57 | """ 58 | self.responses.append(response_obj) 59 | 60 | def add_request(self, request_obj): 61 | """ 62 | Adds a request to the history 63 | 64 | :param request_obj: A request object 65 | """ 66 | self.requests.append(request_obj) 67 | 68 | @property 69 | def request(self): 70 | """ 71 | Returns the latest stored request or None 72 | """ 73 | try: 74 | return self.requests[-1] 75 | except IndexError: 76 | return None 77 | 78 | @property 79 | def response(self): 80 | """ 81 | Returns the latest stored response or None 82 | """ 83 | try: 84 | return self.responses[-1] 85 | except IndexError: 86 | return None 87 | 88 | def clear(self): 89 | """ 90 | Clears the history lists 91 | """ 92 | del self.requests[:] 93 | del self.responses[:] 94 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/CAA.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | 18 | import dns.exception 19 | import dns.rdata 20 | import dns.tokenizer 21 | 22 | 23 | class CAA(dns.rdata.Rdata): 24 | 25 | """CAA (Certification Authority Authorization) record 26 | 27 | @ivar flags: the flags 28 | @type flags: int 29 | @ivar tag: the tag 30 | @type tag: string 31 | @ivar value: the value 32 | @type value: string 33 | @see: RFC 6844""" 34 | 35 | __slots__ = ['flags', 'tag', 'value'] 36 | 37 | def __init__(self, rdclass, rdtype, flags, tag, value): 38 | super(CAA, self).__init__(rdclass, rdtype) 39 | self.flags = flags 40 | self.tag = tag 41 | self.value = value 42 | 43 | def to_text(self, origin=None, relativize=True, **kw): 44 | return '%u %s "%s"' % (self.flags, 45 | dns.rdata._escapify(self.tag), 46 | dns.rdata._escapify(self.value)) 47 | 48 | @classmethod 49 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 50 | flags = tok.get_uint8() 51 | tag = tok.get_string().encode() 52 | if len(tag) > 255: 53 | raise dns.exception.SyntaxError("tag too long") 54 | if not tag.isalnum(): 55 | raise dns.exception.SyntaxError("tag is not alphanumeric") 56 | value = tok.get_string().encode() 57 | return cls(rdclass, rdtype, flags, tag, value) 58 | 59 | def to_wire(self, file, compress=None, origin=None): 60 | file.write(struct.pack('!B', self.flags)) 61 | l = len(self.tag) 62 | assert l < 256 63 | file.write(struct.pack('!B', l)) 64 | file.write(self.tag) 65 | file.write(self.value) 66 | 67 | @classmethod 68 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 69 | (flags, l) = struct.unpack('!BB', wire[current: current + 2]) 70 | current += 2 71 | tag = wire[current: current + l] 72 | value = wire[current + l:current + rdlen - 2] 73 | return cls(rdclass, rdtype, flags, tag, value) 74 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/HINFO.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | 18 | import dns.exception 19 | import dns.rdata 20 | import dns.tokenizer 21 | from dns._compat import text_type 22 | 23 | 24 | class HINFO(dns.rdata.Rdata): 25 | 26 | """HINFO record 27 | 28 | @ivar cpu: the CPU type 29 | @type cpu: string 30 | @ivar os: the OS type 31 | @type os: string 32 | @see: RFC 1035""" 33 | 34 | __slots__ = ['cpu', 'os'] 35 | 36 | def __init__(self, rdclass, rdtype, cpu, os): 37 | super(HINFO, self).__init__(rdclass, rdtype) 38 | if isinstance(cpu, text_type): 39 | self.cpu = cpu.encode() 40 | else: 41 | self.cpu = cpu 42 | if isinstance(os, text_type): 43 | self.os = os.encode() 44 | else: 45 | self.os = os 46 | 47 | def to_text(self, origin=None, relativize=True, **kw): 48 | return '"%s" "%s"' % (dns.rdata._escapify(self.cpu), 49 | dns.rdata._escapify(self.os)) 50 | 51 | @classmethod 52 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 53 | cpu = tok.get_string() 54 | os = tok.get_string() 55 | tok.get_eol() 56 | return cls(rdclass, rdtype, cpu, os) 57 | 58 | def to_wire(self, file, compress=None, origin=None): 59 | l = len(self.cpu) 60 | assert l < 256 61 | file.write(struct.pack('!B', l)) 62 | file.write(self.cpu) 63 | l = len(self.os) 64 | assert l < 256 65 | file.write(struct.pack('!B', l)) 66 | file.write(self.os) 67 | 68 | @classmethod 69 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 70 | l = wire[current] 71 | current += 1 72 | rdlen -= 1 73 | if l > rdlen: 74 | raise dns.exception.FormError 75 | cpu = wire[current:current + l].unwrap() 76 | current += l 77 | rdlen -= l 78 | l = wire[current] 79 | current += 1 80 | rdlen -= 1 81 | if l != rdlen: 82 | raise dns.exception.FormError 83 | os = wire[current: current + l].unwrap() 84 | return cls(rdclass, rdtype, cpu, os) 85 | -------------------------------------------------------------------------------- /dns/rdtypes/euibase.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Red Hat, Inc. 2 | # Author: Petr Spacek 3 | # 4 | # Permission to use, copy, modify, and distribute this software and its 5 | # documentation for any purpose with or without fee is hereby granted, 6 | # provided that the above copyright notice and this permission notice 7 | # appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | 17 | import binascii 18 | 19 | import dns.rdata 20 | from dns._compat import xrange 21 | 22 | 23 | class EUIBase(dns.rdata.Rdata): 24 | 25 | """EUIxx record 26 | 27 | @ivar fingerprint: xx-bit Extended Unique Identifier (EUI-xx) 28 | @type fingerprint: string 29 | @see: rfc7043.txt""" 30 | 31 | __slots__ = ['eui'] 32 | # define these in subclasses 33 | # byte_len = 6 # 0123456789ab (in hex) 34 | # text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab 35 | 36 | def __init__(self, rdclass, rdtype, eui): 37 | super(EUIBase, self).__init__(rdclass, rdtype) 38 | if len(eui) != self.byte_len: 39 | raise dns.exception.FormError('EUI%s rdata has to have %s bytes' 40 | % (self.byte_len * 8, self.byte_len)) 41 | self.eui = eui 42 | 43 | def to_text(self, origin=None, relativize=True, **kw): 44 | return dns.rdata._hexify(self.eui, chunksize=2).replace(' ', '-') 45 | 46 | @classmethod 47 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 48 | text = tok.get_string() 49 | tok.get_eol() 50 | if len(text) != cls.text_len: 51 | raise dns.exception.SyntaxError( 52 | 'Input text must have %s characters' % cls.text_len) 53 | expected_dash_idxs = xrange(2, cls.byte_len * 3 - 1, 3) 54 | for i in expected_dash_idxs: 55 | if text[i] != '-': 56 | raise dns.exception.SyntaxError('Dash expected at position %s' 57 | % i) 58 | text = text.replace('-', '') 59 | try: 60 | data = binascii.unhexlify(text.encode()) 61 | except (ValueError, TypeError) as ex: 62 | raise dns.exception.SyntaxError('Hex decoding error: %s' % str(ex)) 63 | return cls(rdclass, rdtype, data) 64 | 65 | def to_wire(self, file, compress=None, origin=None): 66 | file.write(self.eui) 67 | 68 | @classmethod 69 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 70 | eui = wire[current:current + rdlen].unwrap() 71 | return cls(rdclass, rdtype, eui) 72 | -------------------------------------------------------------------------------- /dns/opcode.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2001-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS Opcodes.""" 17 | 18 | import dns.exception 19 | 20 | QUERY = 0 21 | IQUERY = 1 22 | STATUS = 2 23 | NOTIFY = 4 24 | UPDATE = 5 25 | 26 | _by_text = { 27 | 'QUERY': QUERY, 28 | 'IQUERY': IQUERY, 29 | 'STATUS': STATUS, 30 | 'NOTIFY': NOTIFY, 31 | 'UPDATE': UPDATE 32 | } 33 | 34 | # We construct the inverse mapping programmatically to ensure that we 35 | # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that 36 | # would cause the mapping not to be true inverse. 37 | 38 | _by_value = dict((y, x) for x, y in _by_text.items()) 39 | 40 | 41 | class UnknownOpcode(dns.exception.DNSException): 42 | 43 | """An DNS opcode is unknown.""" 44 | 45 | 46 | def from_text(text): 47 | """Convert text into an opcode. 48 | 49 | @param text: the textual opcode 50 | @type text: string 51 | @raises UnknownOpcode: the opcode is unknown 52 | @rtype: int 53 | """ 54 | 55 | if text.isdigit(): 56 | value = int(text) 57 | if value >= 0 and value <= 15: 58 | return value 59 | value = _by_text.get(text.upper()) 60 | if value is None: 61 | raise UnknownOpcode 62 | return value 63 | 64 | 65 | def from_flags(flags): 66 | """Extract an opcode from DNS message flags. 67 | 68 | @param flags: int 69 | @rtype: int 70 | """ 71 | 72 | return (flags & 0x7800) >> 11 73 | 74 | 75 | def to_flags(value): 76 | """Convert an opcode to a value suitable for ORing into DNS message 77 | flags. 78 | @rtype: int 79 | """ 80 | 81 | return (value << 11) & 0x7800 82 | 83 | 84 | def to_text(value): 85 | """Convert an opcode to text. 86 | 87 | @param value: the opcdoe 88 | @type value: int 89 | @raises UnknownOpcode: the opcode is unknown 90 | @rtype: string 91 | """ 92 | 93 | text = _by_value.get(value) 94 | if text is None: 95 | text = str(value) 96 | return text 97 | 98 | 99 | def is_update(flags): 100 | """True if the opcode in flags is UPDATE. 101 | 102 | @param flags: DNS flags 103 | @type flags: int 104 | @rtype: bool 105 | """ 106 | 107 | return from_flags(flags) == UPDATE 108 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/SSHFP.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2005-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | import binascii 18 | 19 | import dns.rdata 20 | import dns.rdatatype 21 | 22 | 23 | class SSHFP(dns.rdata.Rdata): 24 | 25 | """SSHFP record 26 | 27 | @ivar algorithm: the algorithm 28 | @type algorithm: int 29 | @ivar fp_type: the digest type 30 | @type fp_type: int 31 | @ivar fingerprint: the fingerprint 32 | @type fingerprint: string 33 | @see: draft-ietf-secsh-dns-05.txt""" 34 | 35 | __slots__ = ['algorithm', 'fp_type', 'fingerprint'] 36 | 37 | def __init__(self, rdclass, rdtype, algorithm, fp_type, 38 | fingerprint): 39 | super(SSHFP, self).__init__(rdclass, rdtype) 40 | self.algorithm = algorithm 41 | self.fp_type = fp_type 42 | self.fingerprint = fingerprint 43 | 44 | def to_text(self, origin=None, relativize=True, **kw): 45 | return '%d %d %s' % (self.algorithm, 46 | self.fp_type, 47 | dns.rdata._hexify(self.fingerprint, 48 | chunksize=128)) 49 | 50 | @classmethod 51 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 52 | algorithm = tok.get_uint8() 53 | fp_type = tok.get_uint8() 54 | chunks = [] 55 | while 1: 56 | t = tok.get().unescape() 57 | if t.is_eol_or_eof(): 58 | break 59 | if not t.is_identifier(): 60 | raise dns.exception.SyntaxError 61 | chunks.append(t.value.encode()) 62 | fingerprint = b''.join(chunks) 63 | fingerprint = binascii.unhexlify(fingerprint) 64 | return cls(rdclass, rdtype, algorithm, fp_type, fingerprint) 65 | 66 | def to_wire(self, file, compress=None, origin=None): 67 | header = struct.pack("!BB", self.algorithm, self.fp_type) 68 | file.write(header) 69 | file.write(self.fingerprint) 70 | 71 | @classmethod 72 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 73 | header = struct.unpack("!BB", wire[current: current + 2]) 74 | current += 2 75 | rdlen -= 2 76 | fingerprint = wire[current: current + rdlen].unwrap() 77 | return cls(rdclass, rdtype, header[0], header[1], fingerprint) 78 | -------------------------------------------------------------------------------- /dns/rdtypes/nsbase.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """NS-like base classes.""" 17 | 18 | from io import BytesIO 19 | 20 | import dns.exception 21 | import dns.rdata 22 | import dns.name 23 | 24 | 25 | class NSBase(dns.rdata.Rdata): 26 | 27 | """Base class for rdata that is like an NS record. 28 | 29 | @ivar target: the target name of the rdata 30 | @type target: dns.name.Name object""" 31 | 32 | __slots__ = ['target'] 33 | 34 | def __init__(self, rdclass, rdtype, target): 35 | super(NSBase, self).__init__(rdclass, rdtype) 36 | self.target = target 37 | 38 | def to_text(self, origin=None, relativize=True, **kw): 39 | target = self.target.choose_relativity(origin, relativize) 40 | return str(target) 41 | 42 | @classmethod 43 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 44 | target = tok.get_name() 45 | target = target.choose_relativity(origin, relativize) 46 | tok.get_eol() 47 | return cls(rdclass, rdtype, target) 48 | 49 | def to_wire(self, file, compress=None, origin=None): 50 | self.target.to_wire(file, compress, origin) 51 | 52 | def to_digestable(self, origin=None): 53 | return self.target.to_digestable(origin) 54 | 55 | @classmethod 56 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 57 | (target, cused) = dns.name.from_wire(wire[: current + rdlen], 58 | current) 59 | if cused != rdlen: 60 | raise dns.exception.FormError 61 | if origin is not None: 62 | target = target.relativize(origin) 63 | return cls(rdclass, rdtype, target) 64 | 65 | def choose_relativity(self, origin=None, relativize=True): 66 | self.target = self.target.choose_relativity(origin, relativize) 67 | 68 | 69 | class UncompressedNS(NSBase): 70 | 71 | """Base class for rdata that is like an NS record, but whose name 72 | is not compressed when convert to DNS wire format, and whose 73 | digestable form is not downcased.""" 74 | 75 | def to_wire(self, file, compress=None, origin=None): 76 | super(UncompressedNS, self).to_wire(file, None, origin) 77 | 78 | def to_digestable(self, origin=None): 79 | f = BytesIO() 80 | self.to_wire(f, None, origin) 81 | return f.getvalue() 82 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/URI.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Permission to use, copy, modify, and distribute this software and its 5 | # documentation for any purpose with or without fee is hereby granted, 6 | # provided that the above copyright notice and this permission notice 7 | # appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | 17 | import struct 18 | 19 | import dns.exception 20 | import dns.rdata 21 | import dns.name 22 | from dns._compat import text_type 23 | 24 | 25 | class URI(dns.rdata.Rdata): 26 | 27 | """URI record 28 | 29 | @ivar priority: the priority 30 | @type priority: int 31 | @ivar weight: the weight 32 | @type weight: int 33 | @ivar target: the target host 34 | @type target: dns.name.Name object 35 | @see: draft-faltstrom-uri-13""" 36 | 37 | __slots__ = ['priority', 'weight', 'target'] 38 | 39 | def __init__(self, rdclass, rdtype, priority, weight, target): 40 | super(URI, self).__init__(rdclass, rdtype) 41 | self.priority = priority 42 | self.weight = weight 43 | if len(target) < 1: 44 | raise dns.exception.SyntaxError("URI target cannot be empty") 45 | if isinstance(target, text_type): 46 | self.target = target.encode() 47 | else: 48 | self.target = target 49 | 50 | def to_text(self, origin=None, relativize=True, **kw): 51 | return '%d %d "%s"' % (self.priority, self.weight, 52 | self.target.decode()) 53 | 54 | @classmethod 55 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 56 | priority = tok.get_uint16() 57 | weight = tok.get_uint16() 58 | target = tok.get().unescape() 59 | if not (target.is_quoted_string() or target.is_identifier()): 60 | raise dns.exception.SyntaxError("URI target must be a string") 61 | tok.get_eol() 62 | return cls(rdclass, rdtype, priority, weight, target.value) 63 | 64 | def to_wire(self, file, compress=None, origin=None): 65 | two_ints = struct.pack("!HH", self.priority, self.weight) 66 | file.write(two_ints) 67 | file.write(self.target) 68 | 69 | @classmethod 70 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 71 | if rdlen < 5: 72 | raise dns.exception.FormError('URI RR is shorter than 5 octets') 73 | 74 | (priority, weight) = struct.unpack('!HH', wire[current: current + 4]) 75 | current += 4 76 | rdlen -= 4 77 | target = wire[current: current + rdlen] 78 | current += rdlen 79 | 80 | return cls(rdclass, rdtype, priority, weight, target) 81 | -------------------------------------------------------------------------------- /dns/flags.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2001-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS Message Flags.""" 17 | 18 | # Standard DNS flags 19 | 20 | QR = 0x8000 21 | AA = 0x0400 22 | TC = 0x0200 23 | RD = 0x0100 24 | RA = 0x0080 25 | AD = 0x0020 26 | CD = 0x0010 27 | 28 | # EDNS flags 29 | 30 | DO = 0x8000 31 | 32 | _by_text = { 33 | 'QR': QR, 34 | 'AA': AA, 35 | 'TC': TC, 36 | 'RD': RD, 37 | 'RA': RA, 38 | 'AD': AD, 39 | 'CD': CD 40 | } 41 | 42 | _edns_by_text = { 43 | 'DO': DO 44 | } 45 | 46 | 47 | # We construct the inverse mappings programmatically to ensure that we 48 | # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that 49 | # would cause the mappings not to be true inverses. 50 | 51 | _by_value = dict((y, x) for x, y in _by_text.items()) 52 | 53 | _edns_by_value = dict((y, x) for x, y in _edns_by_text.items()) 54 | 55 | 56 | def _order_flags(table): 57 | order = list(table.items()) 58 | order.sort() 59 | order.reverse() 60 | return order 61 | 62 | _flags_order = _order_flags(_by_value) 63 | 64 | _edns_flags_order = _order_flags(_edns_by_value) 65 | 66 | 67 | def _from_text(text, table): 68 | flags = 0 69 | tokens = text.split() 70 | for t in tokens: 71 | flags = flags | table[t.upper()] 72 | return flags 73 | 74 | 75 | def _to_text(flags, table, order): 76 | text_flags = [] 77 | for k, v in order: 78 | if flags & k != 0: 79 | text_flags.append(v) 80 | return ' '.join(text_flags) 81 | 82 | 83 | def from_text(text): 84 | """Convert a space-separated list of flag text values into a flags 85 | value. 86 | @rtype: int""" 87 | 88 | return _from_text(text, _by_text) 89 | 90 | 91 | def to_text(flags): 92 | """Convert a flags value into a space-separated list of flag text 93 | values. 94 | @rtype: string""" 95 | 96 | return _to_text(flags, _by_value, _flags_order) 97 | 98 | 99 | def edns_from_text(text): 100 | """Convert a space-separated list of EDNS flag text values into a EDNS 101 | flags value. 102 | @rtype: int""" 103 | 104 | return _from_text(text, _edns_by_text) 105 | 106 | 107 | def edns_to_text(flags): 108 | """Convert an EDNS flags value into a space-separated list of EDNS flag 109 | text values. 110 | @rtype: string""" 111 | 112 | return _to_text(flags, _edns_by_value, _edns_flags_order) 113 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/TLSA.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2005-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | import binascii 18 | 19 | import dns.rdata 20 | import dns.rdatatype 21 | 22 | 23 | class TLSA(dns.rdata.Rdata): 24 | 25 | """TLSA record 26 | 27 | @ivar usage: The certificate usage 28 | @type usage: int 29 | @ivar selector: The selector field 30 | @type selector: int 31 | @ivar mtype: The 'matching type' field 32 | @type mtype: int 33 | @ivar cert: The 'Certificate Association Data' field 34 | @type cert: string 35 | @see: RFC 6698""" 36 | 37 | __slots__ = ['usage', 'selector', 'mtype', 'cert'] 38 | 39 | def __init__(self, rdclass, rdtype, usage, selector, 40 | mtype, cert): 41 | super(TLSA, self).__init__(rdclass, rdtype) 42 | self.usage = usage 43 | self.selector = selector 44 | self.mtype = mtype 45 | self.cert = cert 46 | 47 | def to_text(self, origin=None, relativize=True, **kw): 48 | return '%d %d %d %s' % (self.usage, 49 | self.selector, 50 | self.mtype, 51 | dns.rdata._hexify(self.cert, 52 | chunksize=128)) 53 | 54 | @classmethod 55 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 56 | usage = tok.get_uint8() 57 | selector = tok.get_uint8() 58 | mtype = tok.get_uint8() 59 | cert_chunks = [] 60 | while 1: 61 | t = tok.get().unescape() 62 | if t.is_eol_or_eof(): 63 | break 64 | if not t.is_identifier(): 65 | raise dns.exception.SyntaxError 66 | cert_chunks.append(t.value.encode()) 67 | cert = b''.join(cert_chunks) 68 | cert = binascii.unhexlify(cert) 69 | return cls(rdclass, rdtype, usage, selector, mtype, cert) 70 | 71 | def to_wire(self, file, compress=None, origin=None): 72 | header = struct.pack("!BBB", self.usage, self.selector, self.mtype) 73 | file.write(header) 74 | file.write(self.cert) 75 | 76 | @classmethod 77 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 78 | header = struct.unpack("!BBB", wire[current: current + 3]) 79 | current += 3 80 | rdlen -= 3 81 | cert = wire[current: current + rdlen].unwrap() 82 | return cls(rdclass, rdtype, header[0], header[1], header[2], cert) 83 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/SRV.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | 18 | import dns.exception 19 | import dns.rdata 20 | import dns.name 21 | 22 | 23 | class SRV(dns.rdata.Rdata): 24 | 25 | """SRV record 26 | 27 | @ivar priority: the priority 28 | @type priority: int 29 | @ivar weight: the weight 30 | @type weight: int 31 | @ivar port: the port of the service 32 | @type port: int 33 | @ivar target: the target host 34 | @type target: dns.name.Name object 35 | @see: RFC 2782""" 36 | 37 | __slots__ = ['priority', 'weight', 'port', 'target'] 38 | 39 | def __init__(self, rdclass, rdtype, priority, weight, port, target): 40 | super(SRV, self).__init__(rdclass, rdtype) 41 | self.priority = priority 42 | self.weight = weight 43 | self.port = port 44 | self.target = target 45 | 46 | def to_text(self, origin=None, relativize=True, **kw): 47 | target = self.target.choose_relativity(origin, relativize) 48 | return '%d %d %d %s' % (self.priority, self.weight, self.port, 49 | target) 50 | 51 | @classmethod 52 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 53 | priority = tok.get_uint16() 54 | weight = tok.get_uint16() 55 | port = tok.get_uint16() 56 | target = tok.get_name(None) 57 | target = target.choose_relativity(origin, relativize) 58 | tok.get_eol() 59 | return cls(rdclass, rdtype, priority, weight, port, target) 60 | 61 | def to_wire(self, file, compress=None, origin=None): 62 | three_ints = struct.pack("!HHH", self.priority, self.weight, self.port) 63 | file.write(three_ints) 64 | self.target.to_wire(file, compress, origin) 65 | 66 | @classmethod 67 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 68 | (priority, weight, port) = struct.unpack('!HHH', 69 | wire[current: current + 6]) 70 | current += 6 71 | rdlen -= 6 72 | (target, cused) = dns.name.from_wire(wire[: current + rdlen], 73 | current) 74 | if cused != rdlen: 75 | raise dns.exception.FormError 76 | if origin is not None: 77 | target = target.relativize(origin) 78 | return cls(rdclass, rdtype, priority, weight, port, target) 79 | 80 | def choose_relativity(self, origin=None, relativize=True): 81 | self.target = self.target.choose_relativity(origin, relativize) 82 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/RP.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import dns.exception 17 | import dns.rdata 18 | import dns.name 19 | 20 | 21 | class RP(dns.rdata.Rdata): 22 | 23 | """RP record 24 | 25 | @ivar mbox: The responsible person's mailbox 26 | @type mbox: dns.name.Name object 27 | @ivar txt: The owner name of a node with TXT records, or the root name 28 | if no TXT records are associated with this RP. 29 | @type txt: dns.name.Name object 30 | @see: RFC 1183""" 31 | 32 | __slots__ = ['mbox', 'txt'] 33 | 34 | def __init__(self, rdclass, rdtype, mbox, txt): 35 | super(RP, self).__init__(rdclass, rdtype) 36 | self.mbox = mbox 37 | self.txt = txt 38 | 39 | def to_text(self, origin=None, relativize=True, **kw): 40 | mbox = self.mbox.choose_relativity(origin, relativize) 41 | txt = self.txt.choose_relativity(origin, relativize) 42 | return "%s %s" % (str(mbox), str(txt)) 43 | 44 | @classmethod 45 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 46 | mbox = tok.get_name() 47 | txt = tok.get_name() 48 | mbox = mbox.choose_relativity(origin, relativize) 49 | txt = txt.choose_relativity(origin, relativize) 50 | tok.get_eol() 51 | return cls(rdclass, rdtype, mbox, txt) 52 | 53 | def to_wire(self, file, compress=None, origin=None): 54 | self.mbox.to_wire(file, None, origin) 55 | self.txt.to_wire(file, None, origin) 56 | 57 | def to_digestable(self, origin=None): 58 | return self.mbox.to_digestable(origin) + \ 59 | self.txt.to_digestable(origin) 60 | 61 | @classmethod 62 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 63 | (mbox, cused) = dns.name.from_wire(wire[: current + rdlen], 64 | current) 65 | current += cused 66 | rdlen -= cused 67 | if rdlen <= 0: 68 | raise dns.exception.FormError 69 | (txt, cused) = dns.name.from_wire(wire[: current + rdlen], 70 | current) 71 | if cused != rdlen: 72 | raise dns.exception.FormError 73 | if origin is not None: 74 | mbox = mbox.relativize(origin) 75 | txt = txt.relativize(origin) 76 | return cls(rdclass, rdtype, mbox, txt) 77 | 78 | def choose_relativity(self, origin=None, relativize=True): 79 | self.mbox = self.mbox.choose_relativity(origin, relativize) 80 | self.txt = self.txt.choose_relativity(origin, relativize) 81 | -------------------------------------------------------------------------------- /lib/qrscanner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Electrum - lightweight Bitcoin client 4 | # Copyright (C) 2015 Thomas Voegtlin 5 | # 6 | # Permission is hereby granted, free of charge, to any person 7 | # obtaining a copy of this software and associated documentation files 8 | # (the "Software"), to deal in the Software without restriction, 9 | # including without limitation the rights to use, copy, modify, merge, 10 | # publish, distribute, sublicense, and/or sell copies of the Software, 11 | # and to permit persons to whom the Software is furnished to do so, 12 | # subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | 26 | import os 27 | import sys 28 | import ctypes 29 | 30 | if sys.platform == 'darwin': 31 | name = 'libzbar.dylib' 32 | elif sys.platform == 'windows': 33 | name = 'libzbar.dll' 34 | else: 35 | name = 'libzbar.so.0' 36 | 37 | try: 38 | libzbar = ctypes.cdll.LoadLibrary(name) 39 | except OSError: 40 | libzbar = None 41 | 42 | 43 | def scan_barcode(device='', timeout=-1, display=True, threaded=False): 44 | if libzbar is None: 45 | raise RuntimeError("Cannot start QR scanner; zbar not available.") 46 | libzbar.zbar_symbol_get_data.restype = ctypes.c_char_p 47 | libzbar.zbar_processor_create.restype = ctypes.POINTER(ctypes.c_int) 48 | libzbar.zbar_processor_get_results.restype = ctypes.POINTER(ctypes.c_int) 49 | libzbar.zbar_symbol_set_first_symbol.restype = ctypes.POINTER(ctypes.c_int) 50 | proc = libzbar.zbar_processor_create(threaded) 51 | libzbar.zbar_processor_request_size(proc, 640, 480) 52 | libzbar.zbar_processor_init(proc, device, display) 53 | libzbar.zbar_processor_set_visible(proc) 54 | if libzbar.zbar_process_one(proc, timeout): 55 | symbols = libzbar.zbar_processor_get_results(proc) 56 | else: 57 | symbols = None 58 | libzbar.zbar_processor_destroy(proc) 59 | if symbols is None: 60 | return 61 | if not libzbar.zbar_symbol_set_get_size(symbols): 62 | return 63 | symbol = libzbar.zbar_symbol_set_first_symbol(symbols) 64 | data = libzbar.zbar_symbol_get_data(symbol) 65 | return data.decode('utf8') 66 | 67 | def _find_system_cameras(): 68 | device_root = "/sys/class/video4linux" 69 | devices = {} # Name -> device 70 | if os.path.exists(device_root): 71 | for device in os.listdir(device_root): 72 | try: 73 | with open(os.path.join(device_root, device, 'name')) as f: 74 | name = f.read() 75 | except IOError: 76 | continue 77 | name = name.strip('\n') 78 | devices[name] = os.path.join("/dev", device) 79 | return devices 80 | 81 | 82 | if __name__ == "__main__": 83 | print(scan_barcode()) 84 | -------------------------------------------------------------------------------- /dns/rdtypes/txtbase.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """TXT-like base class.""" 17 | 18 | import struct 19 | 20 | import dns.exception 21 | import dns.rdata 22 | import dns.tokenizer 23 | from dns._compat import binary_type 24 | 25 | 26 | class TXTBase(dns.rdata.Rdata): 27 | 28 | """Base class for rdata that is like a TXT record 29 | 30 | @ivar strings: the text strings 31 | @type strings: list of string 32 | @see: RFC 1035""" 33 | 34 | __slots__ = ['strings'] 35 | 36 | def __init__(self, rdclass, rdtype, strings): 37 | super(TXTBase, self).__init__(rdclass, rdtype) 38 | if isinstance(strings, str): 39 | strings = [strings] 40 | self.strings = strings[:] 41 | 42 | def to_text(self, origin=None, relativize=True, **kw): 43 | txt = '' 44 | prefix = '' 45 | for s in self.strings: 46 | txt += '%s"%s"' % (prefix, dns.rdata._escapify(s)) 47 | prefix = ' ' 48 | return txt 49 | 50 | @classmethod 51 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 52 | strings = [] 53 | while 1: 54 | token = tok.get().unescape() 55 | if token.is_eol_or_eof(): 56 | break 57 | if not (token.is_quoted_string() or token.is_identifier()): 58 | raise dns.exception.SyntaxError("expected a string") 59 | if len(token.value) > 255: 60 | raise dns.exception.SyntaxError("string too long") 61 | value = token.value 62 | if isinstance(value, binary_type): 63 | strings.append(value) 64 | else: 65 | strings.append(value.encode()) 66 | if len(strings) == 0: 67 | raise dns.exception.UnexpectedEnd 68 | return cls(rdclass, rdtype, strings) 69 | 70 | def to_wire(self, file, compress=None, origin=None): 71 | for s in self.strings: 72 | l = len(s) 73 | assert l < 256 74 | file.write(struct.pack('!B', l)) 75 | file.write(s) 76 | 77 | @classmethod 78 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 79 | strings = [] 80 | while rdlen > 0: 81 | l = wire[current] 82 | current += 1 83 | rdlen -= 1 84 | if l > rdlen: 85 | raise dns.exception.FormError 86 | s = wire[current: current + l].unwrap() 87 | current += l 88 | rdlen -= l 89 | strings.append(s) 90 | return cls(rdclass, rdtype, strings) 91 | -------------------------------------------------------------------------------- /dns/rdtypes/dsbase.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010, 2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | import binascii 18 | 19 | import dns.rdata 20 | import dns.rdatatype 21 | 22 | 23 | class DSBase(dns.rdata.Rdata): 24 | 25 | """Base class for rdata that is like a DS record 26 | 27 | @ivar key_tag: the key tag 28 | @type key_tag: int 29 | @ivar algorithm: the algorithm 30 | @type algorithm: int 31 | @ivar digest_type: the digest type 32 | @type digest_type: int 33 | @ivar digest: the digest 34 | @type digest: int 35 | @see: draft-ietf-dnsext-delegation-signer-14.txt""" 36 | 37 | __slots__ = ['key_tag', 'algorithm', 'digest_type', 'digest'] 38 | 39 | def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type, 40 | digest): 41 | super(DSBase, self).__init__(rdclass, rdtype) 42 | self.key_tag = key_tag 43 | self.algorithm = algorithm 44 | self.digest_type = digest_type 45 | self.digest = digest 46 | 47 | def to_text(self, origin=None, relativize=True, **kw): 48 | return '%d %d %d %s' % (self.key_tag, self.algorithm, 49 | self.digest_type, 50 | dns.rdata._hexify(self.digest, 51 | chunksize=128)) 52 | 53 | @classmethod 54 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 55 | key_tag = tok.get_uint16() 56 | algorithm = tok.get_uint8() 57 | digest_type = tok.get_uint8() 58 | chunks = [] 59 | while 1: 60 | t = tok.get().unescape() 61 | if t.is_eol_or_eof(): 62 | break 63 | if not t.is_identifier(): 64 | raise dns.exception.SyntaxError 65 | chunks.append(t.value.encode()) 66 | digest = b''.join(chunks) 67 | digest = binascii.unhexlify(digest) 68 | return cls(rdclass, rdtype, key_tag, algorithm, digest_type, 69 | digest) 70 | 71 | def to_wire(self, file, compress=None, origin=None): 72 | header = struct.pack("!HBB", self.key_tag, self.algorithm, 73 | self.digest_type) 74 | file.write(header) 75 | file.write(self.digest) 76 | 77 | @classmethod 78 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 79 | header = struct.unpack("!HBB", wire[current: current + 4]) 80 | current += 4 81 | rdlen -= 4 82 | digest = wire[current: current + rdlen].unwrap() 83 | return cls(rdclass, rdtype, header[0], header[1], header[2], digest) 84 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/NSEC3PARAM.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | import binascii 18 | 19 | import dns.exception 20 | import dns.rdata 21 | from dns._compat import text_type 22 | 23 | 24 | class NSEC3PARAM(dns.rdata.Rdata): 25 | 26 | """NSEC3PARAM record 27 | 28 | @ivar algorithm: the hash algorithm number 29 | @type algorithm: int 30 | @ivar flags: the flags 31 | @type flags: int 32 | @ivar iterations: the number of iterations 33 | @type iterations: int 34 | @ivar salt: the salt 35 | @type salt: string""" 36 | 37 | __slots__ = ['algorithm', 'flags', 'iterations', 'salt'] 38 | 39 | def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt): 40 | super(NSEC3PARAM, self).__init__(rdclass, rdtype) 41 | self.algorithm = algorithm 42 | self.flags = flags 43 | self.iterations = iterations 44 | if isinstance(salt, text_type): 45 | self.salt = salt.encode() 46 | else: 47 | self.salt = salt 48 | 49 | def to_text(self, origin=None, relativize=True, **kw): 50 | if self.salt == b'': 51 | salt = '-' 52 | else: 53 | salt = binascii.hexlify(self.salt).decode() 54 | return '%u %u %u %s' % (self.algorithm, self.flags, self.iterations, 55 | salt) 56 | 57 | @classmethod 58 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 59 | algorithm = tok.get_uint8() 60 | flags = tok.get_uint8() 61 | iterations = tok.get_uint16() 62 | salt = tok.get_string() 63 | if salt == '-': 64 | salt = '' 65 | else: 66 | salt = binascii.unhexlify(salt.encode()) 67 | tok.get_eol() 68 | return cls(rdclass, rdtype, algorithm, flags, iterations, salt) 69 | 70 | def to_wire(self, file, compress=None, origin=None): 71 | l = len(self.salt) 72 | file.write(struct.pack("!BBHB", self.algorithm, self.flags, 73 | self.iterations, l)) 74 | file.write(self.salt) 75 | 76 | @classmethod 77 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 78 | (algorithm, flags, iterations, slen) = \ 79 | struct.unpack('!BBHB', 80 | wire[current: current + 5]) 81 | current += 5 82 | rdlen -= 5 83 | salt = wire[current: current + slen].unwrap() 84 | current += slen 85 | rdlen -= slen 86 | if rdlen != 0: 87 | raise dns.exception.FormError 88 | return cls(rdclass, rdtype, algorithm, flags, iterations, salt) 89 | -------------------------------------------------------------------------------- /dns/e164.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2006, 2007, 2009, 2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS E.164 helpers 17 | 18 | @var public_enum_domain: The DNS public ENUM domain, e164.arpa. 19 | @type public_enum_domain: dns.name.Name object 20 | """ 21 | 22 | 23 | import dns.exception 24 | import dns.name 25 | import dns.resolver 26 | from ._compat import string_types 27 | 28 | public_enum_domain = dns.name.from_text('e164.arpa.') 29 | 30 | 31 | def from_e164(text, origin=public_enum_domain): 32 | """Convert an E.164 number in textual form into a Name object whose 33 | value is the ENUM domain name for that number. 34 | @param text: an E.164 number in textual form. 35 | @type text: str 36 | @param origin: The domain in which the number should be constructed. 37 | The default is e164.arpa. 38 | @type origin: dns.name.Name object or None 39 | @rtype: dns.name.Name object 40 | """ 41 | parts = [d for d in text if d.isdigit()] 42 | parts.reverse() 43 | return dns.name.from_text('.'.join(parts), origin=origin) 44 | 45 | 46 | def to_e164(name, origin=public_enum_domain, want_plus_prefix=True): 47 | """Convert an ENUM domain name into an E.164 number. 48 | @param name: the ENUM domain name. 49 | @type name: dns.name.Name object. 50 | @param origin: A domain containing the ENUM domain name. The 51 | name is relativized to this domain before being converted to text. 52 | @type origin: dns.name.Name object or None 53 | @param want_plus_prefix: if True, add a '+' to the beginning of the 54 | returned number. 55 | @rtype: str 56 | """ 57 | if origin is not None: 58 | name = name.relativize(origin) 59 | dlabels = [d for d in name.labels if d.isdigit() and len(d) == 1] 60 | if len(dlabels) != len(name.labels): 61 | raise dns.exception.SyntaxError('non-digit labels in ENUM domain name') 62 | dlabels.reverse() 63 | text = b''.join(dlabels) 64 | if want_plus_prefix: 65 | text = b'+' + text 66 | return text 67 | 68 | 69 | def query(number, domains, resolver=None): 70 | """Look for NAPTR RRs for the specified number in the specified domains. 71 | 72 | e.g. lookup('16505551212', ['e164.dnspython.org.', 'e164.arpa.']) 73 | """ 74 | if resolver is None: 75 | resolver = dns.resolver.get_default_resolver() 76 | e_nx = dns.resolver.NXDOMAIN() 77 | for domain in domains: 78 | if isinstance(domain, string_types): 79 | domain = dns.name.from_text(domain) 80 | qname = dns.e164.from_e164(number, domain) 81 | try: 82 | return resolver.query(qname, 'NAPTR') 83 | except dns.resolver.NXDOMAIN as e: 84 | e_nx += e 85 | raise e_nx 86 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/ISDN.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | 18 | import dns.exception 19 | import dns.rdata 20 | import dns.tokenizer 21 | from dns._compat import text_type 22 | 23 | 24 | class ISDN(dns.rdata.Rdata): 25 | 26 | """ISDN record 27 | 28 | @ivar address: the ISDN address 29 | @type address: string 30 | @ivar subaddress: the ISDN subaddress (or '' if not present) 31 | @type subaddress: string 32 | @see: RFC 1183""" 33 | 34 | __slots__ = ['address', 'subaddress'] 35 | 36 | def __init__(self, rdclass, rdtype, address, subaddress): 37 | super(ISDN, self).__init__(rdclass, rdtype) 38 | if isinstance(address, text_type): 39 | self.address = address.encode() 40 | else: 41 | self.address = address 42 | if isinstance(address, text_type): 43 | self.subaddress = subaddress.encode() 44 | else: 45 | self.subaddress = subaddress 46 | 47 | def to_text(self, origin=None, relativize=True, **kw): 48 | if self.subaddress: 49 | return '"%s" "%s"' % (dns.rdata._escapify(self.address), 50 | dns.rdata._escapify(self.subaddress)) 51 | else: 52 | return '"%s"' % dns.rdata._escapify(self.address) 53 | 54 | @classmethod 55 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 56 | address = tok.get_string() 57 | t = tok.get() 58 | if not t.is_eol_or_eof(): 59 | tok.unget(t) 60 | subaddress = tok.get_string() 61 | else: 62 | tok.unget(t) 63 | subaddress = '' 64 | tok.get_eol() 65 | return cls(rdclass, rdtype, address, subaddress) 66 | 67 | def to_wire(self, file, compress=None, origin=None): 68 | l = len(self.address) 69 | assert l < 256 70 | file.write(struct.pack('!B', l)) 71 | file.write(self.address) 72 | l = len(self.subaddress) 73 | if l > 0: 74 | assert l < 256 75 | file.write(struct.pack('!B', l)) 76 | file.write(self.subaddress) 77 | 78 | @classmethod 79 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 80 | l = wire[current] 81 | current += 1 82 | rdlen -= 1 83 | if l > rdlen: 84 | raise dns.exception.FormError 85 | address = wire[current: current + l].unwrap() 86 | current += l 87 | rdlen -= l 88 | if rdlen > 0: 89 | l = wire[current] 90 | current += 1 91 | rdlen -= 1 92 | if l != rdlen: 93 | raise dns.exception.FormError 94 | subaddress = wire[current: current + l].unwrap() 95 | else: 96 | subaddress = '' 97 | return cls(rdclass, rdtype, address, subaddress) 98 | -------------------------------------------------------------------------------- /dns/reversename.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS Reverse Map Names. 17 | 18 | @var ipv4_reverse_domain: The DNS IPv4 reverse-map domain, in-addr.arpa. 19 | @type ipv4_reverse_domain: dns.name.Name object 20 | @var ipv6_reverse_domain: The DNS IPv6 reverse-map domain, ip6.arpa. 21 | @type ipv6_reverse_domain: dns.name.Name object 22 | """ 23 | 24 | import binascii 25 | import sys 26 | 27 | import dns.name 28 | import dns.ipv6 29 | import dns.ipv4 30 | 31 | ipv4_reverse_domain = dns.name.from_text('in-addr.arpa.') 32 | ipv6_reverse_domain = dns.name.from_text('ip6.arpa.') 33 | 34 | 35 | def from_address(text): 36 | """Convert an IPv4 or IPv6 address in textual form into a Name object whose 37 | value is the reverse-map domain name of the address. 38 | @param text: an IPv4 or IPv6 address in textual form (e.g. '127.0.0.1', 39 | '::1') 40 | @type text: str 41 | @rtype: dns.name.Name object 42 | """ 43 | try: 44 | v6 = dns.ipv6.inet_aton(text) 45 | if dns.ipv6.is_mapped(v6): 46 | if sys.version_info >= (3,): 47 | parts = ['%d' % byte for byte in v6[12:]] 48 | else: 49 | parts = ['%d' % ord(byte) for byte in v6[12:]] 50 | origin = ipv4_reverse_domain 51 | else: 52 | parts = [x for x in str(binascii.hexlify(v6).decode())] 53 | origin = ipv6_reverse_domain 54 | except Exception: 55 | parts = ['%d' % 56 | byte for byte in bytearray(dns.ipv4.inet_aton(text))] 57 | origin = ipv4_reverse_domain 58 | parts.reverse() 59 | return dns.name.from_text('.'.join(parts), origin=origin) 60 | 61 | 62 | def to_address(name): 63 | """Convert a reverse map domain name into textual address form. 64 | @param name: an IPv4 or IPv6 address in reverse-map form. 65 | @type name: dns.name.Name object 66 | @rtype: str 67 | """ 68 | if name.is_subdomain(ipv4_reverse_domain): 69 | name = name.relativize(ipv4_reverse_domain) 70 | labels = list(name.labels) 71 | labels.reverse() 72 | text = b'.'.join(labels) 73 | # run through inet_aton() to check syntax and make pretty. 74 | return dns.ipv4.inet_ntoa(dns.ipv4.inet_aton(text)) 75 | elif name.is_subdomain(ipv6_reverse_domain): 76 | name = name.relativize(ipv6_reverse_domain) 77 | labels = list(name.labels) 78 | labels.reverse() 79 | parts = [] 80 | i = 0 81 | l = len(labels) 82 | while i < l: 83 | parts.append(b''.join(labels[i:i + 4])) 84 | i += 4 85 | text = b':'.join(parts) 86 | # run through inet_aton() to check syntax and make pretty. 87 | return dns.ipv6.inet_ntoa(dns.ipv6.inet_aton(text)) 88 | else: 89 | raise dns.exception.SyntaxError('unknown reverse-map address family') 90 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/PX.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | 18 | import dns.exception 19 | import dns.rdata 20 | import dns.name 21 | 22 | 23 | class PX(dns.rdata.Rdata): 24 | 25 | """PX record. 26 | 27 | @ivar preference: the preference value 28 | @type preference: int 29 | @ivar map822: the map822 name 30 | @type map822: dns.name.Name object 31 | @ivar mapx400: the mapx400 name 32 | @type mapx400: dns.name.Name object 33 | @see: RFC 2163""" 34 | 35 | __slots__ = ['preference', 'map822', 'mapx400'] 36 | 37 | def __init__(self, rdclass, rdtype, preference, map822, mapx400): 38 | super(PX, self).__init__(rdclass, rdtype) 39 | self.preference = preference 40 | self.map822 = map822 41 | self.mapx400 = mapx400 42 | 43 | def to_text(self, origin=None, relativize=True, **kw): 44 | map822 = self.map822.choose_relativity(origin, relativize) 45 | mapx400 = self.mapx400.choose_relativity(origin, relativize) 46 | return '%d %s %s' % (self.preference, map822, mapx400) 47 | 48 | @classmethod 49 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 50 | preference = tok.get_uint16() 51 | map822 = tok.get_name() 52 | map822 = map822.choose_relativity(origin, relativize) 53 | mapx400 = tok.get_name(None) 54 | mapx400 = mapx400.choose_relativity(origin, relativize) 55 | tok.get_eol() 56 | return cls(rdclass, rdtype, preference, map822, mapx400) 57 | 58 | def to_wire(self, file, compress=None, origin=None): 59 | pref = struct.pack("!H", self.preference) 60 | file.write(pref) 61 | self.map822.to_wire(file, None, origin) 62 | self.mapx400.to_wire(file, None, origin) 63 | 64 | @classmethod 65 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 66 | (preference, ) = struct.unpack('!H', wire[current: current + 2]) 67 | current += 2 68 | rdlen -= 2 69 | (map822, cused) = dns.name.from_wire(wire[: current + rdlen], 70 | current) 71 | if cused > rdlen: 72 | raise dns.exception.FormError 73 | current += cused 74 | rdlen -= cused 75 | if origin is not None: 76 | map822 = map822.relativize(origin) 77 | (mapx400, cused) = dns.name.from_wire(wire[: current + rdlen], 78 | current) 79 | if cused != rdlen: 80 | raise dns.exception.FormError 81 | if origin is not None: 82 | mapx400 = mapx400.relativize(origin) 83 | return cls(rdclass, rdtype, preference, map822, mapx400) 84 | 85 | def choose_relativity(self, origin=None, relativize=True): 86 | self.map822 = self.map822.choose_relativity(origin, relativize) 87 | self.mapx400 = self.mapx400.choose_relativity(origin, relativize) 88 | -------------------------------------------------------------------------------- /dns/rcode.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2001-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS Result Codes.""" 17 | 18 | import dns.exception 19 | from ._compat import long 20 | 21 | 22 | NOERROR = 0 23 | FORMERR = 1 24 | SERVFAIL = 2 25 | NXDOMAIN = 3 26 | NOTIMP = 4 27 | REFUSED = 5 28 | YXDOMAIN = 6 29 | YXRRSET = 7 30 | NXRRSET = 8 31 | NOTAUTH = 9 32 | NOTZONE = 10 33 | BADVERS = 16 34 | 35 | _by_text = { 36 | 'NOERROR': NOERROR, 37 | 'FORMERR': FORMERR, 38 | 'SERVFAIL': SERVFAIL, 39 | 'NXDOMAIN': NXDOMAIN, 40 | 'NOTIMP': NOTIMP, 41 | 'REFUSED': REFUSED, 42 | 'YXDOMAIN': YXDOMAIN, 43 | 'YXRRSET': YXRRSET, 44 | 'NXRRSET': NXRRSET, 45 | 'NOTAUTH': NOTAUTH, 46 | 'NOTZONE': NOTZONE, 47 | 'BADVERS': BADVERS 48 | } 49 | 50 | # We construct the inverse mapping programmatically to ensure that we 51 | # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that 52 | # would cause the mapping not to be a true inverse. 53 | 54 | _by_value = dict((y, x) for x, y in _by_text.items()) 55 | 56 | 57 | class UnknownRcode(dns.exception.DNSException): 58 | 59 | """A DNS rcode is unknown.""" 60 | 61 | 62 | def from_text(text): 63 | """Convert text into an rcode. 64 | 65 | @param text: the textual rcode 66 | @type text: string 67 | @raises UnknownRcode: the rcode is unknown 68 | @rtype: int 69 | """ 70 | 71 | if text.isdigit(): 72 | v = int(text) 73 | if v >= 0 and v <= 4095: 74 | return v 75 | v = _by_text.get(text.upper()) 76 | if v is None: 77 | raise UnknownRcode 78 | return v 79 | 80 | 81 | def from_flags(flags, ednsflags): 82 | """Return the rcode value encoded by flags and ednsflags. 83 | 84 | @param flags: the DNS flags 85 | @type flags: int 86 | @param ednsflags: the EDNS flags 87 | @type ednsflags: int 88 | @raises ValueError: rcode is < 0 or > 4095 89 | @rtype: int 90 | """ 91 | 92 | value = (flags & 0x000f) | ((ednsflags >> 20) & 0xff0) 93 | if value < 0 or value > 4095: 94 | raise ValueError('rcode must be >= 0 and <= 4095') 95 | return value 96 | 97 | 98 | def to_flags(value): 99 | """Return a (flags, ednsflags) tuple which encodes the rcode. 100 | 101 | @param value: the rcode 102 | @type value: int 103 | @raises ValueError: rcode is < 0 or > 4095 104 | @rtype: (int, int) tuple 105 | """ 106 | 107 | if value < 0 or value > 4095: 108 | raise ValueError('rcode must be >= 0 and <= 4095') 109 | v = value & 0xf 110 | ev = long(value & 0xff0) << 20 111 | return (v, ev) 112 | 113 | 114 | def to_text(value): 115 | """Convert rcode into text. 116 | 117 | @param value: the rcode 118 | @type value: int 119 | @rtype: string 120 | """ 121 | 122 | text = _by_value.get(value) 123 | if text is None: 124 | text = str(value) 125 | return text 126 | -------------------------------------------------------------------------------- /dns/inet.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """Generic Internet address helper functions.""" 17 | 18 | import socket 19 | 20 | import dns.ipv4 21 | import dns.ipv6 22 | 23 | 24 | # We assume that AF_INET is always defined. 25 | 26 | AF_INET = socket.AF_INET 27 | 28 | # AF_INET6 might not be defined in the socket module, but we need it. 29 | # We'll try to use the socket module's value, and if it doesn't work, 30 | # we'll use our own value. 31 | 32 | try: 33 | AF_INET6 = socket.AF_INET6 34 | except AttributeError: 35 | AF_INET6 = 9999 36 | 37 | 38 | def inet_pton(family, text): 39 | """Convert the textual form of a network address into its binary form. 40 | 41 | @param family: the address family 42 | @type family: int 43 | @param text: the textual address 44 | @type text: string 45 | @raises NotImplementedError: the address family specified is not 46 | implemented. 47 | @rtype: string 48 | """ 49 | 50 | if family == AF_INET: 51 | return dns.ipv4.inet_aton(text) 52 | elif family == AF_INET6: 53 | return dns.ipv6.inet_aton(text) 54 | else: 55 | raise NotImplementedError 56 | 57 | 58 | def inet_ntop(family, address): 59 | """Convert the binary form of a network address into its textual form. 60 | 61 | @param family: the address family 62 | @type family: int 63 | @param address: the binary address 64 | @type address: string 65 | @raises NotImplementedError: the address family specified is not 66 | implemented. 67 | @rtype: string 68 | """ 69 | if family == AF_INET: 70 | return dns.ipv4.inet_ntoa(address) 71 | elif family == AF_INET6: 72 | return dns.ipv6.inet_ntoa(address) 73 | else: 74 | raise NotImplementedError 75 | 76 | 77 | def af_for_address(text): 78 | """Determine the address family of a textual-form network address. 79 | 80 | @param text: the textual address 81 | @type text: string 82 | @raises ValueError: the address family cannot be determined from the input. 83 | @rtype: int 84 | """ 85 | try: 86 | dns.ipv4.inet_aton(text) 87 | return AF_INET 88 | except Exception: 89 | try: 90 | dns.ipv6.inet_aton(text) 91 | return AF_INET6 92 | except: 93 | raise ValueError 94 | 95 | 96 | def is_multicast(text): 97 | """Is the textual-form network address a multicast address? 98 | 99 | @param text: the textual address 100 | @raises ValueError: the address family cannot be determined from the input. 101 | @rtype: bool 102 | """ 103 | try: 104 | first = ord(dns.ipv4.inet_aton(text)[0]) 105 | return first >= 224 and first <= 239 106 | except Exception: 107 | try: 108 | first = ord(dns.ipv6.inet_aton(text)[0]) 109 | return first == 255 110 | except Exception: 111 | raise ValueError 112 | -------------------------------------------------------------------------------- /dns/rdataclass.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2001-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS Rdata Classes. 17 | 18 | @var _by_text: The rdata class textual name to value mapping 19 | @type _by_text: dict 20 | @var _by_value: The rdata class value to textual name mapping 21 | @type _by_value: dict 22 | @var _metaclasses: If an rdataclass is a metaclass, there will be a mapping 23 | whose key is the rdatatype value and whose value is True in this dictionary. 24 | @type _metaclasses: dict""" 25 | 26 | import re 27 | 28 | import dns.exception 29 | 30 | RESERVED0 = 0 31 | IN = 1 32 | CH = 3 33 | HS = 4 34 | NONE = 254 35 | ANY = 255 36 | 37 | _by_text = { 38 | 'RESERVED0': RESERVED0, 39 | 'IN': IN, 40 | 'CH': CH, 41 | 'HS': HS, 42 | 'NONE': NONE, 43 | 'ANY': ANY 44 | } 45 | 46 | # We construct the inverse mapping programmatically to ensure that we 47 | # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that 48 | # would cause the mapping not to be true inverse. 49 | 50 | _by_value = dict((y, x) for x, y in _by_text.items()) 51 | 52 | # Now that we've built the inverse map, we can add class aliases to 53 | # the _by_text mapping. 54 | 55 | _by_text.update({ 56 | 'INTERNET': IN, 57 | 'CHAOS': CH, 58 | 'HESIOD': HS 59 | }) 60 | 61 | _metaclasses = { 62 | NONE: True, 63 | ANY: True 64 | } 65 | 66 | _unknown_class_pattern = re.compile('CLASS([0-9]+)$', re.I) 67 | 68 | 69 | class UnknownRdataclass(dns.exception.DNSException): 70 | 71 | """A DNS class is unknown.""" 72 | 73 | 74 | def from_text(text): 75 | """Convert text into a DNS rdata class value. 76 | @param text: the text 77 | @type text: string 78 | @rtype: int 79 | @raises dns.rdataclass.UnknownRdataclass: the class is unknown 80 | @raises ValueError: the rdata class value is not >= 0 and <= 65535 81 | """ 82 | 83 | value = _by_text.get(text.upper()) 84 | if value is None: 85 | match = _unknown_class_pattern.match(text) 86 | if match is None: 87 | raise UnknownRdataclass 88 | value = int(match.group(1)) 89 | if value < 0 or value > 65535: 90 | raise ValueError("class must be between >= 0 and <= 65535") 91 | return value 92 | 93 | 94 | def to_text(value): 95 | """Convert a DNS rdata class to text. 96 | @param value: the rdata class value 97 | @type value: int 98 | @rtype: string 99 | @raises ValueError: the rdata class value is not >= 0 and <= 65535 100 | """ 101 | 102 | if value < 0 or value > 65535: 103 | raise ValueError("class must be between >= 0 and <= 65535") 104 | text = _by_value.get(value) 105 | if text is None: 106 | text = 'CLASS' + repr(value) 107 | return text 108 | 109 | 110 | def is_metaclass(rdclass): 111 | """True if the class is a metaclass. 112 | @param rdclass: the rdata class 113 | @type rdclass: int 114 | @rtype: bool""" 115 | 116 | if rdclass in _metaclasses: 117 | return True 118 | return False 119 | -------------------------------------------------------------------------------- /dns/rdtypes/mxbase.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """MX-like base classes.""" 17 | 18 | from io import BytesIO 19 | import struct 20 | 21 | import dns.exception 22 | import dns.rdata 23 | import dns.name 24 | 25 | 26 | class MXBase(dns.rdata.Rdata): 27 | 28 | """Base class for rdata that is like an MX record. 29 | 30 | @ivar preference: the preference value 31 | @type preference: int 32 | @ivar exchange: the exchange name 33 | @type exchange: dns.name.Name object""" 34 | 35 | __slots__ = ['preference', 'exchange'] 36 | 37 | def __init__(self, rdclass, rdtype, preference, exchange): 38 | super(MXBase, self).__init__(rdclass, rdtype) 39 | self.preference = preference 40 | self.exchange = exchange 41 | 42 | def to_text(self, origin=None, relativize=True, **kw): 43 | exchange = self.exchange.choose_relativity(origin, relativize) 44 | return '%d %s' % (self.preference, exchange) 45 | 46 | @classmethod 47 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 48 | preference = tok.get_uint16() 49 | exchange = tok.get_name() 50 | exchange = exchange.choose_relativity(origin, relativize) 51 | tok.get_eol() 52 | return cls(rdclass, rdtype, preference, exchange) 53 | 54 | def to_wire(self, file, compress=None, origin=None): 55 | pref = struct.pack("!H", self.preference) 56 | file.write(pref) 57 | self.exchange.to_wire(file, compress, origin) 58 | 59 | def to_digestable(self, origin=None): 60 | return struct.pack("!H", self.preference) + \ 61 | self.exchange.to_digestable(origin) 62 | 63 | @classmethod 64 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 65 | (preference, ) = struct.unpack('!H', wire[current: current + 2]) 66 | current += 2 67 | rdlen -= 2 68 | (exchange, cused) = dns.name.from_wire(wire[: current + rdlen], 69 | current) 70 | if cused != rdlen: 71 | raise dns.exception.FormError 72 | if origin is not None: 73 | exchange = exchange.relativize(origin) 74 | return cls(rdclass, rdtype, preference, exchange) 75 | 76 | def choose_relativity(self, origin=None, relativize=True): 77 | self.exchange = self.exchange.choose_relativity(origin, relativize) 78 | 79 | 80 | class UncompressedMX(MXBase): 81 | 82 | """Base class for rdata that is like an MX record, but whose name 83 | is not compressed when converted to DNS wire format, and whose 84 | digestable form is not downcased.""" 85 | 86 | def to_wire(self, file, compress=None, origin=None): 87 | super(UncompressedMX, self).to_wire(file, None, origin) 88 | 89 | def to_digestable(self, origin=None): 90 | f = BytesIO() 91 | self.to_wire(f, None, origin) 92 | return f.getvalue() 93 | 94 | 95 | class UncompressedDowncasingMX(MXBase): 96 | 97 | """Base class for rdata that is like an MX record, but whose name 98 | is not compressed when convert to DNS wire format.""" 99 | 100 | def to_wire(self, file, compress=None, origin=None): 101 | super(UncompressedDowncasingMX, self).to_wire(file, None, origin) 102 | -------------------------------------------------------------------------------- /dns/namedict.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # Copyright (C) 2016 Coresec Systems AB 3 | # 4 | # Permission to use, copy, modify, and distribute this software and its 5 | # documentation for any purpose with or without fee is hereby granted, 6 | # provided that the above copyright notice and this permission notice 7 | # appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS" AND CORESEC SYSTEMS AB DISCLAIMS ALL 18 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 19 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CORESEC 20 | # SYSTEMS AB BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR 21 | # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 22 | # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 23 | # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 24 | # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 | 26 | """DNS name dictionary""" 27 | 28 | import collections 29 | import dns.name 30 | from ._compat import xrange 31 | 32 | 33 | class NameDict(collections.MutableMapping): 34 | 35 | """A dictionary whose keys are dns.name.Name objects. 36 | @ivar max_depth: the maximum depth of the keys that have ever been 37 | added to the dictionary. 38 | @type max_depth: int 39 | @ivar max_depth_items: the number of items of maximum depth 40 | @type max_depth_items: int 41 | """ 42 | 43 | __slots__ = ["max_depth", "max_depth_items", "__store"] 44 | 45 | def __init__(self, *args, **kwargs): 46 | self.__store = dict() 47 | self.max_depth = 0 48 | self.max_depth_items = 0 49 | self.update(dict(*args, **kwargs)) 50 | 51 | def __update_max_depth(self, key): 52 | if len(key) == self.max_depth: 53 | self.max_depth_items = self.max_depth_items + 1 54 | elif len(key) > self.max_depth: 55 | self.max_depth = len(key) 56 | self.max_depth_items = 1 57 | 58 | def __getitem__(self, key): 59 | return self.__store[key] 60 | 61 | def __setitem__(self, key, value): 62 | if not isinstance(key, dns.name.Name): 63 | raise ValueError('NameDict key must be a name') 64 | self.__store[key] = value 65 | self.__update_max_depth(key) 66 | 67 | def __delitem__(self, key): 68 | value = self.__store.pop(key) 69 | if len(value) == self.max_depth: 70 | self.max_depth_items = self.max_depth_items - 1 71 | if self.max_depth_items == 0: 72 | self.max_depth = 0 73 | for k in self.__store: 74 | self.__update_max_depth(k) 75 | 76 | def __iter__(self): 77 | return iter(self.__store) 78 | 79 | def __len__(self): 80 | return len(self.__store) 81 | 82 | def has_key(self, key): 83 | return key in self.__store 84 | 85 | def get_deepest_match(self, name): 86 | """Find the deepest match to I{name} in the dictionary. 87 | 88 | The deepest match is the longest name in the dictionary which is 89 | a superdomain of I{name}. 90 | 91 | @param name: the name 92 | @type name: dns.name.Name object 93 | @rtype: (key, value) tuple 94 | """ 95 | 96 | depth = len(name) 97 | if depth > self.max_depth: 98 | depth = self.max_depth 99 | for i in xrange(-depth, 0): 100 | n = dns.name.Name(name[i:]) 101 | if n in self: 102 | return (n, self[n]) 103 | v = self[dns.name.empty] 104 | return (dns.name.empty, v) 105 | -------------------------------------------------------------------------------- /jsonrpclib/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -- Content-Encoding: UTF-8 -- 3 | """ 4 | Utility methods, for compatibility between Python version 5 | 6 | :author: Thomas Calmant 7 | :copyright: Copyright 2017, Thomas Calmant 8 | :license: Apache License 2.0 9 | :version: 0.3.1 10 | 11 | .. 12 | 13 | Copyright 2017 Thomas Calmant 14 | 15 | Licensed under the Apache License, Version 2.0 (the "License"); 16 | you may not use this file except in compliance with the License. 17 | You may obtain a copy of the License at 18 | 19 | http://www.apache.org/licenses/LICENSE-2.0 20 | 21 | Unless required by applicable law or agreed to in writing, software 22 | distributed under the License is distributed on an "AS IS" BASIS, 23 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | See the License for the specific language governing permissions and 25 | limitations under the License. 26 | """ 27 | 28 | import sys 29 | 30 | # ------------------------------------------------------------------------------ 31 | 32 | # Module version 33 | __version_info__ = (0, 3, 1) 34 | __version__ = ".".join(str(x) for x in __version_info__) 35 | 36 | # Documentation strings format 37 | __docformat__ = "restructuredtext en" 38 | 39 | # ------------------------------------------------------------------------------ 40 | 41 | if sys.version_info[0] < 3: 42 | # Python 2 43 | # pylint: disable=E1101 44 | import types 45 | try: 46 | STRING_TYPES = ( 47 | types.StringType, 48 | types.UnicodeType 49 | ) 50 | except NameError: 51 | # Python built without unicode support 52 | STRING_TYPES = (types.StringType,) 53 | 54 | NUMERIC_TYPES = ( 55 | types.IntType, 56 | types.LongType, 57 | types.FloatType 58 | ) 59 | 60 | def to_bytes(string): 61 | """ 62 | Converts the given string into bytes 63 | """ 64 | # pylint: disable=E0602 65 | if type(string) is unicode: 66 | return str(string) 67 | return string 68 | 69 | def from_bytes(data): 70 | """ 71 | Converts the given bytes into a string 72 | """ 73 | if type(data) is str: 74 | return data 75 | return str(data) 76 | else: 77 | # Python 3 78 | # pylint: disable=E1101 79 | STRING_TYPES = ( 80 | bytes, 81 | str 82 | ) 83 | 84 | NUMERIC_TYPES = ( 85 | int, 86 | float 87 | ) 88 | 89 | def to_bytes(string): 90 | """ 91 | Converts the given string into bytes 92 | """ 93 | if type(string) is bytes: 94 | return string 95 | return bytes(string, "UTF-8") 96 | 97 | def from_bytes(data): 98 | """ 99 | Converts the given bytes into a string 100 | """ 101 | if type(data) is str: 102 | return data 103 | return str(data, "UTF-8") 104 | 105 | # ------------------------------------------------------------------------------ 106 | # Enumerations 107 | 108 | try: 109 | import enum 110 | 111 | def is_enum(obj): 112 | """ 113 | Checks if an object is from an enumeration class 114 | 115 | :param obj: Object to test 116 | :return: True if the object is an enumeration item 117 | """ 118 | return isinstance(obj, enum.Enum) 119 | except ImportError: 120 | # Pre-Python 3.4 121 | def is_enum(_): 122 | """ 123 | Before Python 3.4, enumerations didn't exist. 124 | 125 | :param _: Object to test 126 | :return: Always False 127 | """ 128 | return False 129 | 130 | # ------------------------------------------------------------------------------ 131 | # Common 132 | 133 | DictType = dict 134 | 135 | ListType = list 136 | TupleType = tuple 137 | 138 | ITERABLE_TYPES = ( 139 | list, 140 | set, frozenset, 141 | tuple 142 | ) 143 | 144 | VALUE_TYPES = ( 145 | bool, 146 | type(None) 147 | ) 148 | 149 | PRIMITIVE_TYPES = STRING_TYPES + NUMERIC_TYPES + VALUE_TYPES 150 | -------------------------------------------------------------------------------- /dns/wiredata.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | """DNS Wire Data Helper""" 17 | 18 | import sys 19 | 20 | import dns.exception 21 | from ._compat import binary_type, string_types 22 | 23 | # Figure out what constant python passes for an unspecified slice bound. 24 | # It's supposed to be sys.maxint, yet on 64-bit windows sys.maxint is 2^31 - 1 25 | # but Python uses 2^63 - 1 as the constant. Rather than making pointless 26 | # extra comparisons, duplicating code, or weakening WireData, we just figure 27 | # out what constant Python will use. 28 | 29 | 30 | class _SliceUnspecifiedBound(binary_type): 31 | 32 | def __getitem__(self, key): 33 | return key.stop 34 | 35 | if sys.version_info < (3,): 36 | def __getslice__(self, i, j): # pylint: disable=getslice-method 37 | return self.__getitem__(slice(i, j)) 38 | 39 | _unspecified_bound = _SliceUnspecifiedBound()[1:] 40 | 41 | 42 | class WireData(binary_type): 43 | # WireData is a string with stricter slicing 44 | 45 | def __getitem__(self, key): 46 | try: 47 | if isinstance(key, slice): 48 | # make sure we are not going outside of valid ranges, 49 | # do stricter control of boundaries than python does 50 | # by default 51 | start = key.start 52 | stop = key.stop 53 | 54 | if sys.version_info < (3,): 55 | if stop == _unspecified_bound: 56 | # handle the case where the right bound is unspecified 57 | stop = len(self) 58 | 59 | if start < 0 or stop < 0: 60 | raise dns.exception.FormError 61 | # If it's not an empty slice, access left and right bounds 62 | # to make sure they're valid 63 | if start != stop: 64 | super(WireData, self).__getitem__(start) 65 | super(WireData, self).__getitem__(stop - 1) 66 | else: 67 | for index in (start, stop): 68 | if index is None: 69 | continue 70 | elif abs(index) > len(self): 71 | raise dns.exception.FormError 72 | 73 | return WireData(super(WireData, self).__getitem__( 74 | slice(start, stop))) 75 | return bytearray(self.unwrap())[key] 76 | except IndexError: 77 | raise dns.exception.FormError 78 | 79 | if sys.version_info < (3,): 80 | def __getslice__(self, i, j): # pylint: disable=getslice-method 81 | return self.__getitem__(slice(i, j)) 82 | 83 | def __iter__(self): 84 | i = 0 85 | while 1: 86 | try: 87 | yield self[i] 88 | i += 1 89 | except dns.exception.FormError: 90 | raise StopIteration 91 | 92 | def unwrap(self): 93 | return binary_type(self) 94 | 95 | 96 | def maybe_wrap(wire): 97 | if isinstance(wire, WireData): 98 | return wire 99 | elif isinstance(wire, binary_type): 100 | return WireData(wire) 101 | elif isinstance(wire, string_types): 102 | return WireData(wire.encode()) 103 | raise ValueError("unhandled type %s" % type(wire)) 104 | -------------------------------------------------------------------------------- /dns/rdtypes/IN/WKS.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import socket 17 | import struct 18 | 19 | import dns.ipv4 20 | import dns.rdata 21 | from dns._compat import xrange 22 | 23 | _proto_tcp = socket.getprotobyname('tcp') 24 | _proto_udp = socket.getprotobyname('udp') 25 | 26 | 27 | class WKS(dns.rdata.Rdata): 28 | 29 | """WKS record 30 | 31 | @ivar address: the address 32 | @type address: string 33 | @ivar protocol: the protocol 34 | @type protocol: int 35 | @ivar bitmap: the bitmap 36 | @type bitmap: string 37 | @see: RFC 1035""" 38 | 39 | __slots__ = ['address', 'protocol', 'bitmap'] 40 | 41 | def __init__(self, rdclass, rdtype, address, protocol, bitmap): 42 | super(WKS, self).__init__(rdclass, rdtype) 43 | self.address = address 44 | self.protocol = protocol 45 | if not isinstance(bitmap, bytearray): 46 | self.bitmap = bytearray(bitmap) 47 | else: 48 | self.bitmap = bitmap 49 | 50 | def to_text(self, origin=None, relativize=True, **kw): 51 | bits = [] 52 | for i in xrange(0, len(self.bitmap)): 53 | byte = self.bitmap[i] 54 | for j in xrange(0, 8): 55 | if byte & (0x80 >> j): 56 | bits.append(str(i * 8 + j)) 57 | text = ' '.join(bits) 58 | return '%s %d %s' % (self.address, self.protocol, text) 59 | 60 | @classmethod 61 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 62 | address = tok.get_string() 63 | protocol = tok.get_string() 64 | if protocol.isdigit(): 65 | protocol = int(protocol) 66 | else: 67 | protocol = socket.getprotobyname(protocol) 68 | bitmap = bytearray() 69 | while 1: 70 | token = tok.get().unescape() 71 | if token.is_eol_or_eof(): 72 | break 73 | if token.value.isdigit(): 74 | serv = int(token.value) 75 | else: 76 | if protocol != _proto_udp and protocol != _proto_tcp: 77 | raise NotImplementedError("protocol must be TCP or UDP") 78 | if protocol == _proto_udp: 79 | protocol_text = "udp" 80 | else: 81 | protocol_text = "tcp" 82 | serv = socket.getservbyname(token.value, protocol_text) 83 | i = serv // 8 84 | l = len(bitmap) 85 | if l < i + 1: 86 | for j in xrange(l, i + 1): 87 | bitmap.append(0) 88 | bitmap[i] = bitmap[i] | (0x80 >> (serv % 8)) 89 | bitmap = dns.rdata._truncate_bitmap(bitmap) 90 | return cls(rdclass, rdtype, address, protocol, bitmap) 91 | 92 | def to_wire(self, file, compress=None, origin=None): 93 | file.write(dns.ipv4.inet_aton(self.address)) 94 | protocol = struct.pack('!B', self.protocol) 95 | file.write(protocol) 96 | file.write(self.bitmap) 97 | 98 | @classmethod 99 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 100 | address = dns.ipv4.inet_ntoa(wire[current: current + 4]) 101 | protocol, = struct.unpack('!B', wire[current + 4: current + 5]) 102 | current += 5 103 | rdlen -= 5 104 | bitmap = wire[current: current + rdlen].unwrap() 105 | return cls(rdclass, rdtype, address, protocol, bitmap) 106 | -------------------------------------------------------------------------------- /lib/verifier.py: -------------------------------------------------------------------------------- 1 | # Electrum - Lightweight Bitcoin Client 2 | # Copyright (c) 2012 Thomas Voegtlin 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation files 6 | # (the "Software"), to deal in the Software without restriction, 7 | # including without limitation the rights to use, copy, modify, merge, 8 | # publish, distribute, sublicense, and/or sell copies of the Software, 9 | # and to permit persons to whom the Software is furnished to do so, 10 | # subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be 13 | # included in all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | from .util import ThreadJob 24 | from .bitcoin import * 25 | 26 | 27 | class SPV(ThreadJob): 28 | """ Simple Payment Verification """ 29 | 30 | def __init__(self, network, wallet): 31 | self.wallet = wallet 32 | self.network = network 33 | self.blockchain = network.blockchain() 34 | # Keyed by tx hash. Value is None if the merkle branch was 35 | # requested, and the merkle root once it has been verified 36 | self.merkle_roots = {} 37 | 38 | def run(self): 39 | lh = self.network.get_local_height() 40 | unverified = self.wallet.get_unverified_txs() 41 | for tx_hash, tx_height in unverified.items(): 42 | # do not request merkle branch before headers are available 43 | if (tx_height > 0) and (tx_hash not in self.merkle_roots) and (tx_height <= lh): 44 | request = ('blockchain.transaction.get_merkle', 45 | [tx_hash, tx_height]) 46 | self.network.send([request], self.verify_merkle) 47 | self.print_error('requested merkle', tx_hash) 48 | self.merkle_roots[tx_hash] = None 49 | 50 | if self.network.blockchain() != self.blockchain: 51 | self.blockchain = self.network.blockchain() 52 | self.undo_verifications() 53 | 54 | def verify_merkle(self, r): 55 | if r.get('error'): 56 | self.print_error('received an error:', r) 57 | return 58 | params = r['params'] 59 | merkle = r['result'] 60 | # Verify the hash of the server-provided merkle branch to a 61 | # transaction matches the merkle root of its block 62 | tx_hash = params[0] 63 | tx_height = merkle.get('block_height') 64 | pos = merkle.get('pos') 65 | merkle_root = self.hash_merkle_root(merkle['merkle'], tx_hash, pos) 66 | header = self.network.blockchain().read_header(tx_height) 67 | if not header or header.get('merkle_root') != merkle_root: 68 | # FIXME: we should make a fresh connection to a server to 69 | # recover from this, as this TX will now never verify 70 | self.print_error("merkle verification failed for", tx_hash) 71 | return 72 | # we passed all the tests 73 | self.merkle_roots[tx_hash] = merkle_root 74 | self.print_error("verified %s" % tx_hash) 75 | self.wallet.add_verified_tx(tx_hash, (tx_height, header.get('timestamp'), pos)) 76 | 77 | def hash_merkle_root(self, merkle_s, target_hash, pos): 78 | h = hash_decode(target_hash) 79 | for i in range(len(merkle_s)): 80 | item = merkle_s[i] 81 | h = Hash(hash_decode(item) + h) if ((pos >> i) & 1) else Hash(h + hash_decode(item)) 82 | return hash_encode(h) 83 | 84 | def undo_verifications(self): 85 | height = self.blockchain.get_checkpoint() 86 | tx_hashes = self.wallet.undo_verifications(self.blockchain, height) 87 | for tx_hash in tx_hashes: 88 | self.print_error("redoing", tx_hash) 89 | self.merkle_roots.pop(tx_hash, None) 90 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/CERT.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | import base64 18 | 19 | import dns.exception 20 | import dns.dnssec 21 | import dns.rdata 22 | import dns.tokenizer 23 | 24 | _ctype_by_value = { 25 | 1: 'PKIX', 26 | 2: 'SPKI', 27 | 3: 'PGP', 28 | 253: 'URI', 29 | 254: 'OID', 30 | } 31 | 32 | _ctype_by_name = { 33 | 'PKIX': 1, 34 | 'SPKI': 2, 35 | 'PGP': 3, 36 | 'URI': 253, 37 | 'OID': 254, 38 | } 39 | 40 | 41 | def _ctype_from_text(what): 42 | v = _ctype_by_name.get(what) 43 | if v is not None: 44 | return v 45 | return int(what) 46 | 47 | 48 | def _ctype_to_text(what): 49 | v = _ctype_by_value.get(what) 50 | if v is not None: 51 | return v 52 | return str(what) 53 | 54 | 55 | class CERT(dns.rdata.Rdata): 56 | 57 | """CERT record 58 | 59 | @ivar certificate_type: certificate type 60 | @type certificate_type: int 61 | @ivar key_tag: key tag 62 | @type key_tag: int 63 | @ivar algorithm: algorithm 64 | @type algorithm: int 65 | @ivar certificate: the certificate or CRL 66 | @type certificate: string 67 | @see: RFC 2538""" 68 | 69 | __slots__ = ['certificate_type', 'key_tag', 'algorithm', 'certificate'] 70 | 71 | def __init__(self, rdclass, rdtype, certificate_type, key_tag, algorithm, 72 | certificate): 73 | super(CERT, self).__init__(rdclass, rdtype) 74 | self.certificate_type = certificate_type 75 | self.key_tag = key_tag 76 | self.algorithm = algorithm 77 | self.certificate = certificate 78 | 79 | def to_text(self, origin=None, relativize=True, **kw): 80 | certificate_type = _ctype_to_text(self.certificate_type) 81 | return "%s %d %s %s" % (certificate_type, self.key_tag, 82 | dns.dnssec.algorithm_to_text(self.algorithm), 83 | dns.rdata._base64ify(self.certificate)) 84 | 85 | @classmethod 86 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 87 | certificate_type = _ctype_from_text(tok.get_string()) 88 | key_tag = tok.get_uint16() 89 | algorithm = dns.dnssec.algorithm_from_text(tok.get_string()) 90 | if algorithm < 0 or algorithm > 255: 91 | raise dns.exception.SyntaxError("bad algorithm type") 92 | chunks = [] 93 | while 1: 94 | t = tok.get().unescape() 95 | if t.is_eol_or_eof(): 96 | break 97 | if not t.is_identifier(): 98 | raise dns.exception.SyntaxError 99 | chunks.append(t.value.encode()) 100 | b64 = b''.join(chunks) 101 | certificate = base64.b64decode(b64) 102 | return cls(rdclass, rdtype, certificate_type, key_tag, 103 | algorithm, certificate) 104 | 105 | def to_wire(self, file, compress=None, origin=None): 106 | prefix = struct.pack("!HHB", self.certificate_type, self.key_tag, 107 | self.algorithm) 108 | file.write(prefix) 109 | file.write(self.certificate) 110 | 111 | @classmethod 112 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 113 | prefix = wire[current: current + 5].unwrap() 114 | current += 5 115 | rdlen -= 5 116 | if rdlen < 0: 117 | raise dns.exception.FormError 118 | (certificate_type, key_tag, algorithm) = struct.unpack("!HHB", prefix) 119 | certificate = wire[current: current + rdlen].unwrap() 120 | return cls(rdclass, rdtype, certificate_type, key_tag, algorithm, 121 | certificate) 122 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/HIP.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010, 2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | import base64 18 | import binascii 19 | 20 | import dns.exception 21 | import dns.rdata 22 | import dns.rdatatype 23 | 24 | 25 | class HIP(dns.rdata.Rdata): 26 | 27 | """HIP record 28 | 29 | @ivar hit: the host identity tag 30 | @type hit: string 31 | @ivar algorithm: the public key cryptographic algorithm 32 | @type algorithm: int 33 | @ivar key: the public key 34 | @type key: string 35 | @ivar servers: the rendezvous servers 36 | @type servers: list of dns.name.Name objects 37 | @see: RFC 5205""" 38 | 39 | __slots__ = ['hit', 'algorithm', 'key', 'servers'] 40 | 41 | def __init__(self, rdclass, rdtype, hit, algorithm, key, servers): 42 | super(HIP, self).__init__(rdclass, rdtype) 43 | self.hit = hit 44 | self.algorithm = algorithm 45 | self.key = key 46 | self.servers = servers 47 | 48 | def to_text(self, origin=None, relativize=True, **kw): 49 | hit = binascii.hexlify(self.hit).decode() 50 | key = base64.b64encode(self.key).replace(b'\n', b'').decode() 51 | text = u'' 52 | servers = [] 53 | for server in self.servers: 54 | servers.append(server.choose_relativity(origin, relativize)) 55 | if len(servers) > 0: 56 | text += (u' ' + u' '.join((x.to_unicode() for x in servers))) 57 | return u'%u %s %s%s' % (self.algorithm, hit, key, text) 58 | 59 | @classmethod 60 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 61 | algorithm = tok.get_uint8() 62 | hit = binascii.unhexlify(tok.get_string().encode()) 63 | if len(hit) > 255: 64 | raise dns.exception.SyntaxError("HIT too long") 65 | key = base64.b64decode(tok.get_string().encode()) 66 | servers = [] 67 | while 1: 68 | token = tok.get() 69 | if token.is_eol_or_eof(): 70 | break 71 | server = dns.name.from_text(token.value, origin) 72 | server.choose_relativity(origin, relativize) 73 | servers.append(server) 74 | return cls(rdclass, rdtype, hit, algorithm, key, servers) 75 | 76 | def to_wire(self, file, compress=None, origin=None): 77 | lh = len(self.hit) 78 | lk = len(self.key) 79 | file.write(struct.pack("!BBH", lh, self.algorithm, lk)) 80 | file.write(self.hit) 81 | file.write(self.key) 82 | for server in self.servers: 83 | server.to_wire(file, None, origin) 84 | 85 | @classmethod 86 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 87 | (lh, algorithm, lk) = struct.unpack('!BBH', 88 | wire[current: current + 4]) 89 | current += 4 90 | rdlen -= 4 91 | hit = wire[current: current + lh].unwrap() 92 | current += lh 93 | rdlen -= lh 94 | key = wire[current: current + lk].unwrap() 95 | current += lk 96 | rdlen -= lk 97 | servers = [] 98 | while rdlen > 0: 99 | (server, cused) = dns.name.from_wire(wire[: current + rdlen], 100 | current) 101 | current += cused 102 | rdlen -= cused 103 | if origin is not None: 104 | server = server.relativize(origin) 105 | servers.append(server) 106 | return cls(rdclass, rdtype, hit, algorithm, key, servers) 107 | 108 | def choose_relativity(self, origin=None, relativize=True): 109 | servers = [] 110 | for server in self.servers: 111 | server = server.choose_relativity(origin, relativize) 112 | servers.append(server) 113 | self.servers = servers 114 | -------------------------------------------------------------------------------- /lib/contacts.py: -------------------------------------------------------------------------------- 1 | # Electrum - Lightweight Bitcoin Client 2 | # Copyright (c) 2015 Thomas Voegtlin 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation files 6 | # (the "Software"), to deal in the Software without restriction, 7 | # including without limitation the rights to use, copy, modify, merge, 8 | # publish, distribute, sublicense, and/or sell copies of the Software, 9 | # and to permit persons to whom the Software is furnished to do so, 10 | # subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be 13 | # included in all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | import re 24 | import dns 25 | import json 26 | 27 | from . import bitcoin 28 | from . import dnssec 29 | 30 | 31 | class Contacts(dict): 32 | 33 | def __init__(self, storage): 34 | self.storage = storage 35 | d = self.storage.get('contacts', {}) 36 | try: 37 | self.update(d) 38 | except: 39 | return 40 | # backward compatibility 41 | for k, v in self.items(): 42 | _type, n = v 43 | if _type == 'address' and bitcoin.is_address(n): 44 | self.pop(k) 45 | self[n] = ('address', k) 46 | 47 | def save(self): 48 | self.storage.put('contacts', dict(self)) 49 | 50 | def import_file(self, path): 51 | try: 52 | with open(path, 'r') as f: 53 | d = self._validate(json.loads(f.read())) 54 | except: 55 | return 56 | self.update(d) 57 | self.save() 58 | 59 | def __setitem__(self, key, value): 60 | dict.__setitem__(self, key, value) 61 | self.save() 62 | 63 | def pop(self, key): 64 | if key in self.keys(): 65 | dict.pop(self, key) 66 | self.save() 67 | 68 | def resolve(self, k): 69 | if bitcoin.is_address(k): 70 | return { 71 | 'address': k, 72 | 'type': 'address' 73 | } 74 | if k in self.keys(): 75 | _type, addr = self[k] 76 | if _type == 'address': 77 | return { 78 | 'address': addr, 79 | 'type': 'contact' 80 | } 81 | out = self.resolve_openalias(k) 82 | if out: 83 | address, name, validated = out 84 | return { 85 | 'address': address, 86 | 'name': name, 87 | 'type': 'openalias', 88 | 'validated': validated 89 | } 90 | raise Exception("Invalid Bitcoin address or alias", k) 91 | 92 | def resolve_openalias(self, url): 93 | # support email-style addresses, per the OA standard 94 | url = url.replace('@', '.') 95 | records, validated = dnssec.query(url, dns.rdatatype.TXT) 96 | prefix = 'btc' 97 | for record in records: 98 | string = record.strings[0] 99 | if string.startswith('oa1:' + prefix): 100 | address = self.find_regex(string, r'recipient_address=([A-Za-z0-9]+)') 101 | name = self.find_regex(string, r'recipient_name=([^;]+)') 102 | if not name: 103 | name = address 104 | if not address: 105 | continue 106 | return address, name, validated 107 | 108 | def find_regex(self, haystack, needle): 109 | regex = re.compile(needle) 110 | try: 111 | return regex.search(haystack).groups()[0] 112 | except AttributeError: 113 | return None 114 | 115 | def _validate(self, data): 116 | for k,v in list(data.items()): 117 | if k == 'contacts': 118 | return self._validate(v) 119 | if not bitcoin.is_address(k): 120 | data.pop(k) 121 | else: 122 | _type,_ = v 123 | if _type != 'address': 124 | data.pop(k) 125 | return data 126 | 127 | -------------------------------------------------------------------------------- /lib/segwit_addr.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 Pieter Wuille 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | # THE SOFTWARE. 20 | 21 | """Reference implementation for Bech32 and segwit addresses.""" 22 | 23 | 24 | CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" 25 | 26 | 27 | def bech32_polymod(values): 28 | """Internal function that computes the Bech32 checksum.""" 29 | generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] 30 | chk = 1 31 | for value in values: 32 | top = chk >> 25 33 | chk = (chk & 0x1ffffff) << 5 ^ value 34 | for i in range(5): 35 | chk ^= generator[i] if ((top >> i) & 1) else 0 36 | return chk 37 | 38 | 39 | def bech32_hrp_expand(hrp): 40 | """Expand the HRP into values for checksum computation.""" 41 | return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp] 42 | 43 | 44 | def bech32_verify_checksum(hrp, data): 45 | """Verify a checksum given HRP and converted data characters.""" 46 | return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1 47 | 48 | 49 | def bech32_create_checksum(hrp, data): 50 | """Compute the checksum values given HRP and data.""" 51 | values = bech32_hrp_expand(hrp) + data 52 | polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ 1 53 | return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)] 54 | 55 | 56 | def bech32_encode(hrp, data): 57 | """Compute a Bech32 string given HRP and data values.""" 58 | combined = data + bech32_create_checksum(hrp, data) 59 | return hrp + '1' + ''.join([CHARSET[d] for d in combined]) 60 | 61 | 62 | def bech32_decode(bech): 63 | """Validate a Bech32 string, and determine HRP and data.""" 64 | if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or 65 | (bech.lower() != bech and bech.upper() != bech)): 66 | return (None, None) 67 | bech = bech.lower() 68 | pos = bech.rfind('1') 69 | if pos < 1 or pos + 7 > len(bech) or len(bech) > 90: 70 | return (None, None) 71 | if not all(x in CHARSET for x in bech[pos+1:]): 72 | return (None, None) 73 | hrp = bech[:pos] 74 | data = [CHARSET.find(x) for x in bech[pos+1:]] 75 | if not bech32_verify_checksum(hrp, data): 76 | return (None, None) 77 | return (hrp, data[:-6]) 78 | 79 | 80 | def convertbits(data, frombits, tobits, pad=True): 81 | """General power-of-2 base conversion.""" 82 | acc = 0 83 | bits = 0 84 | ret = [] 85 | maxv = (1 << tobits) - 1 86 | max_acc = (1 << (frombits + tobits - 1)) - 1 87 | for value in data: 88 | if value < 0 or (value >> frombits): 89 | return None 90 | acc = ((acc << frombits) | value) & max_acc 91 | bits += frombits 92 | while bits >= tobits: 93 | bits -= tobits 94 | ret.append((acc >> bits) & maxv) 95 | if pad: 96 | if bits: 97 | ret.append((acc << (tobits - bits)) & maxv) 98 | elif bits >= frombits or ((acc << (tobits - bits)) & maxv): 99 | return None 100 | return ret 101 | 102 | 103 | def decode(hrp, addr): 104 | """Decode a segwit address.""" 105 | hrpgot, data = bech32_decode(addr) 106 | if hrpgot != hrp: 107 | return (None, None) 108 | decoded = convertbits(data[1:], 5, 8, False) 109 | if decoded is None or len(decoded) < 2 or len(decoded) > 40: 110 | return (None, None) 111 | if data[0] > 16: 112 | return (None, None) 113 | if data[0] == 0 and len(decoded) != 20 and len(decoded) != 32: 114 | return (None, None) 115 | return (data[0], decoded) 116 | 117 | 118 | def encode(hrp, witver, witprog): 119 | """Encode a segwit address.""" 120 | ret = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5)) 121 | assert decode(hrp, ret) is not (None, None) 122 | return ret 123 | -------------------------------------------------------------------------------- /dns/rdtypes/ANY/SOA.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import struct 17 | 18 | import dns.exception 19 | import dns.rdata 20 | import dns.name 21 | 22 | 23 | class SOA(dns.rdata.Rdata): 24 | 25 | """SOA record 26 | 27 | @ivar mname: the SOA MNAME (master name) field 28 | @type mname: dns.name.Name object 29 | @ivar rname: the SOA RNAME (responsible name) field 30 | @type rname: dns.name.Name object 31 | @ivar serial: The zone's serial number 32 | @type serial: int 33 | @ivar refresh: The zone's refresh value (in seconds) 34 | @type refresh: int 35 | @ivar retry: The zone's retry value (in seconds) 36 | @type retry: int 37 | @ivar expire: The zone's expiration value (in seconds) 38 | @type expire: int 39 | @ivar minimum: The zone's negative caching time (in seconds, called 40 | "minimum" for historical reasons) 41 | @type minimum: int 42 | @see: RFC 1035""" 43 | 44 | __slots__ = ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire', 45 | 'minimum'] 46 | 47 | def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry, 48 | expire, minimum): 49 | super(SOA, self).__init__(rdclass, rdtype) 50 | self.mname = mname 51 | self.rname = rname 52 | self.serial = serial 53 | self.refresh = refresh 54 | self.retry = retry 55 | self.expire = expire 56 | self.minimum = minimum 57 | 58 | def to_text(self, origin=None, relativize=True, **kw): 59 | mname = self.mname.choose_relativity(origin, relativize) 60 | rname = self.rname.choose_relativity(origin, relativize) 61 | return '%s %s %d %d %d %d %d' % ( 62 | mname, rname, self.serial, self.refresh, self.retry, 63 | self.expire, self.minimum) 64 | 65 | @classmethod 66 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 67 | mname = tok.get_name() 68 | rname = tok.get_name() 69 | mname = mname.choose_relativity(origin, relativize) 70 | rname = rname.choose_relativity(origin, relativize) 71 | serial = tok.get_uint32() 72 | refresh = tok.get_ttl() 73 | retry = tok.get_ttl() 74 | expire = tok.get_ttl() 75 | minimum = tok.get_ttl() 76 | tok.get_eol() 77 | return cls(rdclass, rdtype, mname, rname, serial, refresh, retry, 78 | expire, minimum) 79 | 80 | def to_wire(self, file, compress=None, origin=None): 81 | self.mname.to_wire(file, compress, origin) 82 | self.rname.to_wire(file, compress, origin) 83 | five_ints = struct.pack('!IIIII', self.serial, self.refresh, 84 | self.retry, self.expire, self.minimum) 85 | file.write(five_ints) 86 | 87 | def to_digestable(self, origin=None): 88 | return self.mname.to_digestable(origin) + \ 89 | self.rname.to_digestable(origin) + \ 90 | struct.pack('!IIIII', self.serial, self.refresh, 91 | self.retry, self.expire, self.minimum) 92 | 93 | @classmethod 94 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 95 | (mname, cused) = dns.name.from_wire(wire[: current + rdlen], current) 96 | current += cused 97 | rdlen -= cused 98 | (rname, cused) = dns.name.from_wire(wire[: current + rdlen], current) 99 | current += cused 100 | rdlen -= cused 101 | if rdlen != 20: 102 | raise dns.exception.FormError 103 | five_ints = struct.unpack('!IIIII', 104 | wire[current: current + rdlen]) 105 | if origin is not None: 106 | mname = mname.relativize(origin) 107 | rname = rname.relativize(origin) 108 | return cls(rdclass, rdtype, mname, rname, 109 | five_ints[0], five_ints[1], five_ints[2], five_ints[3], 110 | five_ints[4]) 111 | 112 | def choose_relativity(self, origin=None, relativize=True): 113 | self.mname = self.mname.choose_relativity(origin, relativize) 114 | self.rname = self.rname.choose_relativity(origin, relativize) 115 | -------------------------------------------------------------------------------- /dns/rdtypes/dnskeybase.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. 2 | # 3 | # Permission to use, copy, modify, and distribute this software and its 4 | # documentation for any purpose with or without fee is hereby granted, 5 | # provided that the above copyright notice and this permission notice 6 | # appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | 16 | import base64 17 | import struct 18 | 19 | import dns.exception 20 | import dns.dnssec 21 | import dns.rdata 22 | 23 | # wildcard import 24 | __all__ = ["SEP", "REVOKE", "ZONE", 25 | "flags_to_text_set", "flags_from_text_set"] 26 | 27 | # flag constants 28 | SEP = 0x0001 29 | REVOKE = 0x0080 30 | ZONE = 0x0100 31 | 32 | _flag_by_text = { 33 | 'SEP': SEP, 34 | 'REVOKE': REVOKE, 35 | 'ZONE': ZONE 36 | } 37 | 38 | # We construct the inverse mapping programmatically to ensure that we 39 | # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that 40 | # would cause the mapping not to be true inverse. 41 | _flag_by_value = dict((y, x) for x, y in _flag_by_text.items()) 42 | 43 | 44 | def flags_to_text_set(flags): 45 | """Convert a DNSKEY flags value to set texts 46 | @rtype: set([string])""" 47 | 48 | flags_set = set() 49 | mask = 0x1 50 | while mask <= 0x8000: 51 | if flags & mask: 52 | text = _flag_by_value.get(mask) 53 | if not text: 54 | text = hex(mask) 55 | flags_set.add(text) 56 | mask <<= 1 57 | return flags_set 58 | 59 | 60 | def flags_from_text_set(texts_set): 61 | """Convert set of DNSKEY flag mnemonic texts to DNSKEY flag value 62 | @rtype: int""" 63 | 64 | flags = 0 65 | for text in texts_set: 66 | try: 67 | flags += _flag_by_text[text] 68 | except KeyError: 69 | raise NotImplementedError( 70 | "DNSKEY flag '%s' is not supported" % text) 71 | return flags 72 | 73 | 74 | class DNSKEYBase(dns.rdata.Rdata): 75 | 76 | """Base class for rdata that is like a DNSKEY record 77 | 78 | @ivar flags: the key flags 79 | @type flags: int 80 | @ivar protocol: the protocol for which this key may be used 81 | @type protocol: int 82 | @ivar algorithm: the algorithm used for the key 83 | @type algorithm: int 84 | @ivar key: the public key 85 | @type key: string""" 86 | 87 | __slots__ = ['flags', 'protocol', 'algorithm', 'key'] 88 | 89 | def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key): 90 | super(DNSKEYBase, self).__init__(rdclass, rdtype) 91 | self.flags = flags 92 | self.protocol = protocol 93 | self.algorithm = algorithm 94 | self.key = key 95 | 96 | def to_text(self, origin=None, relativize=True, **kw): 97 | return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm, 98 | dns.rdata._base64ify(self.key)) 99 | 100 | @classmethod 101 | def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): 102 | flags = tok.get_uint16() 103 | protocol = tok.get_uint8() 104 | algorithm = dns.dnssec.algorithm_from_text(tok.get_string()) 105 | chunks = [] 106 | while 1: 107 | t = tok.get().unescape() 108 | if t.is_eol_or_eof(): 109 | break 110 | if not t.is_identifier(): 111 | raise dns.exception.SyntaxError 112 | chunks.append(t.value.encode()) 113 | b64 = b''.join(chunks) 114 | key = base64.b64decode(b64) 115 | return cls(rdclass, rdtype, flags, protocol, algorithm, key) 116 | 117 | def to_wire(self, file, compress=None, origin=None): 118 | header = struct.pack("!HBB", self.flags, self.protocol, self.algorithm) 119 | file.write(header) 120 | file.write(self.key) 121 | 122 | @classmethod 123 | def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): 124 | if rdlen < 4: 125 | raise dns.exception.FormError 126 | header = struct.unpack('!HBB', wire[current: current + 4]) 127 | current += 4 128 | rdlen -= 4 129 | key = wire[current: current + rdlen].unwrap() 130 | return cls(rdclass, rdtype, header[0], header[1], header[2], 131 | key) 132 | 133 | def flags_to_text_set(self): 134 | """Convert a DNSKEY flags value to set texts 135 | @rtype: set([string])""" 136 | return flags_to_text_set(self.flags) 137 | --------------------------------------------------------------------------------