-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update client/server -> deadlock pbs during connection establishment
- Loading branch information
Showing
8 changed files
with
270 additions
and
232 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,100 @@ | ||
import base64 | ||
import logging | ||
from aioquic.asyncio import serve | ||
from aioquic.asyncio.protocol import QuicConnectionProtocol | ||
from aioquic.quic.configuration import QuicConfiguration | ||
from aioquic.quic.events import HandshakeCompleted | ||
from aioquic.asyncio.server import HttpRequestHandler, HttpServerProtocol, Route | ||
from aioquic.quic.events import ProtocolNegotiated | ||
from typing import Callable | ||
import util.linux_util as linux_util | ||
from util.linux_util.linux_user import * | ||
from http3.http3_server import HttpRequestHandler | ||
from linux_server.handlers import * | ||
from ssh.version import * | ||
|
||
logging.basicConfig(level=logging.DEBUG) | ||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def handle_auths(enablePasswordLogin: bool, defaultMaxPacketSize: int) -> Callable: | ||
async def handle_request(handler: HttpRequestHandler, event: ProtocolNegotiated): | ||
request = handler._http_request_received | ||
logger.debug(f"Received request from User-Agent {request.headers.get('user-agent')}") | ||
async def handle_auths( | ||
enable_password_login: bool, | ||
default_max_packet_size: int, | ||
handler_func: callable, | ||
request_handler: HttpRequestHandler | ||
): | ||
""" | ||
Handle different types of authentication for a given HTTP request. | ||
""" | ||
# Set response server header | ||
request_handler.send({ | ||
"type": "http.response.start", | ||
"status": 200, | ||
"headers": [(b"server", b"MySSH3Server")] # Replace with your server version | ||
}) | ||
|
||
# Add your version check and logic here | ||
# Check SSH3 version | ||
user_agent = request_handler.scope["headers"].get(b"user-agent", b"").decode() | ||
major, minor, patch = parse_version(user_agent) # Implement this function | ||
if major != MAJOR or minor != MINOR: | ||
request_handler.send({ | ||
"type": "http.response.body", | ||
"body": b"Unsupported version", | ||
"more_body": False, | ||
}) | ||
return | ||
|
||
if not handler._quic._is_handshake_complete: | ||
handler._quic.send_response(status_code=425) # 425 Too Early | ||
return | ||
# Check if connection is complete | ||
if not isinstance(request_handler.connection._quic, QuicConnection) or not request_handler.connection._quic._handshake_complete: | ||
request_handler.send({ | ||
"type": "http.response.start", | ||
"status": 425, # HTTP StatusTooEarly | ||
"headers": [] | ||
}) | ||
return | ||
|
||
# Process the request and perform authentication | ||
authorization = request.headers.get('authorization') | ||
if enablePasswordLogin and authorization.startswith('Basic '): | ||
await handle_basic_auth(handler, request) | ||
elif authorization.startswith('Bearer '): | ||
# Handle bearer authentication | ||
pass | ||
else: | ||
handler._quic.send_response(status_code=401) # 401 Unauthorized | ||
# Create a new conversation | ||
# Implement NewServerConversation based on your protocol's specifics | ||
conv = await NewServerConversation( | ||
request_handler.connection._quic, | ||
default_max_packet_size | ||
) | ||
|
||
return handle_request | ||
# Handle authentication | ||
authorization = request_handler.scope["headers"].get(b"authorization", b"").decode() | ||
if enable_password_login and authorization.startswith("Basic "): | ||
await handle_basic_auth(handler_func, conv, request_handler) | ||
elif authorization.startswith("Bearer "): | ||
username = request_handler.scope["headers"].get(b":path").decode().split("?", 1)[0].lstrip("/") | ||
conv_id = base64.b64encode(conv.id).decode() | ||
await HandleBearerAuth(username, conv_id, handler_func, request_handler) | ||
else: | ||
request_handler.send({ | ||
"type": "http.response.start", | ||
"status": 401, | ||
"headers": [(b"www-authenticate", b"Basic")] | ||
}) | ||
|
||
await request_handler.transmit() | ||
|
||
def handle_basic_auth(handler: HttpRequestHandler, request): | ||
auth = request.headers.get('authorization') | ||
username, password = base64.b64decode(auth.split(' ')[1]).decode().split(':') | ||
if not linux_util.UserPasswordAuthentication(username, password): | ||
handler._quic.send_response(status_code=401) # 401 Unauthorized | ||
return | ||
async def handle_basic_auth(request, handler_func, conv, request_handler): | ||
# Extract Basic Auth credentials | ||
username, password, ok = extract_basic_auth(request) | ||
if not ok: | ||
return web.Response(status=401) | ||
|
||
# Replace this with your own authentication method | ||
ok = await user_password_authentication(username, password) | ||
if not ok: | ||
return web.Response(status=401) | ||
|
||
return await handler_func(username, conv, request) | ||
|
||
def extract_basic_auth(request): | ||
auth_header = request.headers.get('Authorization') | ||
if not auth_header: | ||
return None, None, False | ||
|
||
# Continue with the authenticated request processing | ||
# Basic Auth Parsing | ||
try: | ||
auth_type, auth_info = auth_header.split(' ', 1) | ||
if auth_type.lower() != 'basic': | ||
return None, None, False | ||
|
||
def check_credentials(username, password): | ||
# Placeholder for checking username and password | ||
return True # Assuming credentials are valid | ||
username, password = base64.b64decode(auth_info).decode().split(':', 1) | ||
return username, password, True | ||
except Exception as e: | ||
return None, None, False |
Oops, something went wrong.