archive

- Random tools & helpful resources for IRC
git clone git://git.acid.vegas/archive.git
Log | Files | Refs | Archive

identd.py (2153B)

      1 #!/usr/bin/env python
      2 # ident protocol daemon - developed by acidvegas in Python (https://acid.vegas/random)
      3 
      4 import os
      5 import random
      6 import re
      7 import socket
      8 import string
      9 import threading
     10 import pwd
     11 
     12 def check_privledges():
     13 	if os.getuid() == 0 or os.geteuid() == 0:
     14 		return True
     15 	else:
     16 		return False
     17 
     18 def is_valid_port(port):
     19 	if port > 0 and port <= 65535:
     20 		return True
     21 	else:
     22 		return False
     23 
     24 def random_str(size):
     25 	return ''.join(random.choice(string.ascii_letters) for _ in range(size))
     26 
     27 class Identd(threading.Thread):
     28 	def __init__(self, protocol, address, port):
     29 		self.protocol = protocol
     30 		self.address  = address
     31 		self.port     = port
     32 		self.sock     = None
     33 		threading.Thread.__init__(self)
     34 
     35 	def run(self):
     36 		try:
     37 			self._create_sockets()
     38 			self._drop_privledges()
     39 			self._listen()
     40 		except Exception as ex:
     41 			print('error: ' + str(ex))
     42 
     43 	def _create_sockets(self):
     44 		self.sock = socket.socket(self.protocol)
     45 		self.sock.bind((self.address, self.port))
     46 		self.sock.listen(5)
     47 		self.sock.setblocking(0)
     48 
     49 	def _drop_privledges(self):
     50 		os.setgroups([])
     51 		os.setgid(pwd.getpwnam('nobody').pw_gid)
     52 		os.setuid(pwd.getpwnam('nobody').pw_uid)
     53 
     54 	def _listen(self):
     55 		while True:
     56 			client, addr = self.sock.accept()
     57 			data = client.recv(1024).decode('ascii').rstrip()
     58 			source_ip = addr[0][7:] if addr[0][:7] == '::ffff:' else addr[0]
     59 			print(f'[REQUEST] {source_ip}: {data}')
     60 			response = self._parse_data(data)
     61 			client.send(f'{response}\r\n'.encode('ascii'))
     62 			print(f'[ REPLY ] {source_ip}: {response}')
     63 			client.close()
     64 
     65 	def _parse_data(self, data):
     66 		if not re.match(r'(\d+).*,.*(\d+)', data):
     67 			return data + ' : ERROR : INVALID-PORT'
     68 		lport, rport = data.split(',')
     69 		lport = int(re.sub(r'\D', '', lport))
     70 		rport = int(re.sub(r'\D', '', rport))
     71 		if not is_valid_port(lport) or not is_valid_port(rport):
     72 			return data + ' : ERROR : INVALID-PORT'
     73 		return data + ' : USERID : UNIX : ' + random_str(5)
     74 
     75 # Main
     76 if not check_privledges():
     77 	raise SystemExit('requires sudo privledges to bind to port 113')
     78 Identd(socket.AF_INET,  '0.0.0.0', 113).start()
     79 Identd(socket.AF_INET6, '::',      113).start()
     80 while True:
     81 	input('')