From 678b1868f5d579b39c6679f9789643337720d8e2 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Sun, 14 Jun 2026 13:49:24 +0800 Subject: [PATCH] fix: Generate independent short-lived JWT for pcap download No longer depends on the original token type (JWT or API key). Always creates a fresh 10-min JWT for the download URL. --- gns3server/api/routes/mcp/links.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gns3server/api/routes/mcp/links.py b/gns3server/api/routes/mcp/links.py index 64bb9bacc..1a685f651 100644 --- a/gns3server/api/routes/mcp/links.py +++ b/gns3server/api/routes/mcp/links.py @@ -27,6 +27,8 @@ from concurrent.futures import ThreadPoolExecutor, as_completed import logging +from gns3server.services import auth_service + log = logging.getLogger(__name__) BATCH_MAX_WORKERS = 10 @@ -189,12 +191,13 @@ def download_capture_file_handler(params: dict[str, Any], gns3_ctx: dict[str, An if not project_id or not link_id: return {"error": "project_id and link_id are required"} download_url = f"{gns3_ctx['server_url']}/v3/projects/{project_id}/links/{link_id}/capture/file" - auth_token = gns3_ctx['jwt_token'] + # Generate a short-lived download token (10 min) so the user can curl without exposing their API key + download_token = auth_service.create_access_token("mcp-download", expires_in=10) return { "link_id": link_id, "download_url": download_url, - "curl_command": f"curl -L -o capture.pcap -H 'Authorization: Bearer {auth_token}' '{download_url}'", - "note": "Use the curl command to download the PCAP capture file. " + "curl_command": f"curl -L -o capture.pcap -H 'Authorization: Bearer {download_token}' '{download_url}'", + "note": "This download link expires in 10 minutes. " "The file is in pcap format and can be analyzed with Wireshark or tcpdump.", }