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.
Files changed (200) hide show
  1. mcp_proxy_adapter/__main__.py +32 -0
  2. mcp_proxy_adapter/api/app.py +290 -33
  3. mcp_proxy_adapter/api/handlers.py +32 -6
  4. mcp_proxy_adapter/api/middleware/__init__.py +38 -32
  5. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
  6. mcp_proxy_adapter/api/middleware/error_handling.py +9 -0
  7. mcp_proxy_adapter/api/middleware/factory.py +243 -0
  8. mcp_proxy_adapter/api/middleware/logging.py +32 -6
  9. mcp_proxy_adapter/api/middleware/protocol_middleware.py +201 -0
  10. mcp_proxy_adapter/api/middleware/transport_middleware.py +122 -0
  11. mcp_proxy_adapter/api/middleware/unified_security.py +197 -0
  12. mcp_proxy_adapter/api/middleware/user_info_middleware.py +158 -0
  13. mcp_proxy_adapter/commands/__init__.py +19 -4
  14. mcp_proxy_adapter/commands/auth_validation_command.py +408 -0
  15. mcp_proxy_adapter/commands/base.py +66 -32
  16. mcp_proxy_adapter/commands/builtin_commands.py +95 -0
  17. mcp_proxy_adapter/commands/catalog_manager.py +838 -0
  18. mcp_proxy_adapter/commands/cert_monitor_command.py +620 -0
  19. mcp_proxy_adapter/commands/certificate_management_command.py +608 -0
  20. mcp_proxy_adapter/commands/command_registry.py +711 -354
  21. mcp_proxy_adapter/commands/dependency_manager.py +245 -0
  22. mcp_proxy_adapter/commands/echo_command.py +81 -0
  23. mcp_proxy_adapter/commands/health_command.py +8 -1
  24. mcp_proxy_adapter/commands/help_command.py +21 -14
  25. mcp_proxy_adapter/commands/hooks.py +200 -167
  26. mcp_proxy_adapter/commands/key_management_command.py +506 -0
  27. mcp_proxy_adapter/commands/load_command.py +176 -0
  28. mcp_proxy_adapter/commands/plugins_command.py +235 -0
  29. mcp_proxy_adapter/commands/protocol_management_command.py +232 -0
  30. mcp_proxy_adapter/commands/proxy_registration_command.py +409 -0
  31. mcp_proxy_adapter/commands/reload_command.py +48 -50
  32. mcp_proxy_adapter/commands/result.py +1 -0
  33. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  34. mcp_proxy_adapter/commands/roles_management_command.py +697 -0
  35. mcp_proxy_adapter/commands/security_command.py +488 -0
  36. mcp_proxy_adapter/commands/ssl_setup_command.py +366 -0
  37. mcp_proxy_adapter/commands/token_management_command.py +529 -0
  38. mcp_proxy_adapter/commands/transport_management_command.py +144 -0
  39. mcp_proxy_adapter/commands/unload_command.py +158 -0
  40. mcp_proxy_adapter/config.py +394 -14
  41. mcp_proxy_adapter/core/app_factory.py +410 -0
  42. mcp_proxy_adapter/core/app_runner.py +272 -0
  43. mcp_proxy_adapter/core/auth_validator.py +606 -0
  44. mcp_proxy_adapter/core/certificate_utils.py +1045 -0
  45. mcp_proxy_adapter/core/client.py +574 -0
  46. mcp_proxy_adapter/core/client_manager.py +284 -0
  47. mcp_proxy_adapter/core/client_security.py +384 -0
  48. mcp_proxy_adapter/core/config_converter.py +405 -0
  49. mcp_proxy_adapter/core/config_validator.py +218 -0
  50. mcp_proxy_adapter/core/logging.py +19 -3
  51. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  52. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  53. mcp_proxy_adapter/core/protocol_manager.py +385 -0
  54. mcp_proxy_adapter/core/proxy_client.py +602 -0
  55. mcp_proxy_adapter/core/proxy_registration.py +522 -0
  56. mcp_proxy_adapter/core/role_utils.py +426 -0
  57. mcp_proxy_adapter/core/security_adapter.py +370 -0
  58. mcp_proxy_adapter/core/security_factory.py +239 -0
  59. mcp_proxy_adapter/core/security_integration.py +286 -0
  60. mcp_proxy_adapter/core/server_adapter.py +282 -0
  61. mcp_proxy_adapter/core/server_engine.py +270 -0
  62. mcp_proxy_adapter/core/settings.py +1 -0
  63. mcp_proxy_adapter/core/ssl_utils.py +234 -0
  64. mcp_proxy_adapter/core/transport_manager.py +292 -0
  65. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  66. mcp_proxy_adapter/custom_openapi.py +22 -11
  67. mcp_proxy_adapter/examples/__init__.py +13 -4
  68. mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
  69. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  70. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  71. mcp_proxy_adapter/examples/basic_framework/main.py +44 -0
  72. mcp_proxy_adapter/examples/commands/__init__.py +5 -0
  73. mcp_proxy_adapter/examples/create_certificates_simple.py +550 -0
  74. mcp_proxy_adapter/examples/debug_request_state.py +112 -0
  75. mcp_proxy_adapter/examples/debug_role_chain.py +158 -0
  76. mcp_proxy_adapter/examples/demo_client.py +275 -0
  77. mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +9 -0
  78. mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +4 -0
  79. mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +4 -0
  80. mcp_proxy_adapter/examples/examples/basic_framework/main.py +44 -0
  81. mcp_proxy_adapter/examples/examples/full_application/__init__.py +12 -0
  82. mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +7 -0
  83. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +80 -0
  84. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  85. mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +7 -0
  86. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +75 -0
  87. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  88. mcp_proxy_adapter/examples/examples/full_application/main.py +173 -0
  89. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +154 -0
  90. mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
  91. mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
  92. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +80 -0
  93. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  94. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
  95. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +75 -0
  96. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  97. mcp_proxy_adapter/examples/full_application/main.py +173 -0
  98. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
  99. mcp_proxy_adapter/examples/generate_all_certificates.py +362 -0
  100. mcp_proxy_adapter/examples/generate_certificates.py +177 -0
  101. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
  102. mcp_proxy_adapter/examples/generate_test_configs.py +331 -0
  103. mcp_proxy_adapter/examples/proxy_registration_example.py +334 -0
  104. mcp_proxy_adapter/examples/run_example.py +59 -0
  105. mcp_proxy_adapter/examples/run_full_test_suite.py +318 -0
  106. mcp_proxy_adapter/examples/run_proxy_server.py +146 -0
  107. mcp_proxy_adapter/examples/run_security_tests.py +544 -0
  108. mcp_proxy_adapter/examples/run_security_tests_fixed.py +247 -0
  109. mcp_proxy_adapter/examples/scripts/config_generator.py +740 -0
  110. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +560 -0
  111. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +369 -0
  112. mcp_proxy_adapter/examples/security_test_client.py +782 -0
  113. mcp_proxy_adapter/examples/setup_test_environment.py +328 -0
  114. mcp_proxy_adapter/examples/test_config.py +148 -0
  115. mcp_proxy_adapter/examples/test_config_generator.py +86 -0
  116. mcp_proxy_adapter/examples/test_examples.py +281 -0
  117. mcp_proxy_adapter/examples/universal_client.py +620 -0
  118. mcp_proxy_adapter/main.py +93 -0
  119. mcp_proxy_adapter/utils/config_generator.py +1008 -0
  120. mcp_proxy_adapter/version.py +5 -2
  121. mcp_proxy_adapter-6.0.1.dist-info/METADATA +679 -0
  122. mcp_proxy_adapter-6.0.1.dist-info/RECORD +140 -0
  123. mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt +2 -0
  124. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/licenses/LICENSE +2 -2
  125. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  126. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  127. mcp_proxy_adapter/commands/reload_settings_command.py +0 -125
  128. mcp_proxy_adapter/examples/README.md +0 -124
  129. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  130. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  131. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  132. mcp_proxy_adapter/examples/basic_server/config.json +0 -35
  133. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  134. mcp_proxy_adapter/examples/basic_server/server.py +0 -103
  135. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  136. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  137. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -250
  138. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  139. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  140. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  141. mcp_proxy_adapter/examples/custom_commands/config.json +0 -35
  142. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  143. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  144. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  145. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  146. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  147. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  148. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  149. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  150. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  151. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  152. mcp_proxy_adapter/examples/custom_commands/server.py +0 -228
  153. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  154. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  155. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  156. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  157. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  158. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  159. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  160. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  161. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  162. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  163. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  164. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  165. mcp_proxy_adapter/tests/__init__.py +0 -0
  166. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  167. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  168. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  169. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  170. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  171. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  172. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  173. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  174. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  175. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  176. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  177. mcp_proxy_adapter/tests/conftest.py +0 -131
  178. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  179. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  180. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  181. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  182. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  183. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  184. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  185. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  186. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  187. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  188. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  189. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  190. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  191. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  192. mcp_proxy_adapter/tests/test_config.py +0 -127
  193. mcp_proxy_adapter/tests/test_utils.py +0 -65
  194. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  195. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  196. mcp_proxy_adapter/tests/unit/test_config.py +0 -217
  197. mcp_proxy_adapter-4.1.1.dist-info/METADATA +0 -200
  198. mcp_proxy_adapter-4.1.1.dist-info/RECORD +0 -110
  199. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/WHEEL +0 -0
  200. {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
+ }