Compare commits

..

32 Commits

Author SHA1 Message Date
4fb575ba62 Remove extraneous files 2022-10-11 01:39:26 -05:00
44166a2507 Add login functionality (no hashing) 2022-10-11 01:36:50 -05:00
09836efcc4 Ignore all generated csvs for development 2022-10-10 23:51:54 -05:00
1254b543e9 Add both links to ntfy 2022-10-10 23:38:42 -05:00
3838c37b1b Add icon to built exe, default run as admin with manifest, add bash runner script 2022-10-10 23:25:26 -05:00
02175cc67e Install into subfolder 2022-10-10 23:15:54 -05:00
c9de444432 Add exe installer builder 2022-10-10 23:13:30 -05:00
a83e4016ab Fix program quit, enable debug mode 2022-10-10 22:35:52 -05:00
d069196887 actually figure out tags now 2022-10-10 22:25:10 -05:00
ffefad5db5 Actually build before release 2022-10-10 22:13:31 -05:00
f0121274a6 Add notifications 2022-10-10 22:10:58 -05:00
302dcd5529 figure out how tags work 2022-10-10 22:08:54 -05:00
0a55b3ae8c Fix branch tag for release 2022-10-10 22:05:45 -05:00
494afed4ae Actually push commits 2022-10-10 22:03:07 -05:00
b12902183d Unique release tag 2022-10-10 22:01:36 -05:00
f3822c32f2 Publish release 2022-10-10 21:56:38 -05:00
8c5004c24d reformat curl 2022-10-10 21:51:34 -05:00
fb7544fe98 fix release script 2022-10-10 21:50:47 -05:00
0cf55aef93 split up files, add release script 2022-10-10 21:49:28 -05:00
45e1204397 Switch to paramiko; log output 2022-10-10 19:19:00 -05:00
d38e1384a6 add sftp 2022-09-27 21:04:49 -05:00
faafcf8505 update gitignore 2022-09-27 20:26:10 -05:00
0483147207 latest changes 2022-09-27 20:14:23 -05:00
3afe7faf7c add changes from last week 2022-09-27 18:30:27 -05:00
166aa5d93a simplify OS detection 2022-09-19 23:30:59 -05:00
e043a03890 add additional comments 2022-09-19 23:26:29 -05:00
8b005d0ece make more stuff win32 specific 2022-09-19 23:17:28 -05:00
ca3e489adb Add advanced windows netstat parser 2022-09-19 23:14:02 -05:00
159bbf2130 test data collection 2022-09-19 21:00:48 -05:00
b4aecb1974 test modules 2022-09-13 20:59:07 -05:00
f415fe7a6d add icon 2022-09-06 20:21:07 -05:00
c25f517aab add tray icon test 2022-09-06 20:21:02 -05:00
20 changed files with 57816 additions and 120 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
__pycache__/
build/
config.yaml
*.csv
admin-key.ppk
token.txt
*.zip
output.log

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

26
auth.py Normal file
View File

@ -0,0 +1,26 @@
import ssh
import csv
from util import fprint
from util import find_data_file
from time import sleep
def login(config, user, password, sysid):
fprint("Attempting to login as " + user)
filename = sysid + "login.csv"
with open(find_data_file(filename), "w", newline="") as f:
writer = csv.writer(f)
writer.writerows([[user,password,sysid],])
fprint("done creating csv")
ssh.sftp_send_data(config, filename, 'sendlogin')
command = "python3 login_service.py " + sysid
ssh.run_ssh(config, command, 'scripts')
sleep(1)
filename = sysid + "success.txt"
if ssh.check_for_file(config, filename, 'receivelogin') == False:
filename = sysid + "fail.txt"
if ssh.check_for_file(config, filename, 'receivelogin') == False:
raise ValueError("Unable to determine login status")
else:
return False
else:
return True

19
config.yml Normal file
View File

@ -0,0 +1,19 @@
sftp:
host: ec2-34-232-29-46.compute-1.amazonaws.com
user: ec2-user
port: 22
keyfile: keyfile-admin.pem
filepath:
send: /home/ec2-user/Incoming/Incoming_Data
sendlogin: /home/ec2-user/Incoming/Login
receive: /home/ec2-user/Outgoing/Outgoing_Data
receivelogin: /home/ec2-user/Outgoing/Login
scripts: /home/ec2-user/scripts
ui:
darkmode: true
core:
autokill: false
localadmin: true
interval: 10

View File

@ -1,151 +1,138 @@
import glob import glob
import wx import wx
import wx.lib.buttons as buttons import wx.adv
from wx.adv import Wizard, WizardPageSimple import os
from time import sleep
from multiprocessing import Process, Pipe
from sys import platform
TRAY_TOOLTIP = 'IP Pigeon'
TRAY_ICON = 'icon.png'
"""if platform == "linux" or platform == "linux2":
# linux
elif platform == "darwin":
# OS X
elif platform == "win32":
# Windows...
"""
displaydata = None
settings = None
class ServerPanel(wx.Panel):
class ServerPanel(wx.Frame):
def __init__(self, parent): def __init__(self, parent):
self.open_dashboard
super().__init__(parent) super().__init__(parent)
main_sizer = wx.BoxSizer(wx.VERTICAL) main_sizer = wx.BoxSizer(wx.VERTICAL)
secondary_sizer = wx.BoxSizer(wx.HORIZONTAL)
menubar = wx.MenuBar()
menu = wx.Menu()
menubar.Append(menu,"File")
self.SetMenuBar(menubar)
tb = wx.ToolBar( self, -1)
self.ToolBar = tb
#tb.AddTool( wx.ID_ANY, '', wx.Bitmap("IPPigeonLogo.png"))
tb.AddTool(0, '',wx.Bitmap("WXPython.png"), "Server Dashboard")
tb.AddTool(1, '',wx.Bitmap("settings.png"), "Settings")
#tb.Bind(wx.EVT_TOOL, self.Onright)
#tb.Bind(wx.EVT_COMBOBOX,self.OnCombo)
#self.combo = wx.ComboBox( tb, 555, value = "Times", choices = ["Papyrus","Times","Comic Sans"])
#tb.AddControl(self.combo )
tb.Realize()
main_sizer.Add(tb)
self.Show(True)
self.row_obj_dict = {} self.row_obj_dict = {}
self.list_ctrl = wx.ListCtrl( self.list_ctrl = wx.ListCtrl(
self, size=(-1, 100), self, size=(-1, 100),
style=wx.LC_REPORT | wx.BORDER_SUNKEN style=wx.LC_REPORT | wx.BORDER_SUNKEN
) )
self.SetBackgroundColour(wx.BLACK)
self.list_ctrl.InsertColumn(0, 'Server name', width=140) self.list_ctrl.InsertColumn(0, 'Server name', width=140)
self.list_ctrl.InsertColumn(1, 'Port number', width=140) self.list_ctrl.InsertColumn(1, 'Port number', width=140)
self.list_ctrl.InsertColumn(2, 'Status', width=200) self.list_ctrl.InsertColumn(2, 'Status', width=200)
main_sizer.Add(self.list_ctrl, 0, wx.ALL | wx.EXPAND, 5) main_sizer.Add(self.list_ctrl, 0, wx.ALL | wx.EXPAND, 5)
start_button = wx.Button(self, label='Start') start_button = wx.Button(self, label='Start')
start_button.SetBackgroundColour((205, 215, 206))
start_button.Bind(wx.EVT_BUTTON, self.on_edit) start_button.Bind(wx.EVT_BUTTON, self.on_edit)
stop_button = wx.Button(self, label='Stop') stop_button = wx.Button(self, label='Stop')
stop_button.SetBackgroundColour('#F08080')
# wx.BORDER(stop_button, wx.BORDER_NONE)
stop_button.Bind(wx.EVT_BUTTON, self.on_edit) stop_button.Bind(wx.EVT_BUTTON, self.on_edit)
main_sizer.Add(start_button, 0, wx.CENTER | 100, 5) main_sizer.Add(start_button, 0, wx.ALL | 100, 5)
main_sizer.Add(stop_button, 0, wx.CENTER | 100, 5) main_sizer.Add(stop_button, 0, wx.ALL | 100, 5)
# start_button.SetWindowStyleFlag(wx.SIMPLE_BORDER)
# stop_button.SetWindowStyleFlag(wx.SIMPLE_BORDER)
# wx.StaticBitmap(self, -1, png, (500, 300), (png.GetWidth(), png.GetHeight()))
self.SetSizer(main_sizer) self.SetSizer(main_sizer)
self.Bind(wx.EVT_TOOL, self.open_dashboard, id=0)
self.Bind(wx.EVT_TOOL, self.open_settings, id=1)
# self.Bind(wx.EVT_BUTTON, super().__init__(parent))
# self.Bind(wx.EVT_BUTTON, self.open_settings)
def on_edit(self, event): def on_edit(self, event):
print('in on_edit') print('in on_edit')
def open_dashboard(self, e): def update_mp3_listing(self, folder_path):
print("open dashboard") print(folder_path)
def open_settings(self,e):
print("open settings")
dg = GetData(parent = None)
dg.ShowModal()
# box = wx.TextEntryDialog(None, "Host: ")
# if box.ShowModal() == wx.ID_OK:
# answer = box.GetValue()
# main_sizer = wx.BoxSizer(wx.VERTICAL)
# self.Bind(wx.EVT_TOOL, self.open_dashboard, id=0)
# self.Bind(wx.EVT_TOOL, self.open_settings, id=1)
class GetData(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent, wx.ID_ANY, "User Settings", size = (800,440))
self.p = wx.Panel(self, wx.ID_ANY)
self.hostname = wx.StaticText(self.p, label="Host", pos=(20,20))
self.hostnametext = wx.TextCtrl(self.p, value="", pos=(180,20), size=(500,-1))
self.user = wx.StaticText(self.p, label="User: ", pos=(20,60))
self.usertext = wx.TextCtrl(self.p, value="", pos=(180,60), size=(500,-1))
self.port = wx.StaticText(self.p, label="Port: ", pos=(20,100))
self.porttext = wx.TextCtrl(self.p, value="", pos=(180,100), size=(500,-1))
self.keyfile = wx.StaticText(self.p, label="Keyfile: ", pos=(20,140))
self.keyfiletext = wx.TextCtrl(self.p, value="", pos=(180,140), size=(500,-1))
self.filepathsend = wx.StaticText(self.p, label="Sending File Path: ", pos=(20,180))
self.filepathsendtext = wx.TextCtrl(self.p, value="", pos=(180,180), size=(500,-1))
self.filepathsendlogin = wx.StaticText(self.p, label="Sending Login Path: ", pos=(20,220))
self.filepathsendlogintext = wx.TextCtrl(self.p, value="", pos=(180,220), size=(500,-1))
self.filepathreceive = wx.StaticText(self.p, label="Receiving File Path: ", pos=(20,260))
self.filepathreceivetext = wx.TextCtrl(self.p, value="", pos=(180,260), size=(500,-1))
self.filepathreceivelogin = wx.StaticText(self.p, label="Receiving Login Path: ", pos=(20,300))
self.filepathreceivelogintext = wx.TextCtrl(self.p, value="", pos=(180,300), size=(500,-1))
self.darkmode = wx.StaticText(self.p, label="Dark mode (On/Off): ", pos=(20,340))
self.darkmodetext = wx.TextCtrl(self.p, value="", pos=(180,340), size=(500,-1))
self.interval = wx.StaticText(self.p, label="Interval (sec): ", pos=(20,380))
self.interval = wx.TextCtrl(self.p, value="", pos=(180,380), size=(500,-1))
self.Bind(wx.EVT_CLOSE, self.OnQuit)
def OnQuit(self, event):
self.result_name = None
self.Destroy()
def on_edit(self, event):
print('in on_edit')
class ServerFrame(wx.Frame): class ServerFrame(wx.Frame):
def __init__(self): def __init__(self):
super().__init__(parent=None, title='Server Dashboard') super().__init__(parent=None,
self.frame = ServerPanel(self) title='Server Dashboard')
# image = wx.StaticBitmap(self, wx.ID_ANY) self.panel = ServerPanel(self)
# image.SetBitmap(wx.Bitmap('WXPython.png')) self.Show()
# self.Show()
### Taskbar Icon
def create_menu_item(menu, label, func):
item = wx.MenuItem(menu, -1, label)
menu.Bind(wx.EVT_MENU, func, id=item.GetId())
menu.Append(item)
return item
class TaskBarIcon(wx.adv.TaskBarIcon):
def __init__(self, frame):
self.frame = frame
super(TaskBarIcon, self).__init__()
self.set_icon(TRAY_ICON)
self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)
def CreatePopupMenu(self):
menu = wx.Menu()
create_menu_item(menu, 'Control Panel', self.on_open)
menu.AppendSeparator()
create_menu_item(menu, 'Exit', self.on_exit)
return menu
def set_icon(self, path):
icon = wx.Icon(path)
self.SetIcon(icon, TRAY_TOOLTIP)
def on_left_down(self, event):
print ('Tray icon was left-clicked.')
def on_open(self, event):
foreground()
#self.close_popup()
def on_exit(self, event):
wx.CallAfter(self.Destroy)
self.close_popup()
def close_popup(self):
self.frame.Close()
class TaskbarApp(wx.App):
def OnInit(self):
frame=wx.Frame(None)
self.SetTopWindow(frame)
TaskBarIcon(frame)
return True
class FullApp(wx.App):
def OnInit(self):
fullframe=ServerFrame()
return True
def background():
app = TaskbarApp(False)
#with Manager() as manager:
app.MainLoop()
#displaydata = manager.list()
#settings = manager.list()
#rawdata = manager.list()
#logdata = manager.list()
#uploaddata = manager.list()
#downloaddata = manager.list()
def open_fg(outputdata, uisettings):
app = FullApp(False)
app.MainLoop()
def foreground():
# Open the foreground in a separate process so that UI acts independently of the taskbar icon
p = Process(target=open_fg, args=(displaydata, settings))
p.start()
#p.join()
print("Launched foreground")
if __name__ == '__main__': if __name__ == '__main__':
app = wx.App(False) background()
frame = ServerFrame()
app.MainLoop()

BIN
icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

160
ippigeon.py Normal file
View File

@ -0,0 +1,160 @@
import os
import sys
import subprocess
from multiprocessing import Process, Manager, Pool, TimeoutError, freeze_support, active_children
from sys import platform
from time import sleep
import uuid
import yaml
from util import find_data_file
from util import fprint
import taskbartool
import util
import netstat
import ssh
import auth
displaydata = None
settings = None
netdata_res = None
procdata_res = None
killme = None
datafile = ""
#print(datafile)
config = None
interval = 10
win32 = platform == "win32"
linux = platform == "linux" or platform == "linux2"
macos = platform == "darwin"
# Get unique system values
if win32:
sysid = hex(uuid.getnode())
datafile += sysid
datafile += "gendata.csv"
# Python is running as Administrator (so netstat can get filename, to block, etc),
# so we use this to see who is actually logged in
# it's very hacky
startupinfo = subprocess.STARTUPINFO()
#if not getattr(sys, "frozen", False):
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW # hide powershell window
res = subprocess.check_output(["WMIC", "ComputerSystem", "GET", "UserName"], universal_newlines=True, startupinfo=startupinfo)
_, username = res.strip().rsplit("\n", 1)
userid, sysdom = username.rsplit("\\", 1)
def netstat_done(res):
fprint("netstat done, processing")
procdata_res = pool.apply_async(netstat.process, (res,), callback=process_done)
#netstat.process(res)
def process_done(res):
fprint("uploading to sftp...")
#ssh.sftp_send_data(res, config, datafile)
procdata_res = pool.apply_async(ssh.sftp_send_data, (config, datafile, 'send'))
def login_done(res):
if not res:
fprint("Login failure")
settings["message"] = "Login failure"
else:
fprint("Login result in main: " + str(res))
def killall():
kids = active_children()
for kid in kids:
kid.kill()
fprint("Every child has been killed")
os.kill(os.getpid(), 9) # dirty kill of self
def mainloop(pool):
# worker pool: netstat, netstat cleanup, upload, download, ui tasks
global counter
global netdata_res
global procdata_res
global rawdata
global killme
#print(killme)
if killme.value > 0:
#print("killing")
killall()
#print(res.get(timeout=1))
if counter == 0: # runs every INTERVAL
fprint("start loop")
if netdata_res is None or netdata_res.ready():
#rawdata = netdata_res.get()
#procdata_res = pool.apply_async(process_netstat, (rawdata))
fprint("netstat starting")
netdata_res = pool.apply_async(netstat.start, callback=netstat_done)
#fprint(netdata_res.successful())
# runs every 50ms
if settings["login"] == True:
login_res = pool.apply_async(auth.login, (config, settings["username"], settings["password"], sysid), callback=login_done)
#fprint(auth.login(config, settings["username"], settings["password"], sysid))
settings["login"] = False
sleep(interval / (interval * 20.0))
counter += 1
if counter == interval * 20:
counter = 0
class Logger(object):
def __init__(self, filename="output.log"):
self.log = open(filename, "a")
self.terminal = sys.stdout
def write(self, message):
self.log.write(message)
#close(filename)
#self.log = open(filename, "a")
try:
self.terminal.write(message)
except:
sleep(0)
def flush(self):
print("")
if __name__ == '__main__':
freeze_support() # required if packaged into single EXE
# create manager to share data to me, background, foreground
# create worker pool
sys.stdout = Logger(filename=find_data_file("output.log"))
sys.stderr = Logger(filename=find_data_file("output.log"))
with Pool(processes=5) as pool:
with Manager() as manager:
with open(find_data_file('config.yml'), 'r') as file:
#global config
config = yaml.safe_load(file)
#print(config['sftp']['host'])
interval = config['core']['interval']
displaydata = manager.list(range(2)) # data to be printed
settings = manager.dict() # configuration
settings["login"] = False
settings["loggedin"] = False
killme = manager.Value('d', 0)
#killme = False
# launch background UI app as process
p = Process(target=taskbartool.background, args=(displaydata,settings,killme))
p.start()
#p.join() # not a foreground job, so let's not join it
keeprunning = True
# initial setup
#netdata_res = pool.apply_async(netstat, callback=netstat_done)
# launch loop - non-blocking!
counter = 0
while(keeprunning):
mainloop(pool)

27
keyfile-admin.pem Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAkKf5kPTTHIvL44Tfe7QO13K/JVfD+DbIwWQBURqa60ohVldN
mWg7dngpMeHcr27JXLHfAT1c2ztbZR13ZZzKTpu1IbUtecVhCsduNtMzLehB8seQ
0lPLAUeE76IK7KfYBUXNXnA5n9oFTS2DJwnYgSqAODbILOxbUpdRajTbacE3Mo0p
nMLwvqcCwXXfKEhlcccclckDKkZYpwLfmuw7veD007NlBfq/lOezdFBERezEUIgr
+A22JP5KCsVeuQBJuuRrXdz8p334n2xaR4RDjN3p0cmMi2Oohm7M7MbhAImC/J+P
HXOJMQpdEgD6Ea17Jr9ORPf08HrrjaZzA/SW7QIDAQABAoIBAEe07LKdmjTxW42a
JUpl9GF6gSRawEs/pP6wuzJgFOGD6sipGE9uauOMJyeSBdp0+Z5YkepEZ85JO0IB
fFlDgsm6x+xAqp1NaZB1Ub4draYZFu/pW3HXla85q706P14Wya+7bVVeHkKOSch7
QiNM7yUAU3UKOuqB87caSYJzVzyxhUd5S6/ro2VNbXT/7vHSsKCja2scy+JaRhKn
m4cc3P+ggI06JLfZsMZY1zJKDhbWiHGmB5ZdzqAJsu/bAtXWY25QsHowYAqPG7Uq
7rcJlbbdkCASE4MXqi427uJfeqBB0vfykttSriBpQVBKus5wpcCEOMkpEho0zU0Z
yx9bdeECgYEA9d0PDjAqIwrVSxjeOd6eXcSwmMzaK5fc5beptKRQA0U/O4swhn2+
NOio6v6fTWuDwNHAsMZiDvW3boO357GCm2N7YkqvdarydfOt7IccsUnEROaAxOqx
1wlnl0NkVIwaTo3XoRSWIcIqE3mCAaz8peqtRmIcXcQ/S9RGm3QeiAUCgYEAlp67
vmn6Z1U0XLILnf4i9D3ECJlwJXEP64pB4XnXiHU/StaXY7CSRaCX+SxfgUR8pATQ
ySYDRY1Ag6cHxSVIo1vkotT3P11x7/8yWnomvnEwRJqTMdN+/VuTi4tPzU1ScNXX
F7aRqkNoGEkmsmi2wdszbJcruI74k4TGLcbNj8kCgYEAgG37AVRTjn6IMHRLETui
yiSGgyrvBDqN30lzUrNKQIsZnsb0kCx7ATRPmIFtQYnaBw0KdM0MR/g+23HezR7C
tNzghNWyleq4QLkLrzRc3pdD+SHXPgXC5Cs7e55ueGO/Ei2x56jTS8sbI5UjPjDY
wOq3nL5/RtPOpJO8VlPv5ukCgYEAjytM/D9SdNyJzD61SjWiVhVL/HyVHBHvdw3R
d5jQZfZE9kcqWekh8KspKgGiuoY2D9Y/+6N1YqxUkY+4lA3PkPAtURYr+wBA6Ebk
PxpzL3z5y4w+tBL8V6mvguomLdj8ryKktPamWXh/Pu5xqQ5eAcDxjZvYRDMqV1bS
5fpdtPkCgYEAoRVdlDSaj9u3NPoFkschl1bOZlJpm9tJVU+LoWxRe8tuLIwVDvXP
JsZMcpfinEPWSrJN+hlGDuaq7k5LtSNeQoruaafhlE+CV54G7J2Khn8pRKWT+n/p
36PfgGbhuLsZl8KDy+PXjS+L5A1kuTxB4rOBdHXIHm60aNCqB0BRcTM=
-----END RSA PRIVATE KEY-----

1
known_hosts Normal file
View File

@ -0,0 +1 @@
ec2-34-232-29-46.compute-1.amazonaws.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM8sLlu0mu1PqYXk+a9XYHXXFiOaxk/2tIS5O3q+3ah13bd5Iz+NSxS0bXT7TdMTA/lD1kWMUXROEauADgIfT98=

80
netstat.py Normal file
View File

@ -0,0 +1,80 @@
from util import find_data_file
from util import setup_child
from util import fprint
from util import run_ps
from util import win32
import util
import time
import csv
def process(data):
setup_child()
fprint("netstat processing")
if win32:
#output = data.stdout
#print(output)
output = data.stdout.decode().split('\r\n') # split stdout into lines
#print(output)
if output[0].find("The requested operation requires elevation.") >= 0:
#print("test3")
raise PermissionError("Unable to acquire netstat data without admin!")
#print("test2")
output2 = list()
output2.append([util.sysid, util.userid, util.sysdom, util.time()]) # add metadata
#print(output2)
procname = ""
"""for x in range(4, len(output)):
tmp = output[x].split(" ")
print(tmp)
tmp = [i for i in output[x] if i]
print(tmp)
print(len(tmp))
if len(len(tmp) == 1):
procname = tmp[0]
print(x)
else:
print(x)
output2[x] = list()
output2[x].append(procname)
output2[x].append(output[x].split(" "))
output2[x] = [i for i in output2[x] if i]
output2 = [i for i in output2 if i]
print(output2)"""
x = len(output) - 1 # start at the end because filename comes after connection
procname = "Unknown" # if the very last connection happens to have no file (yes, it's possible), we can say unknown
while x > 3:
string = output[x]
#print("LINE: ", string)
string_split = string.split(" ")
string_split = [i for i in string_split if i]
if string.find("Can not obtain ownership information") >= 0: # Higher privilige than us, must be system
procname = "Windows System"
elif string.find("]") >= 0 and string.find("[") == 1: # generic [file.exe]
procname = string[2:-1]
elif len(string_split) == 5: # actual netstat line
tmp = [procname,] # add executable name first
tmp.extend(string.split(" "))
tmp = [i for i in tmp if i]
#print(tmp)
output2.append(tmp)
#else: # In case of an extra line above file, or an empty line, ignore it
#print("Garbage data", string)
x = x - 1
#output2 = output2[2:]
#print(output2)
with open(find_data_file(util.datafile), "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(output2)
fprint("done creating csv")
def start():
fprint("netstat started")
setup_child()
if win32:
data = run_ps("netstat -n -o -b")
fprint("data acquired")
return data

57089
output.log Normal file

File diff suppressed because it is too large Load Diff

57
release.sh Normal file
View File

@ -0,0 +1,57 @@
#!/bin/bash
#set -x
TOKEN=$(< token.txt)
EDITOR=nano git commit -a
git push
COMMIT=$(git log | head -n 1 | cut -d' ' -f2)
echo $COMMIT
export PATH=$PATH:"C:\Program Files\7-Zip"
TAG=$(date +%s)
"C:/Program Files/Python310/python.exe" setup.py build
sleep 2
mv ./build/exe.win-amd64-3.10/ ./build/ippigeon-win
7z a -r release-$COMMIT.zip ./build/ippigeon-win
7z a -sfx7z.sfx IPPigeon-install.exe ./build/ippigeon-win
mv ./build/ippigeon-win/ ./build/exe.win-amd64-3.10
#sleep 30
DATA='{
"body": "Autogenerated release",
"draft": false,
"name": "Development release",
"prerelease": true,
"tag_name": "'$TAG'",
"target_commitish": "'$COMMIT'"
}'
OUT=$(curl -X 'POST' \
'https://git.deck.sh/api/v1/repos/Interfaz/ff/releases?token='$TOKEN'' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d "$DATA")
ID=$(echo $OUT | cut -d',' -f 1 | cut -d':' -f 2)
OUT=$(curl -X 'POST' \
'https://git.deck.sh/api/v1/repos/Interfaz/ff/releases/'$ID'/assets?token='$TOKEN'' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'attachment=@IPPigeon-install.exe;type=application/octet-stream')
URL=$(echo $OUT | cut -d',' -f 7 | cut -d\" -f4)
OUT=$(curl -X 'POST' \
'https://git.deck.sh/api/v1/repos/Interfaz/ff/releases/'$ID'/assets?token='$TOKEN'' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'attachment=@'release-$COMMIT.zip';type=application/x-zip-compressed')
URLZIP=$(echo $OUT | cut -d',' -f 7 | cut -d\" -f4)
curl -d "Self extracting installer: $URL
Portable Zip: $URLZIP" https://notify.deck.sh/ipro-release
rm release-$COMMIT.zip
rm IPPigeon-install.exe

2
run.sh Normal file
View File

@ -0,0 +1,2 @@
"C:/Program Files/Python310/python.exe" setup.py build

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

21
setup.py Normal file
View File

@ -0,0 +1,21 @@
import sys
from cx_Freeze import setup, Executable
debug = True
#debug = not debug
# Dependencies are automatically detected, but it might need fine tuning.
# "packages": ["os"] is used as example only
build_exe_options = {"packages": ["os"], "excludes": ["tkinter"], "include_msvcr": True, "include_files": ["icon.png", "config.yml", "keyfile-admin.pem"], "optimize": 2}
# base="Win32GUI" should be used only for Windows GUI app
base = None
if sys.platform == "win32" and not debug:
base = "Win32GUI"
setup(
name="IP Pigeon",
version="0.2.4",
description="IP Pigeon client application",
options={"build_exe": build_exe_options},
executables=[Executable("ippigeon.py", base=base, icon="icon.ico", uac_admin=True, target_name="IPPigeon.exe")],
)

39
ssh.py Normal file
View File

@ -0,0 +1,39 @@
#from __future__ import with_statement
from fabric import Connection
from util import find_data_file
from util import setup_child
from util import fprint
from invoke import exceptions
import sys
def sftp_send_data(config, filename, filetype):
setup_child()
fprint("Connecting over SSH to " + config['sftp']['host'])
c = Connection(host=config['sftp']['host'], user=config['sftp']['user'], port=config['sftp']['port'], connect_kwargs={"key_filename": find_data_file(config['sftp']['keyfile']),})
fprint("Sending data over SFTP: " + filename)
fprint(c.put(find_data_file(filename), remote=config['sftp']['filepath'][filetype]))
fprint("Data sent over SFTP successfully")
#command = 'ls ' + config['sftp']['filepath'][filetype]
#fprint(c.run(command))
def check_for_file(config, filename, location):
setup_child()
fprint("Connecting over SSH to " + config['sftp']['host'])
c = Connection(host=config['sftp']['host'], user=config['sftp']['user'], port=config['sftp']['port'], connect_kwargs={"key_filename": find_data_file(config['sftp']['keyfile']),})
fprint("Checking for existence of file " + config['sftp']['filepath'][location] + "/" + filename)
try:
res = c.run("ls -l " + config['sftp']['filepath'][location] + "/" + filename, hide=True)
fprint("File " + filename + " exists!")
return c.run("cat " + config['sftp']['filepath'][location] + "/" + filename, hide=True)
except exceptions.UnexpectedExit:
return False
def run_ssh(config, command, location):
setup_child()
fprint("Connecting over SSH to " + config['sftp']['host'])
c = Connection(host=config['sftp']['host'], user=config['sftp']['user'], port=config['sftp']['port'], connect_kwargs={"key_filename": find_data_file(config['sftp']['keyfile']),})
fprint("cd to " + config['sftp']['filepath'][location])
with c.cd(config['sftp']['filepath'][location]):
fprint("Running ssh command: " + command)
res = c.run(command, hide=True, asynchronous=True)
return res

82
taskbartool.py Normal file
View File

@ -0,0 +1,82 @@
import glob
import wx
import wx.adv
import os
from time import sleep
from sys import platform
import sys
from util import find_data_file
from util import fprint
TRAY_TOOLTIP = 'IP Pigeon'
displaydata = None
settings = None
killme = False
def create_menu_item(menu, label, func):
item = wx.MenuItem(menu, -1, label)
menu.Bind(wx.EVT_MENU, func, id=item.GetId())
menu.Append(item)
return item
class TaskBarIcon(wx.adv.TaskBarIcon):
def __init__(self, frame):
self.frame = frame
super(TaskBarIcon, self).__init__()
self.set_icon(TRAY_ICON)
self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)
def CreatePopupMenu(self):
menu = wx.Menu()
create_menu_item(menu, 'Control Panel', self.on_open)
create_menu_item(menu, 'Login test', self.on_login)
menu.AppendSeparator()
create_menu_item(menu, 'Exit', self.on_exit)
return menu
def set_icon(self, path):
icon = wx.Icon(path)
self.SetIcon(icon, TRAY_TOOLTIP)
def on_left_down(self, event):
fprint ('Tray icon was left-clicked.')
def on_open(self, event):
foreground()
#self.close_popup()
def on_login(self, event):
settings["username"] = "Cole"
settings["password"] = "12345"
settings["login"] = True
def on_exit(self, event):
wx.CallAfter(self.Destroy)
self.close_popup()
#print("kill cmd")
global killme
killme.value += 1
def close_popup(self):
self.frame.Close()
class TaskbarApp(wx.App):
def OnInit(self):
frame=wx.Frame(None)
self.SetTopWindow(frame)
TaskBarIcon(frame)
return True
def background(data, sets, kill):
global killme
global settings
global displaydata
killme = kill
app = TaskbarApp(False)
displaydata = data
settings = sets
app.MainLoop()
TRAY_ICON = find_data_file('icon.png')

98
util.py Normal file
View File

@ -0,0 +1,98 @@
import inspect
import sys
import subprocess
import os
from sys import platform
import time as t
import uuid
win32 = platform == "win32"
linux = platform == "linux" or platform == "linux2"
macos = platform == "darwin"
datafile = ""
if win32:
sysid = hex(uuid.getnode())
datafile += sysid
datafile += "gendata.csv"
# Python is running as Administrator (so netstat can get filename, to block, etc),
# so we use this to see who is actually logged in
# it's very hacky
startupinfo = subprocess.STARTUPINFO()
#if not getattr(sys, "frozen", False):
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW # hide powershell window
res = subprocess.check_output(["WMIC", "ComputerSystem", "GET", "UserName"], universal_newlines=True, startupinfo=startupinfo)
_, username = res.strip().rsplit("\n", 1)
userid, sysdom = username.rsplit("\\", 1)
def time():
return int(t.time())
def fprint(msg):
#if not getattr(sys, "frozen", False):
setup_child()
try:
frm = inspect.stack()[1]
mod = inspect.getmodule(frm[0])
print('[' + mod.__name__ + ":" + frm.function + ']:', msg)
except Exception as e:
try:
print('[????:' + frm.function + ']:', msg)
except:
print('[????]:', msg)
# else:
#print(msg)
def find_data_file(filename):
if getattr(sys, "frozen", False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
def run_ps(cmd):
fprint("init PS")
if win32:
startupinfo = subprocess.STARTUPINFO()
#print("DICKS")
#if not getattr(sys, "frozen", False):
# print("test")
#
#completed = subprocess.run(["powershell", "-Command", cmd], capture_output=True, startupinfo=startupinfo)
#else:
# print("alt")
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW # , "-WindowStyle", "hidden"
fprint("running PS command: " + cmd)
completed = subprocess.run(["powershell", "-Command", cmd], capture_output=True, startupinfo=startupinfo)
fprint("ran PS command successfully")
#completed = subprocess.run(["powershell", "-WindowStyle", "hidden", "-Command", cmd], capture_output=True, startupinfo=startupinfo)
return completed
def setup_child():
if not getattr(sys, "frozen", False):
sys.stdout = Logger(filename=find_data_file("output.log"))
sys.stderr = Logger(filename=find_data_file("output.log"))
class Logger(object):
def __init__(self, filename="output.log"):
self.log = open(filename, "a")
self.terminal = sys.stdout
def write(self, message):
self.log.write(message)
#close(filename)
#self.log = open(filename, "a")
try:
self.terminal.write(message)
except:
sleep(0)
def flush(self):
print("")