So here’s the most basic whois server in Python (connects to a PostgreSQL DB for the cached data):
Also, a funny holiday reminder that the NSA is spying on all of us!
limiter.py
#!/usr/bin/python import ast import getpass import hashlib import os import random import re import socket import string import sys import time def rstr(size): outp = "" for x in range(0, size): outp += random.choice(string.digits + string.ascii_uppercase + string.ascii_lowercase + "[email protected]#$%^&*-_=+?") return outp fobj = open(sys.argv[1], "r") conf = ast.literal_eval(fobj.read().strip()) fobj.close() servport = conf["limiter"]["port"] password = conf["limiter"]["pass"] numtimes = conf["limiter"]["conn"] timeouts = conf["limiter"]["time"] prepad = rstr(8); pospad = rstr(8); cntrlist = [] addrlist = {} sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sockobjc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sockobjc.bind(("", servport)) sockobjc.listen(1) while (1): (sockconn, sockaddr) = sockobjc.accept() print("conn open:", sockaddr) try: sockconn.settimeout(1) datalist = sockconn.recv(1024).strip().split(" ") try: sendflag = 0 scounter = datalist[0].strip() inetaddr = datalist[1].strip() authhash = datalist.pop() sharedsec = (prepad + " " + password + " " + pospad) temphash = hashlib.sha256(sharedsec + " " + " ".join(datalist) + " " + sharedsec).hexdigest() if (temphash != authhash): sockconn.send("0" + " " + prepad + " " + pospad) sendflag = 1 else: if (len(cntrlist) >= 65536): prepad = rstr(8); pospad = rstr(8); cntrlist = [] if (scounter in cntrlist): sockconn.send("1" + " " + scounter) sendflag = 1 else: cntrlist.append(scounter) if (not inetaddr in addrlist.keys()): addrlist[inetaddr] = [0, 0] prestime = time.time() if ((prestime - addrlist[inetaddr][0]) >= timeouts): addrlist[inetaddr][0] = prestime addrlist[inetaddr][1] = 0 print("conn info:", sockaddr, scounter, datalist, addrlist[inetaddr]) if (addrlist[inetaddr][1] < numtimes): addrlist[inetaddr][1] += 1 sockconn.send("2" + " " + "ok") sendflag = 1 if (sendflag != 1): sockconn.send("2" + " " + "no") except: pass except: pass try: print("conn closed:", sockaddr) sockconn.shutdown(socket.SHUT_RDWR) sockconn.close() except: pass
whoiss.py
#!/usr/bin/python import ast import getpass import hashlib import os import psycopg2 import random import re import socket import string import sys import time def sstr(inpt): outp = "" yesl = (string.digits + string.ascii_uppercase + string.ascii_lowercase + "-_.") for chrl in inpt: if (chrl in yesl): outp += chrl return outp def rnum(size): random.seed(time.time()) outp = "" for x in range(0, size): outp += random.choice(string.digits) return outp def lims(connaddr): global limhost, limport global limpass, limpre, limpos x = 0 limresp = ["-1"] try: while ((x < 8) and (limresp[0] != "2")): limnumb = rnum(8) limobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) limobjc.connect((limhost, limport)) limdata = (limnumb + " " + connaddr) limsec = (limpre + " " + limpass + " " + limpos) limhash = hashlib.sha256(limsec + " " + limdata + " " + limsec).hexdigest() limobjc.sendall(limdata + " " + limhash) limresp = limobjc.recv(1024).strip().split(" ") limobjc.close() if (len(limresp) < 1): limresp = ["-1"] if (limresp[0] == "0"): limpre = limresp[1] limpos = limresp[2] elif (limresp[0] == "1"): pass print("recv limit:", limdata, limresp) x += 1 except: pass return limresp '''{ "db":{"host":"127.0.0.1", "user":"whois", "pass":"Siohw1!", "name":"dbname", "table":"whois_cache", "col":"text"}, "limiter":{"host":"127.0.0.1", "port":3434, "pass":"Limiter1!", "conn":1, "time":10}, "whois":{"port":4343}, }''' fobj = open(sys.argv[1], "r") conf = ast.literal_eval(fobj.read().strip()) fobj.close() servport = conf["whois"]["port"] childlist = [] limhost = conf["limiter"]["host"] limport = conf["limiter"]["port"] limpass = conf["limiter"]["pass"] limpre = ""; limpos = "" sqlshost = conf["db"]["host"] sqlsuser = conf["db"]["user"] sqlspass = conf["db"]["pass"] sqlsdb = conf["db"]["name"] sqlstbl = conf["db"]["table"] sqlscol = conf["db"]["col"] sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sockobjc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sockobjc.bind(("", servport)) sockobjc.listen(1) while (1): for x in range(0, len(childlist)): try: os.waitpid(childlist[x], os.WNOHANG) except: childlist[x] = -1 while (-1 in childlist): childlist.remove(-1) lims("127.0.0.1") (sockconn, sockaddr) = sockobjc.accept() print("conn open:", sockaddr) try: childpid = os.fork() except: childpid = -1 if (childpid == 0): resplim = lims(sockaddr[0]) try: sqldom = sockconn.recv(1024).strip() sqldom = sstr(sqldom.upper()) connresp = "" print("conn data:", sockaddr, sqldom) if ((resplim[0] == "2") and (resplim[1] == "ok")): try: conn = psycopg2.connect("host='%s' dbname='%s' user='%s' password='%s'" % (sqlshost, sqlsdb, sqlsuser, sqlspass)) curs = conn.cursor() curs.execute("SELECT %s FROM %s WHERE name = '%s';" % (sqlscol, sqlstbl, sqldom)) rows = curs.fetchall() conn.close() leng = 0 for rowo in rows: connresp = ("%s\n\n\n" % (rowo[0].strip())) leng += 1 break if (leng < 1): connresp = ("NOT FOUND\n") except: connresp = ("SERVER ERROR (1)\n") else: connresp = ("LIMIT REACHED\n") sockconn.send(connresp) except: pass try: print("conn closed:", sockaddr) sockconn.shutdown(socket.SHUT_RDWR) sockconn.close() except: pass sys.exit(0) else: try: sockconn.close() except: pass childlist.append(childpid)
Limiter Notes:
- The shared secret is padded with 2 random strings:
- shared-secret = (pre-pad + common-password + post-pad)
- These 2 strings are re-generated after 2^16 unique nonces are used
- The message data is prefixed with a unique nonce string:
- message-data = (uniq-nonce + message-body)
- The limiter server uses sha256 hashing to authenticate data:
- auth-message = sha256(shared-secret + message-data + shared-secret)
- Can switch to a basic HMAC call if greater security is needed
- The limiter server is a single process which communicates with any connecting clients
- Can switch to a forked-child setup if faster connections are needed
Whois Notes:
- The whois server uses forked-child processes to communicate with multiple clients at the same time
- Each client process will make its own connection to the database server
[…] Whois Server (Python) […]
[…] Whois Server […]
I have been browsing online more than 4 hours today, yet I never
found any interesting article like yours. It’s pretty worth enough for me.
In my opinion, if all web owners and bloggers made good content as you did, the web
will be a lot more useful than ever before.
Appreciating the dedication you put into your website and in depth information you offer.
It’s nice to come across a blog every once in a while that
isn’t the same outdated rehashed material. Great read!
I’ve bookmarked your site and I’m adding your RSS feeds to my Google account.
I’m impressed, I must say. Seldom do I encounter a blog that’s both educative and entertaining, and without a doubt, you
have hit the nail on the head. The problem is an issue that not enough men and women are speaking intelligently about.
Now i’m very happy I came across this during my hunt for something regarding this.
Thanks for sharing such a fastidious idea, aarticle is good, thats
why i have read it entirely
You should take part in a contest for one of the finest websites online.
I’m going to recommend this site!
Oh my goodness! Impressive article dude! Many thanks, However
I am encountering difficulties with your RSS. I don’t
understand why I cannot join it. Is there anybody else having identical RSS problems?
Anyone that knows the solution will you kindly respond?
Thanks!!
Imponujący artykuł, aż chce się czytać dalej
Greetings from Carolina! I’m bored to tears at work so I decided to check out your site on my iphone
during lunch break. I enjoy the knowledge you provide here and can’t wait to take a
look when I get home. I’m surprised at how fast your blog filled on my cell phone ..
I’m not even using WIFI, just 3G .. Anyways, amazing site!
Thanks for finally talking about >A small whois server and
a nice holiday video | Jon’s FOSS Blog <Loved it!
If you are going for best contents like I do, only pay a
quick visit this website daily as it gives quality contents, thanks
It is really a great and useful piece of information.
I am happy that you simply shared this useful
information with us. Please stay us informed like this.
Thanks for sharing.
Generally I do not read post on blogs, but I wish to say
that this write-up very pressured me to take a look at and do it!
Your writing taste has been amazed me. Thank you, quite nice post.
This is a very good tip particularly to those new to the blogosphere.
Short but very precise info… Appreciate your sharing this one.
A must read post!