mcp-proxy-adapter 4.1.1__py3-none-any.whl → 6.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_proxy_adapter/__main__.py +32 -0
- mcp_proxy_adapter/api/app.py +290 -33
- mcp_proxy_adapter/api/handlers.py +32 -6
- mcp_proxy_adapter/api/middleware/__init__.py +38 -32
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +9 -0
- mcp_proxy_adapter/api/middleware/factory.py +243 -0
- mcp_proxy_adapter/api/middleware/logging.py +32 -6
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +201 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +122 -0
- mcp_proxy_adapter/api/middleware/unified_security.py +197 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +158 -0
- mcp_proxy_adapter/commands/__init__.py +19 -4
- mcp_proxy_adapter/commands/auth_validation_command.py +408 -0
- mcp_proxy_adapter/commands/base.py +66 -32
- mcp_proxy_adapter/commands/builtin_commands.py +95 -0
- mcp_proxy_adapter/commands/catalog_manager.py +838 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +620 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +608 -0
- mcp_proxy_adapter/commands/command_registry.py +711 -354
- mcp_proxy_adapter/commands/dependency_manager.py +245 -0
- mcp_proxy_adapter/commands/echo_command.py +81 -0
- mcp_proxy_adapter/commands/health_command.py +8 -1
- mcp_proxy_adapter/commands/help_command.py +21 -14
- mcp_proxy_adapter/commands/hooks.py +200 -167
- mcp_proxy_adapter/commands/key_management_command.py +506 -0
- mcp_proxy_adapter/commands/load_command.py +176 -0
- mcp_proxy_adapter/commands/plugins_command.py +235 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +232 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +409 -0
- mcp_proxy_adapter/commands/reload_command.py +48 -50
- mcp_proxy_adapter/commands/result.py +1 -0
- mcp_proxy_adapter/commands/role_test_command.py +141 -0
- mcp_proxy_adapter/commands/roles_management_command.py +697 -0
- mcp_proxy_adapter/commands/security_command.py +488 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +366 -0
- mcp_proxy_adapter/commands/token_management_command.py +529 -0
- mcp_proxy_adapter/commands/transport_management_command.py +144 -0
- mcp_proxy_adapter/commands/unload_command.py +158 -0
- mcp_proxy_adapter/config.py +394 -14
- mcp_proxy_adapter/core/app_factory.py +410 -0
- mcp_proxy_adapter/core/app_runner.py +272 -0
- mcp_proxy_adapter/core/auth_validator.py +606 -0
- mcp_proxy_adapter/core/certificate_utils.py +1045 -0
- mcp_proxy_adapter/core/client.py +574 -0
- mcp_proxy_adapter/core/client_manager.py +284 -0
- mcp_proxy_adapter/core/client_security.py +384 -0
- mcp_proxy_adapter/core/config_converter.py +405 -0
- mcp_proxy_adapter/core/config_validator.py +218 -0
- mcp_proxy_adapter/core/logging.py +19 -3
- mcp_proxy_adapter/core/mtls_asgi.py +156 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/protocol_manager.py +385 -0
- mcp_proxy_adapter/core/proxy_client.py +602 -0
- mcp_proxy_adapter/core/proxy_registration.py +522 -0
- mcp_proxy_adapter/core/role_utils.py +426 -0
- mcp_proxy_adapter/core/security_adapter.py +370 -0
- mcp_proxy_adapter/core/security_factory.py +239 -0
- mcp_proxy_adapter/core/security_integration.py +286 -0
- mcp_proxy_adapter/core/server_adapter.py +282 -0
- mcp_proxy_adapter/core/server_engine.py +270 -0
- mcp_proxy_adapter/core/settings.py +1 -0
- mcp_proxy_adapter/core/ssl_utils.py +234 -0
- mcp_proxy_adapter/core/transport_manager.py +292 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
- mcp_proxy_adapter/custom_openapi.py +22 -11
- mcp_proxy_adapter/examples/__init__.py +13 -4
- mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +44 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/create_certificates_simple.py +550 -0
- mcp_proxy_adapter/examples/debug_request_state.py +112 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +158 -0
- mcp_proxy_adapter/examples/demo_client.py +275 -0
- mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/examples/basic_framework/main.py +44 -0
- mcp_proxy_adapter/examples/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +7 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +80 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +90 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +7 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +75 -0
- mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +71 -0
- mcp_proxy_adapter/examples/examples/full_application/main.py +173 -0
- mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +154 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +80 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +90 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +75 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +71 -0
- mcp_proxy_adapter/examples/full_application/main.py +173 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
- mcp_proxy_adapter/examples/generate_all_certificates.py +362 -0
- mcp_proxy_adapter/examples/generate_certificates.py +177 -0
- mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
- mcp_proxy_adapter/examples/generate_test_configs.py +331 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +334 -0
- mcp_proxy_adapter/examples/run_example.py +59 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +318 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +146 -0
- mcp_proxy_adapter/examples/run_security_tests.py +544 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +247 -0
- mcp_proxy_adapter/examples/scripts/config_generator.py +740 -0
- mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +560 -0
- mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +369 -0
- mcp_proxy_adapter/examples/security_test_client.py +782 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +328 -0
- mcp_proxy_adapter/examples/test_config.py +148 -0
- mcp_proxy_adapter/examples/test_config_generator.py +86 -0
- mcp_proxy_adapter/examples/test_examples.py +281 -0
- mcp_proxy_adapter/examples/universal_client.py +620 -0
- mcp_proxy_adapter/main.py +93 -0
- mcp_proxy_adapter/utils/config_generator.py +1008 -0
- mcp_proxy_adapter/version.py +5 -2
- mcp_proxy_adapter-6.0.1.dist-info/METADATA +679 -0
- mcp_proxy_adapter-6.0.1.dist-info/RECORD +140 -0
- mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt +2 -0
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/licenses/LICENSE +2 -2
- mcp_proxy_adapter/api/middleware/auth.py +0 -146
- mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
- mcp_proxy_adapter/commands/reload_settings_command.py +0 -125
- mcp_proxy_adapter/examples/README.md +0 -124
- mcp_proxy_adapter/examples/basic_server/README.md +0 -60
- mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
- mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
- mcp_proxy_adapter/examples/basic_server/config.json +0 -35
- mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
- mcp_proxy_adapter/examples/basic_server/server.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
- mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
- mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -250
- mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
- mcp_proxy_adapter/examples/custom_commands/config.json +0 -35
- mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
- mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
- mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
- mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
- mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
- mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
- mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
- mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
- mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
- mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/server.py +0 -228
- mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
- mcp_proxy_adapter/examples/deployment/README.md +0 -49
- mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
- mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
- mcp_proxy_adapter/examples/deployment/config.json +0 -29
- mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
- mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
- mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
- mcp_proxy_adapter/examples/deployment/run.sh +0 -43
- mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
- mcp_proxy_adapter/schemas/base_schema.json +0 -114
- mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
- mcp_proxy_adapter/tests/__init__.py +0 -0
- mcp_proxy_adapter/tests/api/__init__.py +0 -3
- mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
- mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
- mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
- mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
- mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
- mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
- mcp_proxy_adapter/tests/commands/__init__.py +0 -3
- mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
- mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
- mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
- mcp_proxy_adapter/tests/conftest.py +0 -131
- mcp_proxy_adapter/tests/functional/__init__.py +0 -3
- mcp_proxy_adapter/tests/functional/test_api.py +0 -253
- mcp_proxy_adapter/tests/integration/__init__.py +0 -3
- mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
- mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
- mcp_proxy_adapter/tests/performance/__init__.py +0 -3
- mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
- mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
- mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
- mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
- mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
- mcp_proxy_adapter/tests/test_base_command.py +0 -123
- mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
- mcp_proxy_adapter/tests/test_command_registry.py +0 -281
- mcp_proxy_adapter/tests/test_config.py +0 -127
- mcp_proxy_adapter/tests/test_utils.py +0 -65
- mcp_proxy_adapter/tests/unit/__init__.py +0 -3
- mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
- mcp_proxy_adapter/tests/unit/test_config.py +0 -217
- mcp_proxy_adapter-4.1.1.dist-info/METADATA +0 -200
- mcp_proxy_adapter-4.1.1.dist-info/RECORD +0 -110
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,366 @@
|
|
1
|
+
"""
|
2
|
+
SSL Setup Command
|
3
|
+
|
4
|
+
Author: Vasiliy Zdanovskiy
|
5
|
+
email: vasilyvz@gmail.com
|
6
|
+
|
7
|
+
Command for SSL/TLS configuration and certificate management.
|
8
|
+
"""
|
9
|
+
|
10
|
+
import logging
|
11
|
+
import ssl
|
12
|
+
from typing import Dict, Any, Optional
|
13
|
+
|
14
|
+
# Import mcp_security_framework
|
15
|
+
try:
|
16
|
+
from mcp_security_framework.core.ssl_manager import SSLManager
|
17
|
+
from mcp_security_framework.schemas.config import SSLConfig
|
18
|
+
from mcp_security_framework.utils.cert_utils import validate_certificate_chain
|
19
|
+
SECURITY_FRAMEWORK_AVAILABLE = True
|
20
|
+
except ImportError:
|
21
|
+
SECURITY_FRAMEWORK_AVAILABLE = False
|
22
|
+
|
23
|
+
from .base import Command
|
24
|
+
from .result import SuccessResult, ErrorResult
|
25
|
+
from ..config import Config
|
26
|
+
|
27
|
+
logger = logging.getLogger(__name__)
|
28
|
+
|
29
|
+
|
30
|
+
class SSLSetupCommand(Command):
|
31
|
+
"""
|
32
|
+
SSL Setup Command
|
33
|
+
|
34
|
+
Handles SSL/TLS configuration and certificate management.
|
35
|
+
"""
|
36
|
+
|
37
|
+
# Command metadata
|
38
|
+
name = "ssl_setup"
|
39
|
+
version = "1.0.0"
|
40
|
+
descr = "Configure SSL/TLS settings and manage certificates"
|
41
|
+
category = "security"
|
42
|
+
author = "MCP Proxy Adapter Team"
|
43
|
+
email = "team@mcp-proxy-adapter.com"
|
44
|
+
source_url = "https://github.com/mcp-proxy-adapter"
|
45
|
+
result_class = SuccessResult
|
46
|
+
|
47
|
+
def __init__(self):
|
48
|
+
"""Initialize SSL Setup Command."""
|
49
|
+
super().__init__()
|
50
|
+
|
51
|
+
async def execute(self, **kwargs) -> SuccessResult | ErrorResult:
|
52
|
+
"""
|
53
|
+
Execute SSL setup command.
|
54
|
+
|
55
|
+
Args:
|
56
|
+
params: Command parameters including:
|
57
|
+
- action: Operation to perform (get, set, update, reset, test)
|
58
|
+
- config_data: Configuration data for set/update actions
|
59
|
+
- cert_file: Certificate file path for testing
|
60
|
+
- key_file: Private key file path for testing
|
61
|
+
|
62
|
+
Returns:
|
63
|
+
SuccessResult or ErrorResult
|
64
|
+
"""
|
65
|
+
try:
|
66
|
+
action = kwargs.get("action", "get")
|
67
|
+
|
68
|
+
if action == "get":
|
69
|
+
return await self._get_ssl_config()
|
70
|
+
elif action == "set":
|
71
|
+
return await self._set_ssl_config(kwargs.get("config_data", {}))
|
72
|
+
elif action == "update":
|
73
|
+
return await self._update_ssl_config(kwargs.get("config_data", {}))
|
74
|
+
elif action == "reset":
|
75
|
+
return await self._reset_ssl_config()
|
76
|
+
elif action == "test":
|
77
|
+
return await self._test_ssl_config(
|
78
|
+
kwargs.get("cert_file"),
|
79
|
+
kwargs.get("key_file")
|
80
|
+
)
|
81
|
+
else:
|
82
|
+
return ErrorResult(
|
83
|
+
message=f"Unknown action: {action}. Supported actions: get, set, update, reset, test"
|
84
|
+
)
|
85
|
+
|
86
|
+
except Exception as e:
|
87
|
+
logger.error(f"SSL setup command failed: {e}")
|
88
|
+
return ErrorResult(
|
89
|
+
message=f"SSL setup command failed: {str(e)}"
|
90
|
+
)
|
91
|
+
|
92
|
+
async def _get_ssl_config(self) -> SuccessResult | ErrorResult:
|
93
|
+
"""Get current SSL configuration."""
|
94
|
+
try:
|
95
|
+
config = Config()
|
96
|
+
ssl_config = config.get("ssl", {})
|
97
|
+
|
98
|
+
# Add framework information
|
99
|
+
ssl_config["framework_available"] = SECURITY_FRAMEWORK_AVAILABLE
|
100
|
+
|
101
|
+
return SuccessResult(
|
102
|
+
data={"ssl_config": ssl_config}
|
103
|
+
)
|
104
|
+
|
105
|
+
except Exception as e:
|
106
|
+
logger.error(f"Failed to get SSL config: {e}")
|
107
|
+
return ErrorResult(
|
108
|
+
message=f"Failed to get SSL config: {str(e)}"
|
109
|
+
)
|
110
|
+
|
111
|
+
async def _set_ssl_config(self, config_data: Dict[str, Any]) -> SuccessResult | ErrorResult:
|
112
|
+
"""Set SSL configuration."""
|
113
|
+
try:
|
114
|
+
if not isinstance(config_data, dict):
|
115
|
+
return ErrorResult(
|
116
|
+
message="Configuration data must be a dictionary"
|
117
|
+
)
|
118
|
+
|
119
|
+
# Validate configuration if mcp_security_framework is available
|
120
|
+
if SECURITY_FRAMEWORK_AVAILABLE:
|
121
|
+
try:
|
122
|
+
ssl_config = SSLConfig(**config_data)
|
123
|
+
config_data = ssl_config.dict()
|
124
|
+
except Exception as e:
|
125
|
+
return ErrorResult(
|
126
|
+
message=f"Invalid SSL configuration: {str(e)}"
|
127
|
+
)
|
128
|
+
|
129
|
+
# Update configuration
|
130
|
+
config = Config()
|
131
|
+
config.update_config({"ssl": config_data})
|
132
|
+
|
133
|
+
return SuccessResult(
|
134
|
+
data={"message": "SSL configuration updated", "ssl_config": config_data}
|
135
|
+
)
|
136
|
+
|
137
|
+
except Exception as e:
|
138
|
+
logger.error(f"Failed to set SSL config: {e}")
|
139
|
+
return ErrorResult(
|
140
|
+
message=f"Failed to set SSL config: {str(e)}"
|
141
|
+
)
|
142
|
+
|
143
|
+
async def _update_ssl_config(self, config_data: Dict[str, Any]) -> SuccessResult | ErrorResult:
|
144
|
+
"""Update SSL configuration."""
|
145
|
+
try:
|
146
|
+
if not isinstance(config_data, dict):
|
147
|
+
return ErrorResult(
|
148
|
+
message="Configuration data must be a dictionary"
|
149
|
+
)
|
150
|
+
|
151
|
+
config = Config()
|
152
|
+
current_config = config.get("ssl", {})
|
153
|
+
|
154
|
+
# Update with new data
|
155
|
+
current_config.update(config_data)
|
156
|
+
|
157
|
+
# Validate configuration if mcp_security_framework is available
|
158
|
+
if SECURITY_FRAMEWORK_AVAILABLE:
|
159
|
+
try:
|
160
|
+
ssl_config = SSLConfig(**current_config)
|
161
|
+
current_config = ssl_config.dict()
|
162
|
+
except Exception as e:
|
163
|
+
return ErrorResult(
|
164
|
+
message=f"Invalid SSL configuration: {str(e)}"
|
165
|
+
)
|
166
|
+
|
167
|
+
# Update configuration
|
168
|
+
config.update_config({"ssl": current_config})
|
169
|
+
|
170
|
+
return SuccessResult(
|
171
|
+
data={"message": "SSL configuration updated", "ssl_config": current_config}
|
172
|
+
)
|
173
|
+
|
174
|
+
except Exception as e:
|
175
|
+
logger.error(f"Failed to update SSL config: {e}")
|
176
|
+
return ErrorResult(
|
177
|
+
message=f"Failed to update SSL config: {str(e)}"
|
178
|
+
)
|
179
|
+
|
180
|
+
async def _reset_ssl_config(self) -> SuccessResult | ErrorResult:
|
181
|
+
"""Reset SSL configuration to defaults."""
|
182
|
+
try:
|
183
|
+
default_config = {
|
184
|
+
"enabled": False,
|
185
|
+
"cert_file": None,
|
186
|
+
"key_file": None,
|
187
|
+
"ca_file": None,
|
188
|
+
"verify_mode": "CERT_REQUIRED",
|
189
|
+
"cipher_suites": [],
|
190
|
+
"framework_available": SECURITY_FRAMEWORK_AVAILABLE
|
191
|
+
}
|
192
|
+
|
193
|
+
config = Config()
|
194
|
+
config.update_config({"ssl": default_config})
|
195
|
+
|
196
|
+
return SuccessResult(
|
197
|
+
data={"message": "SSL configuration reset to defaults", "ssl_config": default_config}
|
198
|
+
)
|
199
|
+
|
200
|
+
except Exception as e:
|
201
|
+
logger.error(f"Failed to reset SSL config: {e}")
|
202
|
+
return ErrorResult(
|
203
|
+
message=f"Failed to reset SSL config: {str(e)}"
|
204
|
+
)
|
205
|
+
|
206
|
+
async def _test_ssl_config(self, cert_file: Optional[str], key_file: Optional[str]) -> SuccessResult | ErrorResult:
|
207
|
+
"""
|
208
|
+
Test SSL configuration.
|
209
|
+
|
210
|
+
Args:
|
211
|
+
cert_file: Path to certificate file
|
212
|
+
key_file: Path to private key file
|
213
|
+
|
214
|
+
Returns:
|
215
|
+
SuccessResult or ErrorResult with test results
|
216
|
+
"""
|
217
|
+
try:
|
218
|
+
if not cert_file or not key_file:
|
219
|
+
return ErrorResult(
|
220
|
+
message="Both cert_file and key_file are required for testing"
|
221
|
+
)
|
222
|
+
|
223
|
+
if SECURITY_FRAMEWORK_AVAILABLE:
|
224
|
+
return await self._test_ssl_config_with_framework(cert_file, key_file)
|
225
|
+
else:
|
226
|
+
return await self._test_ssl_config_fallback(cert_file, key_file)
|
227
|
+
|
228
|
+
except Exception as e:
|
229
|
+
logger.error(f"Failed to test SSL config: {e}")
|
230
|
+
return ErrorResult(
|
231
|
+
message=f"Failed to test SSL config: {str(e)}"
|
232
|
+
)
|
233
|
+
|
234
|
+
async def _test_ssl_config_with_framework(self, cert_file: str, key_file: str) -> SuccessResult | ErrorResult:
|
235
|
+
"""Test SSL configuration using mcp_security_framework."""
|
236
|
+
try:
|
237
|
+
# Create SSL manager
|
238
|
+
ssl_config = SSLConfig(
|
239
|
+
cert_file=cert_file,
|
240
|
+
key_file=key_file,
|
241
|
+
enabled=True
|
242
|
+
)
|
243
|
+
|
244
|
+
ssl_manager = SSLManager(ssl_config)
|
245
|
+
|
246
|
+
# Test SSL context creation
|
247
|
+
context = ssl_manager.create_server_ssl_context()
|
248
|
+
|
249
|
+
details = {
|
250
|
+
"framework": "mcp_security_framework",
|
251
|
+
"certificate_loaded": True,
|
252
|
+
"private_key_loaded": True,
|
253
|
+
"context_created": True,
|
254
|
+
"cert_file": cert_file,
|
255
|
+
"key_file": key_file
|
256
|
+
}
|
257
|
+
|
258
|
+
return SuccessResult(
|
259
|
+
data={
|
260
|
+
"success": True,
|
261
|
+
"details": details
|
262
|
+
}
|
263
|
+
)
|
264
|
+
|
265
|
+
except Exception as e:
|
266
|
+
return ErrorResult(
|
267
|
+
message=f"SSL test failed: {str(e)}",
|
268
|
+
data={
|
269
|
+
"success": False,
|
270
|
+
"error": str(e),
|
271
|
+
"details": {
|
272
|
+
"framework": "mcp_security_framework",
|
273
|
+
"certificate_loaded": False,
|
274
|
+
"private_key_loaded": False,
|
275
|
+
"context_created": False
|
276
|
+
}
|
277
|
+
}
|
278
|
+
)
|
279
|
+
|
280
|
+
async def _test_ssl_config_fallback(self, cert_file: str, key_file: str) -> SuccessResult | ErrorResult:
|
281
|
+
"""Test SSL configuration using fallback method."""
|
282
|
+
try:
|
283
|
+
# Create SSL context
|
284
|
+
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
285
|
+
context.check_hostname = False
|
286
|
+
context.verify_mode = ssl.CERT_NONE
|
287
|
+
|
288
|
+
# Load certificate and key
|
289
|
+
context.load_cert_chain(cert_file, key_file)
|
290
|
+
|
291
|
+
# Test basic SSL functionality
|
292
|
+
details = {
|
293
|
+
"framework": "fallback (ssl module)",
|
294
|
+
"ssl_version": ssl.OPENSSL_VERSION,
|
295
|
+
"certificate_loaded": True,
|
296
|
+
"private_key_loaded": True,
|
297
|
+
"context_created": True,
|
298
|
+
"cert_file": cert_file,
|
299
|
+
"key_file": key_file
|
300
|
+
}
|
301
|
+
|
302
|
+
return SuccessResult(
|
303
|
+
data={
|
304
|
+
"success": True,
|
305
|
+
"details": details
|
306
|
+
}
|
307
|
+
)
|
308
|
+
|
309
|
+
except Exception as e:
|
310
|
+
return ErrorResult(
|
311
|
+
message=f"SSL test failed: {str(e)}",
|
312
|
+
data={
|
313
|
+
"success": False,
|
314
|
+
"error": str(e),
|
315
|
+
"details": {
|
316
|
+
"framework": "fallback (ssl module)",
|
317
|
+
"ssl_version": ssl.OPENSSL_VERSION,
|
318
|
+
"certificate_loaded": False,
|
319
|
+
"private_key_loaded": False,
|
320
|
+
"context_created": False
|
321
|
+
}
|
322
|
+
}
|
323
|
+
)
|
324
|
+
|
325
|
+
def to_dict(self) -> Dict[str, Any]:
|
326
|
+
"""Convert command to dictionary."""
|
327
|
+
return {
|
328
|
+
"name": self.name,
|
329
|
+
"description": self.description,
|
330
|
+
"version": self.version,
|
331
|
+
"framework_available": SECURITY_FRAMEWORK_AVAILABLE
|
332
|
+
}
|
333
|
+
|
334
|
+
def get_schema(self) -> Dict[str, Any]:
|
335
|
+
"""Get command schema."""
|
336
|
+
return {
|
337
|
+
"type": "object",
|
338
|
+
"properties": {
|
339
|
+
"action": {
|
340
|
+
"type": "string",
|
341
|
+
"enum": ["get", "set", "update", "reset", "test"],
|
342
|
+
"description": "Action to perform"
|
343
|
+
},
|
344
|
+
"config_data": {
|
345
|
+
"type": "object",
|
346
|
+
"description": "SSL configuration data",
|
347
|
+
"properties": {
|
348
|
+
"enabled": {"type": "boolean"},
|
349
|
+
"cert_file": {"type": "string"},
|
350
|
+
"key_file": {"type": "string"},
|
351
|
+
"ca_file": {"type": "string"},
|
352
|
+
"verify_mode": {"type": "string"},
|
353
|
+
"cipher_suites": {"type": "array", "items": {"type": "string"}}
|
354
|
+
}
|
355
|
+
},
|
356
|
+
"cert_file": {
|
357
|
+
"type": "string",
|
358
|
+
"description": "Certificate file path for testing"
|
359
|
+
},
|
360
|
+
"key_file": {
|
361
|
+
"type": "string",
|
362
|
+
"description": "Private key file path for testing"
|
363
|
+
}
|
364
|
+
},
|
365
|
+
"required": ["action"]
|
366
|
+
}
|