Files
IoT_PreTester_Demo/V4.5/django_project/IoTAnalyzer/db_create.py
T
2026-06-24 14:53:14 +02:00

1052 lines
34 KiB
Python

import logging
from datetime import datetime
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.db import IntegrityError, DatabaseError, transaction
from django.http import JsonResponse
from .analyze.analyze_pcap import analyze_pcap_file
from .models import *
from .exception_handling import handle_exceptions
from .db_validate import *
from rest_framework import serializers, status
from rest_framework.views import APIView
from rest_framework.response import Response
#Logger configuration
logger = logging.getLogger(__name__)
### CREATE - functions ###
# Create manufacturer
@handle_exceptions
@transaction.atomic
def create_manufacturer(name: str):
# Input validation
if not name or not isinstance(name, str): # Checks for None, empty strings and non-strings
raise ValidationError("Ungültiger Herstellername")
# Manufacturer must not consist only of whitespace
name = name.strip()
if not name: # Checks again after stripping whitespace
raise ValidationError("Herstellername darf nicht leer sein")
# Check for duplicate
if Manufacturer.objects.filter(name=name).exists():
raise ValidationError(f"Hersteller '{name}' existiert bereits")
# Create manufacturer
manufacturer = Manufacturer.objects.create(
name=name,
created=datetime.now()
)
# Return manufacturer object as JSON
logging.info(f"Hersteller erfolgreich erstellt: {name} (ID: {manufacturer.id})")
return JsonResponse({
'status': 'success',
'message': 'Hersteller wurde erfolgreich erstellt',
'data': manufacturer.to_json()
}, status=201)
# Create device type
@handle_exceptions
@transaction.atomic
def create_device_type(device_type: str):
# Input validation
if not device_type or not isinstance(device_type, str):
raise ValidationError("Ungültiger Gerätetyp")
# Manufacturer must not consist only of whitespace
device_type = device_type.strip()
if not device_type: # Checks again after stripping whitespace
raise ValidationError("Gerätetyp darf nicht leer sein")
# Check for duplicate
if DeviceType.objects.filter(device_type=device_type).exists():
raise ValidationError(f"Gerätetyp '{device_type}' existiert bereits")
# Create type
device_type_obj = DeviceType.objects.create(
device_type=device_type
)
logging.info(f"Gerätetyp erfolgreich erstellt: {device_type} (ID: {device_type_obj.id})")
return JsonResponse({
'status': 'success',
'message': 'Gerätetyp wurde erfolgreich erstellt',
'data': device_type_obj.to_json()
}, status=201)
# Create product
@handle_exceptions
@transaction.atomic
def create_product(manufacturer_id: int, device_type_id: int, product_name: str):
# Input validation
if not product_name or not isinstance(product_name, str):
raise ValidationError("Ungültiger Produktname")
# Product name must not be empty
product_name = product_name.strip()
if not product_name:
raise ValidationError("Produktname darf nicht leer sein")
# Check manufacturer and device type
manufacturer = Manufacturer.objects.get(id=manufacturer_id)
device_type = DeviceType.objects.get(id=device_type_id)
# Check for duplicate
if Product.objects.filter(
manufacturer=manufacturer,
device_type=device_type,
product_name=product_name
).exists():
raise ValidationError(f"Produkt '{product_name}' existiert bereits für diesen Hersteller und Gerätetyp")
# Create product
product = Product.objects.create(
manufacturer=manufacturer,
device_type=device_type,
product_name=product_name,
created=datetime.now()
)
logging.info(
f"Produkt erfolgreich erstellt: {product_name} (ID: {product.id}, Hersteller: {manufacturer.name}, Typ: {device_type.device_type})")
return JsonResponse({
'status': 'success',
'message': 'Produkt wurde erfolgreich erstellt',
'data': product.to_json()
}, status=201)
# Create firmware
@handle_exceptions
@transaction.atomic
def create_firmware(product_id: int, version: str):
# Input validation
if not version or not isinstance(version, str):
raise ValidationError("Ungültige Firmware-Version")
# Version must not be empty
version = version.strip()
if not version:
raise ValidationError("Firmware-Version darf nicht leer sein")
# Check product
product = Product.objects.get(id=product_id)
# Check for duplicate
if Firmware.objects.filter(
product=product,
version=version
).exists():
raise ValidationError(f"Firmware-Version '{version}' existiert bereits für dieses Produkt")
# Create firmware
firmware = Firmware.objects.create(
product=product,
version=version,
created=datetime.now()
)
logging.info(
f"Firmware erfolgreich erstellt: Version {version} (ID: {firmware.id}, Produkt: {product.product_name})")
return JsonResponse({
'status': 'success',
'message': 'Firmware wurde erfolgreich erstellt',
'data': firmware.to_json()
}, status=201)
#Create device
@handle_exceptions
@transaction.atomic
def create_new_device(manufacturer_id:int, device_type_id: int, device_name: str, serial: str, comment: str = None):
# Input validation
if not manufacturer_id or not isinstance(manufacturer_id, int):
raise ValidationError("Ungültige Manufacturer ID")
# Input validation
if not device_type_id or not isinstance(device_type_id, int):
raise ValidationError("Ungültige Device ID")
# Input validation
if not serial or not isinstance(serial, str):
raise ValidationError("Ungültige Seriennummer")
# Serial number must not be empty
serial = serial.strip()
if not serial:
raise ValidationError("Seriennummer darf nicht leer sein")
# Validate device name
if not device_name or not isinstance(device_name, str):
raise ValidationError("Ungültiger Gerätename")
device_name = device_name.strip()
if not device_name:
raise ValidationError("Gerätename darf nicht leer sein")
manufacturer = Manufacturer.objects.get(id=manufacturer_id)
device_type = DeviceType.objects.get(id=device_type_id)
# Find or create product
try:
product = Product.objects.get(
product_name=device_name,
manufacturer=manufacturer,
device_type=device_type
)
logging.info(f"Existierendes Produkt gefunden: {product.product_name}")
except Product.DoesNotExist:
product = Product.objects.create(
product_name=device_name,
manufacturer=manufacturer,
device_type=device_type
)
logging.info(f"Neues Produkt erstellt: {product.product_name}")
# Check for duplicate
if Device.objects.filter(
product=product,
serial=serial
).exists():
raise ValidationError(f"Gerät mit Seriennummer '{serial}' existiert bereits für dieses Produkt")
# Create device
device = Device.objects.create(
product=product,
serial=serial,
comment=comment if comment else '',
created=datetime.now()
)
logging.info(
f"Gerät erfolgreich erstellt: Seriennummer {serial} (ID: {device.id}, Produkt: {product.product_name})")
return JsonResponse({
'status': 'success',
'message': 'Gerät wurde erfolgreich erstellt',
'data': {
'device': device.to_json(),
'product_id': product.id
}
}, status=201)
# Create file
@handle_exceptions
@transaction.atomic
def create_file(device_id: int, firmware_id: int, filename: str, ip_address: str, status: str, upload_time: datetime = None):
# Input validation
if not filename or not isinstance(filename, str):
raise ValidationError("Ungültiger Dateiname")
# Filename must not be empty
filename = filename.strip()
if not filename:
raise ValidationError("Dateiname darf nicht leer sein")
if not ip_address or not isinstance(ip_address, str):
raise ValidationError("Ungültige IP-Adresse")
# IP address must not be empty
ip_address = ip_address.strip()
if not ip_address:
raise ValidationError("IP-Adresse darf nicht leer sein")
if not status or not isinstance(status, str):
raise ValidationError("Ungültiger Status")
if not re.match(r'^(\d{1,3}\.){3}\d{1,3}$', ip_address):
raise ValidationError("Ungültige IP-Adresse")
# Check device
device = Device.objects.get(id=device_id) # Raises ObjectDoesNotExist
# Check firmware
firmware = Firmware.objects.get(id=firmware_id) # Raises ObjectDoesNotExist
# Check for duplicate
if File.objects.filter(
device=device,
firmware=firmware,
filename=filename,
ip_address=ip_address
).exists():
raise ValidationError(f"Datei '{filename}' existiert bereits für dieses Gerät und diese Firmware")
# Create file
file = File.objects.create(
device=device,
firmware=firmware,
filename=filename,
ip_address=ip_address,
status=status,
upload_time=upload_time if upload_time else datetime.now()
)
logging.info(
f"Datei erfolgreich erstellt: {filename} (ID: {file.id}, Gerät: {device.serial}, Firmware: {firmware.version})")
#Link firmware with device
create_firmware_to_device(device_id, firmware_id)
return JsonResponse({
'status': 'success',
'message': 'Datei wurde erfolgreich erstellt',
'data': file.to_json()
}, status=201)
# Create file
@handle_exceptions
@transaction.atomic
def create_firmware_to_device(device_id: int, firmware_id: int):
# Check device
device = Device.objects.get(id=device_id) # Raises ObjectDoesNotExist
# Check device
firmware = Firmware.objects.get(id=firmware_id) # Raises ObjectDoesNotExist
# Check for duplicate
if FirmwareDevices.objects.filter(
device=device_id,
firmware=firmware_id,
).exists():
raise ValidationError(f"Firmware '{firmware}' existiert bereits!")
# Create file
firmware_device=FirmwareDevices.objects.create(
device=device,
firmware=firmware,
created=datetime.now())
logging.info(
f"Firmware erfolgreich mit device verknüpft: {firmware} (Gerät: {device})")
return JsonResponse({
'status': 'success',
'message': 'Firmware wurde erfolgreich verknüpft',
'data': firmware_device.to_json()
}, status=201)
# REPLACE the existing create_file_with_firmware_version function in db_create.py
# with this extended version:
@handle_exceptions
@transaction.atomic
def create_file_with_firmware_version(device_id: int, firmware_version: str, filename: str, ip_address: str,
status: str):
# Input validation (stays the same)
if not firmware_version or not isinstance(firmware_version, str):
raise ValidationError("Ungültige Firmware-Version")
firmware_version = firmware_version.strip()
if not firmware_version:
raise ValidationError("Firmware-Version darf nicht leer sein")
if not filename or not isinstance(filename, str):
raise ValidationError("Ungültiger Dateiname")
filename = filename.strip()
if not filename:
raise ValidationError("Dateiname darf nicht leer sein")
if not ip_address or not isinstance(ip_address, str):
raise ValidationError("Ungültige IP-Adresse")
ip_address = ip_address.strip()
if not ip_address:
raise ValidationError("IP-Adresse darf nicht leer sein")
if not status or not isinstance(status, str):
raise ValidationError("Ungültiger Status")
if not re.match(r'^(\d{1,3}\.){3}\d{1,3}$', ip_address):
raise ValidationError("Ungültige IP-Adresse")
# Get device
device = Device.objects.get(id=device_id)
# Get or create firmware
try:
firmware = Firmware.objects.get(version=firmware_version, product=device.product)
except Firmware.DoesNotExist:
firmware = Firmware.objects.create(
version=firmware_version,
product=device.product
)
# Check for duplicates
if File.objects.filter(
device=device,
firmware=firmware,
filename=filename,
ip_address=ip_address
).exists():
raise ValidationError(f"Datei '{filename}' existiert bereits für dieses Gerät und diese Firmware")
# Create file
file = File.objects.create(
device=device,
firmware=firmware,
filename=filename,
ip_address=ip_address,
status=status,
upload_time=datetime.now()
)
logging.info(
f"Datei erfolgreich erstellt: {filename} (ID: {file.id}, Gerät: {device.serial}, Firmware: {firmware.version})")
# Link firmware with device
create_firmware_to_device(device.id, firmware.id)
# Create raw dataset
response = create_raw_dataset(file.id)
if not isinstance(response, JsonResponse):
raise ValueError("Expected JsonResponse from create_raw_dataset")
# Decode and parse the JsonResponse content
raw_dataset_data = json.loads(response.content.decode('utf-8'))
if raw_dataset_data['status'] != 'success':
raise ValueError(f"Failed to create raw dataset: {raw_dataset_data.get('message', 'Unknown error')}")
raw_dataset_id = raw_dataset_data['data']['id']
# *** NEW LOGIC: Distinguish between PCAP and firmware ***
file_extension = filename.lower().split('.')[-1]
if file_extension in ['pcap', 'pcapng', 'cap']:
# PCAP analysis as before
analyze_pcap_file(filename, raw_dataset_id)
elif file_extension == 'bin':
# Firmware analysis for .bin files
from .analyze.analyze_firmware import analyze_firmware_file
analyze_firmware_file(filename, raw_dataset_id)
else:
logging.warning(f"Unbekannter Dateityp: {file_extension}. Keine automatische Analyse.")
return JsonResponse({
'status': 'success',
'message': 'Datei wurde erfolgreich erstellt',
'data': file.to_json()
}, status=201)
# Create tool
@handle_exceptions
@transaction.atomic
def create_tool(tool_name: str, version: str):
# Input validation
if not tool_name or not isinstance(tool_name, str):
raise ValidationError("Ungültiger Tool-Name")
tool_name = tool_name.strip()
if not tool_name:
raise ValidationError("Tool-Name darf nicht leer sein")
if not version or not isinstance(version, str):
raise ValidationError("Ungültige Version")
version = version.strip()
if not version:
raise ValidationError("Version darf nicht leer sein")
# Check for duplicate
if Tool.objects.filter(
tool_name=tool_name,
version=version
).exists():
raise ValidationError(f"Tool '{tool_name}' mit Version '{version}' existiert bereits")
# Create tool
tool = Tool.objects.create(
tool_name=tool_name,
version=version,
created=datetime.now()
)
logging.info(
f"Tool erfolgreich erstellt: {tool_name} Version {version} (ID: {tool.id})")
return JsonResponse({
'status': 'success',
'message': 'Tool wurde erfolgreich erstellt',
'data': tool.to_json()
}, status=201)
# Create raw dataset
@handle_exceptions
@transaction.atomic
def create_raw_dataset(file_id: int):
# Check file
file = File.objects.get(id=file_id)
# Not necessary, since File.objects.get() already raises an ObjectDoesNotExist exception
"""if not file.exists():
raise ValidationError(f"File mit Id '{file_id}' existiert nicht")"""
# Create raw dataset
raw_dataset = RawDataset.objects.create(
file=file,
created=datetime.now()
)
logging.info(f"Raw Dataset erfolgreich erstellt für File: {file.filename} (ID: {raw_dataset.id})")
return JsonResponse({
'status': 'success',
'message': 'Raw Dataset wurde erfolgreich erstellt',
'data': raw_dataset.to_json()
}, status=201)
# Create raw_url entry
@handle_exceptions
@transaction.atomic
def create_raw_url(raw_dataset_id: int, url: str):
# Input validation
if not url or not isinstance(url, str):
raise ValidationError("Ungültige URL")
url = url.strip()
if not url:
raise ValidationError("URL darf nicht leer sein")
# Use raw dataset ID directly
raw_url = UrlRaw.objects.create(
raw_dataset_id=raw_dataset_id,
url=url,
created=datetime.now()
)
logging.info(f"Raw URL erfolgreich erstellt: {url} (ID: {raw_url.id})")
return JsonResponse({
'status': 'success',
'message': 'Raw URL wurde erfolgreich erstellt',
'data': raw_url.to_json()
}, status=201)
# Create raw_dns entry
@handle_exceptions
@transaction.atomic
def create_raw_dns(raw_dataset_id: int, dns_hostname: str):
# Input validation
if not dns_hostname or not isinstance(dns_hostname, str):
raise ValidationError("Ungültiger DNS Hostname")
dns_hostname = dns_hostname.strip()
if not dns_hostname:
raise ValidationError("DNS Hostname darf nicht leer sein")
# Check for duplicate by ID
if DnsRaw.objects.filter(
raw_dataset_id=raw_dataset_id,
dns_hostname=dns_hostname
).exists():
raise ValidationError(f"DNS Hostname '{dns_hostname}' existiert bereits")
# Create raw DNS with ID
raw_dns = DnsRaw.objects.create(
raw_dataset_id=raw_dataset_id,
dns_hostname=dns_hostname,
created=datetime.now()
)
logging.info(f"Raw DNS erfolgreich erstellt: {dns_hostname} (ID: {raw_dns.id})")
return JsonResponse({
'status': 'success',
'message': 'Raw DNS wurde erfolgreich erstellt',
'data': raw_dns.to_json()
}, status=201)
# Create raw_hash entry
@handle_exceptions
@transaction.atomic
def create_raw_hash(raw_dataset_id: int, hash_value: str):
# Input validation
if not hash_value or not isinstance(hash_value, str):
raise ValidationError("Ungültiger Hash-Wert")
hash_value = hash_value.strip()
if not hash_value:
raise ValidationError("Hash-Wert darf nicht leer sein")
# Use raw dataset ID directly
raw_hash = HashRaw.objects.create(
raw_dataset_id=raw_dataset_id,
hash_value=hash_value,
created=datetime.now()
)
logging.info(f"Raw Hash erfolgreich erstellt: {hash_value} (ID: {raw_hash.id})")
return JsonResponse({
'status': 'success',
'message': 'Raw Hash wurde erfolgreich erstellt',
'data': raw_hash.to_json()
}, status=201)
# Create analyzed dataset
@handle_exceptions
@transaction.atomic
def create_analyzed_dataset(file_id: int):
# Check file
file = File.objects.get(id=file_id)
# Create analyzed dataset
analyzed_dataset = AnalyzedDataset.objects.create(
file=file,
created=datetime.now()
)
logging.info(f"Analyzed Dataset erfolgreich erstellt für File: {file.filename}")
return JsonResponse({
'status': 'success',
'message': 'Analyzed Dataset wurde erfolgreich erstellt',
'data': analyzed_dataset.to_json()
}, status=201)
# Analyzed Data - Create port
@handle_exceptions
@transaction.atomic
def create_port(port_number: int):
# Input validation
if not isinstance(port_number, int):
raise ValidationError("Port muss eine Ganzzahl sein")
# Create port or return existing one
port, created = Port.objects.get_or_create(
port=port_number, # Note: field name is 'port', not 'port_number'
defaults={'created': datetime.now()}
)
logging.info(f"Port {'erstellt' if created else 'gefunden'}: {port_number}")
return JsonResponse({
'status': 'success',
'message': f"Port wurde {'erstellt' if created else 'gefunden'}",
'data': port.to_json()
}, status=201 if created else 200)
# Analyzed Data - Create TLS version
@handle_exceptions
@transaction.atomic
def create_tls_version(version: str):
# Input validation
if not version or not isinstance(version, str):
raise ValidationError("Ungültige TLS-Version")
version = version.strip()
if not version:
raise ValidationError("TLS-Version darf nicht leer sein")
# Create TLS version or return existing one
tls_version, created = TlsVersion.objects.get_or_create(
tls_version=version, # Note: field name is 'tls_version'
defaults={'created': datetime.now()}
)
logging.info(f"TLS-Version {'erstellt' if created else 'gefunden'}: {version}")
return JsonResponse({
'status': 'success',
'message': f"TLS-Version wurde {'erstellt' if created else 'gefunden'}",
'data': tls_version.to_json()
}, status=201 if created else 200)
# Analyzed Data - Create cipher suite
@handle_exceptions
@transaction.atomic
def create_cipher_suite(name: str):
# Input validation
if not name or not isinstance(name, str):
raise ValidationError("Ungültige Cipher Suite")
name = name.strip()
if not name:
raise ValidationError("Cipher Suite darf nicht leer sein")
# Create cipher suite or return existing one
cipher_suite, created = CipherSuite.objects.get_or_create(
cipher_suite=name, # Note: field name is 'cipher_suite'
defaults={'created': datetime.now()}
)
logging.info(f"Cipher Suite {'erstellt' if created else 'gefunden'}: {name}")
return JsonResponse({
'status': 'success',
'message': f"Cipher Suite wurde {'erstellt' if created else 'gefunden'}",
'data': cipher_suite.to_json()
}, status=201 if created else 200)
# Analyzed Data - Add data (ports, TLS version and cipher suites) to analyzed_URL
@handle_exceptions
@transaction.atomic
def add_features_to_url(url_id: int, ports: list = None, tls_versions: list = None, cipher_suites: list = None):
url = UrlAnalyzed.objects.get(id=url_id)
if ports:
for port_number in ports:
port, _ = Port.objects.get_or_create(
port=port_number,
defaults={'created': datetime.now()}
)
url.ports.add(port)
if tls_versions:
for version in tls_versions:
tls, _ = TlsVersion.objects.get_or_create(
tls_version=version,
defaults={'created': datetime.now()}
)
url.tls_versions.add(tls)
if cipher_suites:
for suite in cipher_suites:
cipher, _ = CipherSuite.objects.get_or_create(
cipher_suite=suite,
defaults={'created': datetime.now()}
)
url.cipher_suites.add(cipher)
return JsonResponse({
'status': 'success',
'message': 'Features wurden zur URL hinzugefügt',
'data': url.to_json()
}, status=201)
# Create analyzed_url entry
@handle_exceptions
@transaction.atomic
def create_analyzed_url(analyzed_dataset_id: int, tool_id: int, url: str,
ports: list = None, tls_versions: list = None, cipher_suites: list = None):
# Input validation
if not url or not isinstance(url, str):
raise ValidationError("Ungültige URL")
url = url.strip()
if not url:
raise ValidationError("URL darf nicht leer sein")
# Check for duplicate
if UrlAnalyzed.objects.filter(
analyzed_dataset_id=analyzed_dataset_id,
url=url
).exists():
raise ValidationError(f"URL '{url}' existiert bereits für dieses Analyzed Dataset")
# Create URL
analyzed_url = UrlAnalyzed.objects.create(
analyzed_dataset_id=analyzed_dataset_id,
tool_id=tool_id,
url=url,
created=datetime.now()
)
# Add features
if any([ports, tls_versions, cipher_suites]):
add_features_to_url(analyzed_url.id, ports, tls_versions, cipher_suites)
logging.info(f"Analyzed URL erfolgreich erstellt: {url} (ID: {analyzed_url.id})")
# Return updated URL
analyzed_url.refresh_from_db()
return JsonResponse({
'status': 'success',
'message': 'Analyzed URL wurde erfolgreich erstellt',
'data': analyzed_url.to_json()
}, status=201)
# Create analyzed_dns entry
@handle_exceptions
@transaction.atomic
def create_analyzed_dns(analyzed_dataset_id: int, tool_id: int, dns_hostname: str, record_type: str):
# Input validation
if not dns_hostname or not isinstance(dns_hostname, str):
raise ValidationError("Ungültiger DNS Hostname")
dns_hostname = dns_hostname.strip()
if not dns_hostname:
raise ValidationError("DNS Hostname darf nicht leer sein")
if not record_type or not isinstance(record_type, str):
raise ValidationError("Ungültiger Record Type")
record_type = record_type.strip()
if not record_type:
raise ValidationError("Record Type darf nicht leer sein")
# Check for duplicate by IDs
if DnsAnalyzed.objects.filter(
analyzed_dataset_id=analyzed_dataset_id,
dns_hostname=dns_hostname,
record_type=record_type
).exists():
raise ValidationError(
f"DNS '{dns_hostname}' mit Record Type '{record_type}' existiert bereits für dieses Analyzed Dataset")
# Create analyzed DNS with IDs
analyzed_dns = DnsAnalyzed.objects.create(
analyzed_dataset_id=analyzed_dataset_id,
tool_id=tool_id,
dns_hostname=dns_hostname,
record_type=record_type,
created=datetime.now()
)
logging.info(
f"Analyzed DNS erfolgreich erstellt: {dns_hostname} (ID: {analyzed_dns.id}, Analyzed Dataset ID: {analyzed_dataset_id})")
return JsonResponse({
'status': 'success',
'message': 'Analyzed DNS wurde erfolgreich erstellt',
'data': analyzed_dns.to_json()
}, status=201)
# Create analyzed_hash entry
@handle_exceptions
@transaction.atomic
def create_analyzed_hash(analyzed_dataset_id: int, tool_id: int, hash_type: str, hash_value: str, cracked: bool = False,
cracked_value: str = None, crack_time: str = None):
# Input validation
if not hash_type or not isinstance(hash_type, str):
raise ValidationError("Ungültiger Hash-Typ")
hash_type = hash_type.strip()
if not hash_type:
raise ValidationError("Hash-Typ darf nicht leer sein")
if not hash_value or not isinstance(hash_value, str):
raise ValidationError("Ungültiger Hash-Wert")
hash_value = hash_value.strip()
if not hash_value:
raise ValidationError("Hash-Wert darf nicht leer sein")
if cracked and not cracked_value:
raise ValidationError("Bei gecracktem Hash muss ein Wert angegeben werden")
# Check for duplicate or fetch existing object for update
existing_hash = HashAnalyzed.objects.filter(
analyzed_dataset_id=analyzed_dataset_id,
hash_value=hash_value
).first()
if existing_hash:
# Update existing hash
if cracked:
existing_hash.cracked = True
existing_hash.cracked_value = cracked_value
existing_hash.crack_time = crack_time
existing_hash.save()
logging.info(f"Analyzed Hash aktualisiert: {hash_value} (ID: {existing_hash.id})")
return JsonResponse({
'status': 'success',
'message': 'Analyzed Hash wurde erfolgreich aktualisiert',
'data': existing_hash.to_json()
}, status=200)
# Create HashType or find existing one
hash_type_obj, created = HashType.objects.get_or_create(
hash_type=hash_type,
defaults={'created': datetime.now()}
)
# Create analyzed hash
analyzed_hash = HashAnalyzed.objects.create(
analyzed_dataset_id=analyzed_dataset_id,
tool_id=tool_id,
hash_value=hash_value,
cracked=cracked,
cracked_value=cracked_value if cracked else None,
crack_time=crack_time,
created=datetime.now()
)
# Add HashType to the many-to-many relationship
analyzed_hash.hash_type.add(hash_type_obj)
logging.info(
f"Analyzed Hash erfolgreich erstellt: {hash_value} (ID: {analyzed_hash.id}, "
f"Hash-Typ: {hash_type} ({hash_type_obj.id}), "
f"Analyzed Dataset ID: {analyzed_dataset_id})")
return JsonResponse({
'status': 'success',
'message': 'Analyzed Hash wurde erfolgreich erstellt',
'data': analyzed_hash.to_json()
}, status=201)
### Firmware analysis CREATE functions ###
# Create BinwalkRaw entry
@handle_exceptions
@transaction.atomic
def create_binwalk_raw(raw_dataset_id: int, offset: str, description: str, file_path: str = None):
"""
Creates a Binwalk raw data entry.
"""
# Input validation
if not offset or not isinstance(offset, str):
raise ValidationError("Ungültiger Offset")
if not description or not isinstance(description, str):
raise ValidationError("Ungültige Beschreibung")
offset = offset.strip()
description = description.strip()
if not offset or not description:
raise ValidationError("Offset und Beschreibung dürfen nicht leer sein")
# Create Binwalk Raw
binwalk_raw = BinwalkRaw.objects.create(
raw_dataset_id=raw_dataset_id,
offset=offset,
description=description,
file_path=file_path,
created=datetime.now()
)
logging.info(f"Binwalk Raw erfolgreich erstellt: {offset} (ID: {binwalk_raw.id})")
return JsonResponse({
'status': 'success',
'message': 'Binwalk Raw wurde erfolgreich erstellt',
'data': binwalk_raw.to_json()
}, status=201)
# Create StringsRaw entry
@handle_exceptions
@transaction.atomic
def create_strings_raw(raw_dataset_id: int, string_value: str, string_type: str = 'generic'):
"""
Creates a Strings raw data entry.
"""
# Input validation
if not string_value or not isinstance(string_value, str):
raise ValidationError("Ungültiger String-Wert")
string_value = string_value.strip()
if not string_value:
raise ValidationError("String-Wert darf nicht leer sein")
if len(string_value) > 1000:
raise ValidationError("String-Wert zu lang (max 1000 Zeichen)")
# Create Strings Raw
strings_raw = StringsRaw.objects.create(
raw_dataset_id=raw_dataset_id,
string_value=string_value,
string_type=string_type,
created=datetime.now()
)
logging.info(f"Strings Raw erfolgreich erstellt: {string_type} (ID: {strings_raw.id})")
return JsonResponse({
'status': 'success',
'message': 'Strings Raw wurde erfolgreich erstellt',
'data': strings_raw.to_json()
}, status=201)
# Create BinwalkAnalyzed entry
@handle_exceptions
@transaction.atomic
def create_binwalk_analyzed(analyzed_dataset_id: int, tool_id: int, component_type: str,
offset: str, size: str = None, entropy: float = None):
"""
Creates an analyzed Binwalk entry.
"""
# Input validation
if not component_type or not isinstance(component_type, str):
raise ValidationError("Ungültiger Komponententyp")
if not offset or not isinstance(offset, str):
raise ValidationError("Ungültiger Offset")
component_type = component_type.strip()
offset = offset.strip()
if not component_type or not offset:
raise ValidationError("Komponententyp und Offset dürfen nicht leer sein")
# Create Binwalk Analyzed
binwalk_analyzed = BinwalkAnalyzed.objects.create(
analyzed_dataset_id=analyzed_dataset_id,
tool_id=tool_id,
component_type=component_type,
offset=offset,
size=size,
entropy=entropy,
created=datetime.now()
)
logging.info(f"Binwalk Analyzed erfolgreich erstellt: {component_type} (ID: {binwalk_analyzed.id})")
return JsonResponse({
'status': 'success',
'message': 'Binwalk Analyzed wurde erfolgreich erstellt',
'data': binwalk_analyzed.to_json()
}, status=201)
# Create StringsAnalyzed entry
@handle_exceptions
@transaction.atomic
def create_strings_analyzed(analyzed_dataset_id: int, tool_id: int, string_value: str,
category: str, severity: str = 'info'):
"""
Creates an analyzed Strings entry.
"""
# Input validation
if not string_value or not isinstance(string_value, str):
raise ValidationError("Ungültiger String-Wert")
if not category or not isinstance(category, str):
raise ValidationError("Ungültige Kategorie")
string_value = string_value.strip()
category = category.strip()
if not string_value or not category:
raise ValidationError("String-Wert und Kategorie dürfen nicht leer sein")
# Validate severity
valid_severities = ['critical', 'high', 'medium', 'low', 'info']
if severity not in valid_severities:
raise ValidationError(f"Ungültiger Severity-Wert. Erlaubt: {', '.join(valid_severities)}")
# Create Strings Analyzed
strings_analyzed = StringsAnalyzed.objects.create(
analyzed_dataset_id=analyzed_dataset_id,
tool_id=tool_id,
string_value=string_value[:1000], # Limit 1000 characters
category=category,
severity=severity,
created=datetime.now()
)
logging.info(f"Strings Analyzed erfolgreich erstellt: {category} (ID: {strings_analyzed.id})")
return JsonResponse({
'status': 'success',
'message': 'Strings Analyzed wurde erfolgreich erstellt',
'data': strings_analyzed.to_json()
}, status=201)
# Add import statements at the top of db_create.py:
# from .models import BinwalkRaw, StringsRaw, BinwalkAnalyzed, StringsAnalyzed