summaryrefslogtreecommitdiff
path: root/client_manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'client_manager.py')
-rw-r--r--client_manager.py140
1 files changed, 140 insertions, 0 deletions
diff --git a/client_manager.py b/client_manager.py
new file mode 100644
index 0000000..84bf3df
--- /dev/null
+++ b/client_manager.py
@@ -0,0 +1,140 @@
+
+# main logic
+
+from sys_init import setup
+setup()
+
+import pyinotify
+import subprocess
+import re
+import pwd
+import os
+import json
+import atexit
+import fcntl
+
+def get_ssh_port(pid):
+ '''
+ Jan 31 07:50:28 vultr sshd[43690]: Accepted publickey for root from 210.10.76.5 port 43730 ssh2: ED25519 SHA256:qz9ffMCb3vPlabn3ZHee00qIPBxkDiUiVSorcUkGdII
+ Jan 31 07:50:28 vultr sshd[43690]: pam_unix(sshd:session): session opened for user root(uid=0) by root(uid=0)
+ Jan 31 07:50:29 vultr sshd[43693]: Received disconnect from 210.10.76.5 port 43730:11: disconnected by user
+ Jan 31 07:50:29 vultr sshd[43693]: Disconnected from user root 210.10.76.5 port 43730
+ Jan 31 07:50:29 vultr sshd[43690]: pam_unix(sshd:session): session closed for user root
+ '''
+ '''
+ # less efficient but readable
+ pid = '33216'
+ pids = []
+ port = -1
+ for l in lines:
+ l = l.split()
+ if pid == l[1]:
+ commonstring = l[8]
+ for l2 in lines:
+ if commonstring in l2.split():
+ pids.append(l2.split()[1])
+ for i in pids:
+ for l in lines:
+ l = l.split()
+ if i in l[1] and "*:" in l[8]:
+ port = l[8][2:]
+ '''
+ try:
+ lines = subprocess.check_output("lsof -i -n | grep sshd", shell=True, text=True).splitlines()
+ pid = str(pid)
+ pids = {l.split()[1] for l in lines
+ if pid == l.split()[1] or
+ l.split()[8] in [x.split()[8] for x in lines if x.split()[1] == pid]}
+
+ port = next(l.split()[8][2:] for l in lines if l.split()[1] in pids and "*:" in l.split()[8])
+ return port
+ except:
+ return -1
+
+def get_keyname(fingerprint):
+ auth_file = os.path.join(os.path.expanduser(f"~{user}"), ".ssh", "authorized_keys")
+ try:
+ result = subprocess.run(['ssh-keygen', '-lf', f'{auth_file}'], capture_output=True, text=True, shell=False, check=True)
+ # Raises CalledProcessError if command fails, for check = true
+
+ #256 SHA256:d9CBxSLBLzLjYGZDCsO6V+lddlN/elK1hGDBS56cbTo user@host (ED25519)
+ for line in result.stdout.strip().split('\n'):
+ parts = line.split()
+ if fingerprint in parts[1]:
+ return parts[2]
+ return 'not found'
+
+ except subprocess.CalledProcessError as e:
+ print(f"Error executing command: {e}")
+ return None
+ except Exception as e:
+ print(f"Error processing output: {e}")
+ return None
+
+def write_data(data):
+ with open('/tmp/ssh_sessions.json', 'w') as f:
+ # Get exclusive lock for writing
+ fcntl.flock(f.fileno(), fcntl.LOCK_EX)
+ try:
+ # Clear file and write new data
+ f.seek(0)
+ json.dump(data, f)
+ f.truncate()
+ finally:
+ fcntl.flock(f.fileno(), fcntl.LOCK_UN)
+
+def handle_log_change(event):
+ global last_position
+ with open(event.pathname, 'r') as f:
+ # Go to end and read new lines
+ f.seek(last_position)
+ new_lines = f.readlines()
+ last_position = f.tell()
+
+ for line in new_lines:
+ #print(f"New log: {line.strip()}")
+ line = line.strip()
+ if f"Accepted publickey for {user}" in line:
+ pid = re.search(r'\[(\d+)\]', line.split()[4]).group(1)
+ port = get_ssh_port(pid)
+ keyname = get_keyname(line.split()[15])
+ srcip = line.split()[10]
+ #print(pid, port, keyname, srcip)
+ ssh_sessions[pid] = [srcip, keyname, port]
+ ssh_sessions[pid] = {
+ 'srcip': srcip,
+ 'key': keyname,
+ 'pubport': port
+ }
+ write_data(ssh_sessions)
+ if "pam_unix(sshd:session): session closed" in line:
+ pid = re.search(r'\[(\d+)\]', line.split()[4]).group(1)
+ if pid in ssh_sessions:
+ del ssh_sessions[pid]
+ else:
+ print("WARNING! PID NOT FOUND IN SESSION CACHE!")
+ write_data(ssh_sessions)
+
+ print("db: ",ssh_sessions)
+
+
+
+user = "root"
+
+# init last_position
+global last_position
+with open('/var/log/secure', 'r') as f:
+ f.seek(0, 2)
+ last_position = f.tell()
+
+global ssh_sessions
+ssh_sessions = {}
+
+wm = pyinotify.WatchManager()
+wm.add_watch('/var/log/secure', pyinotify.IN_MODIFY, handle_log_change)
+notifier = pyinotify.Notifier(wm)
+
+print("Watching /var/log/secure...")
+notifier.loop()
+
+