This commit is contained in:
pika 2025-03-30 23:42:24 +02:00
parent 3b2f1db4ce
commit 5c16964b76
47 changed files with 2080 additions and 1053 deletions

View file

@ -3,51 +3,52 @@ from app.core.models import Subnet, Server, App, Port
from app.core.auth import User # Import User from auth module
import json
def seed_database():
"""Add sample data to the database"""
# Create a default subnet if none exists
if Subnet.query.count() == 0:
subnet = Subnet(
cidr='192.168.1.0/24',
location='Office',
cidr="192.168.1.0/24",
location="Office",
auto_scan=True,
active_hosts=json.dumps([])
active_hosts=json.dumps([]),
)
db.session.add(subnet)
# Create a sample server
server = Server(
hostname='server1',
ip_address='192.168.1.10',
hostname="server1",
ip_address="192.168.1.10",
subnet=subnet,
documentation='# Server 1\n\nThis is a sample server.'
documentation="# Server 1\n\nThis is a sample server.",
)
db.session.add(server)
# Create a sample app
app = App(
name='Web App',
server=server,
documentation='# Welcome to Web App\n\nThis is a sample application.'
name="Web App",
server=server,
documentation="# Welcome to Web App\n\nThis is a sample application.",
)
db.session.add(app)
# Add some ports
ports = [
Port(app=app, port_number=80, protocol='TCP', description='HTTP'),
Port(app=app, port_number=443, protocol='TCP', description='HTTPS')
Port(app=app, port_number=80, protocol="TCP", description="HTTP"),
Port(app=app, port_number=443, protocol="TCP", description="HTTPS"),
]
db.session.add_all(ports)
# Create a default user if none exists
if User.query.count() == 0:
admin = User(username='admin', email='admin@example.com', is_admin=True)
admin.set_password('admin')
admin = User(username="admin", email="admin@example.com", is_admin=True)
admin.set_password("admin")
db.session.add(admin)
try:
db.session.commit()
print("Database seeded successfully")
except Exception as e:
db.session.rollback()
print(f"Error seeding database: {e}")
print(f"Error seeding database: {e}")

View file

@ -11,10 +11,11 @@ import concurrent.futures
from datetime import datetime
import platform
def scan(subnet, manual_trigger=False):
"""
Scan a subnet for active hosts
Args:
subnet: The subnet object to scan
manual_trigger: If False, only scan if the subnet hasn't been scanned recently
@ -22,50 +23,56 @@ def scan(subnet, manual_trigger=False):
# Skip if not auto scan and not manually triggered
if not subnet.auto_scan and not manual_trigger:
return False
active_hosts = []
try:
# Parse the CIDR notation
network = ipaddress.ip_network(subnet.cidr, strict=False)
# For each address in this network, ping it
for ip in network.hosts():
if ping(str(ip)):
active_hosts.append(str(ip))
# Update subnet with scan results
subnet.active_hosts = json.dumps(active_hosts)
subnet.last_scanned = datetime.utcnow()
return True
except Exception as e:
print(f"Error scanning subnet {subnet.cidr}: {str(e)}")
return False
def scan_worker(ip_list, results, index):
"""Worker function for threading"""
for ip in ip_list:
if ping(ip):
hostname = get_hostname(ip)
results[index].append({
'ip': str(ip),
'hostname': hostname if hostname else str(ip),
'status': 'up'
})
results[index].append(
{
"ip": str(ip),
"hostname": hostname if hostname else str(ip),
"status": "up",
}
)
def ping(host):
"""
Returns True if host responds to a ping request
"""
# Ping parameters based on OS
param = '-n' if platform.system().lower() == 'windows' else '-c'
param = "-n" if platform.system().lower() == "windows" else "-c"
# Build the command
command = ['ping', param, '1', '-w', '1', host]
command = ["ping", param, "1", "-w", "1", host]
try:
# Run the command and capture output
output = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=2)
output = subprocess.run(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=2
)
# Return True if ping was successful
return output.returncode == 0
except subprocess.TimeoutExpired:
@ -73,6 +80,7 @@ def ping(host):
except Exception:
return False
def get_hostname(ip):
"""Try to get the hostname for an IP address"""
try:
@ -81,43 +89,53 @@ def get_hostname(ip):
except (socket.herror, socket.gaierror):
return None
def is_host_active_ping(ip):
"""Simple ICMP ping test (platform dependent)"""
import platform
import subprocess
param = '-n' if platform.system().lower() == 'windows' else '-c'
command = ['ping', param, '1', '-w', '1', ip]
param = "-n" if platform.system().lower() == "windows" else "-c"
command = ["ping", param, "1", "-w", "1", ip]
try:
return subprocess.call(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0
return (
subprocess.call(
command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
)
== 0
)
except:
return False
def save_scan_results(cidr, results):
"""Save scan results to the database"""
from flask import current_app
# Need to be in application context
if not hasattr(current_app, 'app_context'):
if not hasattr(current_app, "app_context"):
print("Not in Flask application context, cannot save results")
return
try:
# Find subnet by CIDR
subnet = Subnet.query.filter_by(cidr=cidr).first()
if not subnet:
print(f"Subnet {cidr} not found in database")
return
# Get existing servers in this subnet
existing_servers = {server.ip_address: server for server in Server.query.filter_by(subnet_id=subnet.id).all()}
existing_servers = {
server.ip_address: server
for server in Server.query.filter_by(subnet_id=subnet.id).all()
}
# Process scan results
for host in results:
ip = host['ip']
hostname = host['hostname']
ip = host["ip"]
hostname = host["hostname"]
# Check if server already exists
if ip in existing_servers:
# Update hostname if it was previously unknown
@ -130,37 +148,34 @@ def save_scan_results(cidr, results):
hostname=hostname,
ip_address=ip,
subnet_id=subnet.id,
documentation=f"# {hostname}\n\nAutomatically discovered by network scan on {time.strftime('%Y-%m-%d %H:%M:%S')}"
documentation=f"# {hostname}\n\nAutomatically discovered by network scan on {time.strftime('%Y-%m-%d %H:%M:%S')}",
)
db.session.add(server)
db.session.commit()
print(f"Saved scan results for {cidr}")
except Exception as e:
db.session.rollback()
print(f"Error saving scan results: {e}")
def schedule_subnet_scans():
"""Schedule automatic scans for subnets marked as auto_scan"""
from flask import current_app
with current_app.app_context():
try:
# Find all subnets with auto_scan enabled
subnets = Subnet.query.filter_by(auto_scan=True).all()
for subnet in subnets:
# Start a thread for each subnet
thread = threading.Thread(
target=scan,
args=(subnet,),
daemon=True
)
thread = threading.Thread(target=scan, args=(subnet,), daemon=True)
thread.start()
# Sleep briefly to avoid overloading
time.sleep(1)
except Exception as e:
print(f"Error scheduling subnet scans: {e}")
print(f"Error scheduling subnet scans: {e}")