This commit is contained in:
2026-02-06 14:49:01 +01:00
parent 3b70e1c5fb
commit 9149976db4
10 changed files with 302 additions and 40 deletions

View File

@@ -0,0 +1,17 @@
switch_name,ip_address,firmware_version
NET-SW01,10.220.1.84,PL.10.16.1006
NET-SW02,10.220.1.85,PL.10.16.1006
NET-SW01,10.220.1.84,PL.10.16.1006
NET-SW02,10.220.1.85,PL.10.16.1006
NET-SW04,10.220.1.86,PL.10.16.1006
NET-SW05,10.220.1.87,PL.10.16.1006
NET-SW06,10.220.1.88,PL.10.16.1006
NET-SW01-CORE,10.220.1.89,LL.10.16.1006
NET-SW07,10.220.1.90,PL.10.16.1006
NET-SW08,10.220.1.91,PL.10.16.1006
NET-SW09,10.220.1.92,PL.10.16.1006
NET-SW10,10.220.1.93,PL.10.16.1006
NET-SW11,10.220.1.94,PL.10.16.1006
NET-SW13,10.220.1.96,PL.10.16.1006
NET-SW16,10.220.1.98,PL.10.16.1006
N/A,10.220.1.99,Auth Failed
1 switch_name ip_address firmware_version
2 NET-SW01 10.220.1.84 PL.10.16.1006
3 NET-SW02 10.220.1.85 PL.10.16.1006
4 NET-SW01 10.220.1.84 PL.10.16.1006
5 NET-SW02 10.220.1.85 PL.10.16.1006
6 NET-SW04 10.220.1.86 PL.10.16.1006
7 NET-SW05 10.220.1.87 PL.10.16.1006
8 NET-SW06 10.220.1.88 PL.10.16.1006
9 NET-SW01-CORE 10.220.1.89 LL.10.16.1006
10 NET-SW07 10.220.1.90 PL.10.16.1006
11 NET-SW08 10.220.1.91 PL.10.16.1006
12 NET-SW09 10.220.1.92 PL.10.16.1006
13 NET-SW10 10.220.1.93 PL.10.16.1006
14 NET-SW11 10.220.1.94 PL.10.16.1006
15 NET-SW13 10.220.1.96 PL.10.16.1006
16 NET-SW16 10.220.1.98 PL.10.16.1006
17 N/A 10.220.1.99 Auth Failed

View File

@@ -0,0 +1,17 @@
switch_name,ip_address,firmware_version
NET-SW01,10.220.1.84,PL.10.16.1006
NET-SW02,10.220.1.85,PL.10.16.1006
NET-SW01,10.220.1.84,PL.10.16.1006
NET-SW02,10.220.1.85,PL.10.16.1006
NET-SW04,10.220.1.86,PL.10.16.1006
NET-SW05,10.220.1.87,PL.10.16.1006
NET-SW06,10.220.1.88,PL.10.16.1006
NET-SW01-CORE,10.220.1.89,LL.10.16.1006
NET-SW07,10.220.1.90,PL.10.16.1006
NET-SW08,10.220.1.91,PL.10.16.1006
NET-SW09,10.220.1.92,PL.10.16.1006
NET-SW10,10.220.1.93,PL.10.16.1006
NET-SW11,10.220.1.94,PL.10.16.1006
NET-SW13,10.220.1.96,PL.10.16.1006
NET-SW16,10.220.1.98,PL.10.16.1006
N/A,10.220.1.99,Auth Failed
1 switch_name ip_address firmware_version
2 NET-SW01 10.220.1.84 PL.10.16.1006
3 NET-SW02 10.220.1.85 PL.10.16.1006
4 NET-SW01 10.220.1.84 PL.10.16.1006
5 NET-SW02 10.220.1.85 PL.10.16.1006
6 NET-SW04 10.220.1.86 PL.10.16.1006
7 NET-SW05 10.220.1.87 PL.10.16.1006
8 NET-SW06 10.220.1.88 PL.10.16.1006
9 NET-SW01-CORE 10.220.1.89 LL.10.16.1006
10 NET-SW07 10.220.1.90 PL.10.16.1006
11 NET-SW08 10.220.1.91 PL.10.16.1006
12 NET-SW09 10.220.1.92 PL.10.16.1006
13 NET-SW10 10.220.1.93 PL.10.16.1006
14 NET-SW11 10.220.1.94 PL.10.16.1006
15 NET-SW13 10.220.1.96 PL.10.16.1006
16 NET-SW16 10.220.1.98 PL.10.16.1006
17 N/A 10.220.1.99 Auth Failed

View File

@@ -1,19 +1,20 @@
{ {
"network": { "switch_ips": [
"subnet": "10.101.0.0/24", "10.220.1.84",
"auto_detect": false "10.220.1.85",
}, "10.220.1.86",
"scanning": { "10.220.1.87",
"ping_timeout": 0.3, "10.220.1.88",
"ping_delay": 0.001, "10.220.1.89",
"max_threads": 10 "10.220.1.90",
}, "10.220.1.91",
"database": { "10.220.1.92",
"devices_file": "known_devices.json" "10.220.1.93",
}, "10.220.1.94",
"logging": { "10.220.1.96",
"enabled": true, "10.220.1.98",
"log_file": "network_scanner.log", "10.220.1.99"
"log_level": "INFO" ],
} "username": "svc.operator",
} "password": "NuAaGTNPQWyeneQLI5qr"
}

View File

@@ -101,7 +101,7 @@ if __name__ == "__main__":
PASSWORD = os.getenv('ARUBA_PASSWORD') PASSWORD = os.getenv('ARUBA_PASSWORD', 'NuAaGTNPQWyeneQLI5qr')
if not PASSWORD: if not PASSWORD:
print("Hiba: Az ARUBA_PASSWORD környezeti változó nincs beállítva.") print("Hiba: Az ARUBA_PASSWORD környezeti változó nincs beállítva.")
exit() exit()

View File

@@ -0,0 +1,13 @@
import webbrowser
from msal import ConfidentialClientApplication, PublicClientApplication
client_secret = 'Rk-8Q~nJ.sZ-xUiNxtEDdzVgoFFosODLVHX~jdrh'
app_id = '3a08b279-1fc3-419f-a77e-31f12a0f65f7'
SCOPES = ['Mail.ReadWrite']
client = ConfidentialClientApplication(client_id=app_id, client_credential=client_secret)
authorization_url = client.get_authorization_request_url(SCOPES)
print(authorization_url)
# webbrowser.open(authorization_url)

View File

@@ -0,0 +1,58 @@
import os
import requests
from ms_graph import generate_access_token
def download_email_attachments(message_id, headers, save_folder=os.getcwd()):
try:
response = requests.get(
GRAPH_API_ENDPOINT + '/me/messages/{0}/attachments'.format(message_id),
headers=headers
)
attachment_items = response.json()['value']
for attachment in attachment_items:
file_name = attachment['name']
attachment_id = attachment['id']
attachment_content = requests.get(
GRAPH_API_ENDPOINT + '/me/messages/{0}/attachments/{1}/$value'.format(message_id, attachment_id)
)
print('Saving file {0}...'.format(file_name))
with open(os.path.join(save_folder, file_name), 'wb') as _f:
_f.write(attachment_content.content)
return True
except Exception as e:
print(e)
return False
# Step 1. Get the access token
APP_ID = '<app id>'
SCOPES = ['Mail.ReadWrite']
GRAPH_API_ENDPOINT = 'https://graph.microsoft.com/v1.0'
access_token = generate_access_token(app_id=APP_ID, scopes=SCOPES)
headers = {
'Authorization': 'Bearer ' + access_token['access_token']
}
# Step 2. Retrieve emails
params = {
'top': 3, # max is 1000 messages per request
'select': 'subject,hasAttachments',
'filter': 'hasAttachments eq true',
'count': 'true'
}
response = requests.get(GRAPH_API_ENDPOINT + '/me/mailFolders/inbox/messages', headers=headers, params=params)
if response.status_code != 200:
raise Exception(response.json())
response_json = response.json()
response_json.keys()
response_json['@odata.count']
emails = response_json['value']
for email in emails:
if email['hasAttachments']:
email_id = email['id']
download_email_attachments(email_id, headers, r'C:\Tools\')

View File

@@ -0,0 +1,93 @@
import imaplib
import email
import os
from email.header import decode_header
# ===== Einstellungen =====
IMAP_SERVER = "outlook.office365.com" # IMAP-Server-Adresse
IMAP_PORT = 993 # IMAP-SSL-Port
USERNAME = "i.meszely@aps-hh.de" # Benutzername / E-Mail-Adresse
PASSWORD = "virgI6774#Maci" # Passwort
# MAILBOX = 'HelpDesk/Inbox' # Der zu verwendende Ordner
MAILBOX = "INBOX" # Ordnername (z. B. "INBOX" oder "HelpDesk")
PROCESSED_FOLDER = "erledigt" # Zielordner für verarbeitete E-Mails
DOWNLOAD_DIR = r"C:/Tools/" # Speicherort für PDFs
# Verbindung herstellen
mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
mail.login(USERNAME, PASSWORD)
# Ordner auswählen
mail.select(MAILBOX)
# Alle Nachrichten suchen (hier: alle E-Mails)
status, messages = mail.search(None, "ALL")
if status != "OK":
print("Fehler beim Abrufen der Nachrichtenliste")
mail.logout()
exit()
# Liste für zu löschende Nachrichten
delete_list = []
# Nachrichten verarbeiten
for num in messages[0].split():
try:
# Nachricht abrufen
status, data = mail.fetch(num, "(RFC822)")
if status != "OK":
print(f"Fehler beim Herunterladen der Nachricht {num}")
continue
msg = email.message_from_bytes(data[0][1])
pdf_found = False
# Betreff dekodieren
subject, encoding = decode_header(msg["Subject"])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding if encoding else "utf-8", errors="replace")
print(f"Verarbeite E-Mail: {subject}")
# Anhänge prüfen
for part in msg.walk():
if part.get_content_maintype() == "multipart":
continue
if part.get("Content-Disposition") is None:
continue
filename = part.get_filename()
if filename:
decoded_name, enc = decode_header(filename)[0]
if isinstance(decoded_name, bytes):
decoded_name = decoded_name.decode(enc if enc else "utf-8", errors="replace")
# Ungültige Zeichen im Dateinamen ersetzen
safe_filename = "".join(c if c.isalnum() or c in (" ", ".", "_", "-") else "_" for c in decoded_name)
if safe_filename.lower().endswith(".pdf"):
filepath = os.path.join(DOWNLOAD_DIR, safe_filename)
with open(filepath, "wb") as f:
f.write(part.get_payload(decode=True))
print(f"PDF gespeichert: {filepath}")
pdf_found = True
# Falls PDF gefunden → in Zielordner verschieben & später löschen
if pdf_found:
result = mail.copy(num, PROCESSED_FOLDER)
if result[0] == "OK":
delete_list.append(num)
else:
print(f"Fehler beim Verschieben der Nachricht {num}")
except Exception as e:
print(f"Fehler beim Verarbeiten der Nachricht {num}: {e}")
# Nach der Verarbeitung: löschen
for num in delete_list:
mail.store(num, "+FLAGS", "\\Deleted")
mail.expunge()
# Verbindung trennen
mail.logout()
print("Fertig! Alle neuen PDFs wurden heruntergeladen und verarbeitet.")

View File

@@ -0,0 +1,44 @@
import webbrowser
from datetime import datetime
import json
import os
import msal
GRAPH_API_ENDPOINT = 'https://graph.microsoft.com/v1.0'
def generate_access_token(app_id, scopes):
# Save Session Token as a token file
access_token_cache = msal.SerializableTokenCache()
# read the token file
if os.path.exists('ms_graph_api_token.json'):
access_token_cache.deserialize(open("ms_graph_api_token.json", "r").read())
token_detail = json.load(open('ms_graph_api_token.json',))
token_detail_key = list(token_detail['AccessToken'].keys())[0]
token_expiration = datetime.fromtimestamp(int(token_detail['AccessToken'][token_detail_key]['expires_on']))
if datetime.now() > token_expiration:
os.remove('ms_graph_api_token.json')
access_token_cache = msal.SerializableTokenCache()
# assign a SerializableTokenCache object to the client instance
client = msal.PublicClientApplication(client_id=app_id, token_cache=access_token_cache)
accounts = client.get_accounts()
if accounts:
# load the session
token_response = client.acquire_token_silent(scopes, accounts[0])
else:
# authetnicate your accoutn as usual
flow = client.initiate_device_flow(scopes=scopes)
print('user_code: ' + flow['user_code'])
webbrowser.open('https://microsoft.com/devicelogin')
token_response = client.acquire_token_by_device_flow(flow)
with open('ms_graph_api_token.json', 'w') as _f:
_f.write(access_token_cache.serialize())
return token_response
if __name__ == '__main__':
...

View File

@@ -1,21 +0,0 @@
# Code snippets are only available for the latest version. Current version is 1.x
# pip install msgraph-sdk
# New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
from msgraph import GraphServiceClient
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
scopes = ['User.Read']
# Multi-tenant apps can use "common",
# single-tenant apps must use the tenant ID from the Azure portal
tenant_id = 'caee3499-03f8-4175-9fa8-a935248d0ece'
# Values from app registration
client_id = '3a08b279-1fc3-419f-a77e-31f12a0f65f7'
# azure.identity
credential = DeviceCodeCredential(
tenant_id=tenant_id,
client_id=client_id)
graph_client = GraphServiceClient(credential, scopes)

View File

@@ -0,0 +1,40 @@
import imaplib
import os
import ssl
IMAP_SERVER = "outlook.office365.com"
IMAP_PORT = 993
O365_IMAP_USERNAME="i.meszely@aps-hh.de"
O365_IMAP_PASSWORD="virgI6774#"
def test_imap_connection(username, password):
try:
# Create a default SSL context
ssl_context = ssl.create_default_context()
# Connect to the IMAP server over SSL
print(f"Connecting to IMAP server: {IMAP_SERVER}:{IMAP_PORT}...")
with imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT, ssl_context=ssl_context) as mail:
print("Connection established. Attempting to log in...")
mail.login(username, password)
print(f"Successfully logged in as {username}.")
mail.logout()
print("Logged out.")
return True
except imaplib.IMAP4.error as e:
print(f"IMAP login failed for {username}: {e}")
return False
except Exception as e:
print(f"An unexpected error occurred: {e}")
return False
if __name__ == "__main__":
# WARNING: Hardcoding credentials is not recommended for security reasons.
# Consider using environment variables or a secure configuration method.
username = O365_IMAP_USERNAME
password = O365_IMAP_PASSWORD
print(f"Testing IMAP connection for user: {username}")
if test_imap_connection(username, password):
print("\nIMAP connection test completed successfully!")
else:
print("\nIMAP connection test failed.")