mirror of
https://github.com/moghtech/komodo.git
synced 2026-08-25 08:00:17 +00:00
clean up passkey login
This commit is contained in:
@@ -93,7 +93,7 @@ impl PeripheryConnectionArgs<'_> {
|
||||
/// to implement passkey support for backward compatibility
|
||||
async fn handle_login(
|
||||
handler: &mut super::WebsocketHandler<'_, TungsteniteWebsocket>,
|
||||
// deprecated.
|
||||
// for legacy auth
|
||||
passkey: &str,
|
||||
) -> anyhow::Result<()> {
|
||||
// Get the required auth type
|
||||
@@ -107,61 +107,7 @@ async fn handle_login(
|
||||
// Noise auth
|
||||
&[0] => handler.login::<ClientLoginFlow>().await,
|
||||
// Passkey auth
|
||||
&[1] => {
|
||||
let res = async {
|
||||
let mut passkey = if passkey.is_empty() {
|
||||
core_config()
|
||||
.passkey
|
||||
.as_deref()
|
||||
.context("Periphery requires passkey auth")?
|
||||
.as_bytes()
|
||||
.to_vec()
|
||||
} else {
|
||||
passkey.as_bytes().to_vec()
|
||||
};
|
||||
passkey.push(MessageState::Successful.as_byte());
|
||||
|
||||
handler
|
||||
.socket
|
||||
.send(passkey.into())
|
||||
.await
|
||||
.context("Failed to send passkey")?;
|
||||
|
||||
// Receive login state message and return based on value
|
||||
let state_msg = handler.socket.recv_bytes().await.context(
|
||||
"Failed to receive authentication state message",
|
||||
)?;
|
||||
let state = state_msg.last().context(
|
||||
"Authentication state message did not contain state byte",
|
||||
)?;
|
||||
match MessageState::from_byte(*state) {
|
||||
MessageState::Successful => anyhow::Ok(()),
|
||||
_ => Err(deserialize_error_bytes(
|
||||
&state_msg[..(state_msg.len() - 1)],
|
||||
)),
|
||||
}
|
||||
}
|
||||
.await;
|
||||
if let Err(e) = res {
|
||||
let mut bytes = serialize_error_bytes(&e);
|
||||
bytes.push(MessageState::Failed.as_byte());
|
||||
if let Err(e) = handler
|
||||
.socket
|
||||
.send(bytes.into())
|
||||
.await
|
||||
.context("Failed to send login failed to client")
|
||||
{
|
||||
// Log additional error
|
||||
warn!("{e:#}");
|
||||
}
|
||||
// Close socket
|
||||
let _ = handler.socket.close(None).await;
|
||||
// Return the original error
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
&[1] => handle_passkey_login(handler, passkey).await,
|
||||
other => {
|
||||
return Err(anyhow!(
|
||||
"Receieved invalid login type pattern: {other:?}"
|
||||
@@ -170,6 +116,68 @@ async fn handle_login(
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_passkey_login(
|
||||
handler: &mut super::WebsocketHandler<'_, TungsteniteWebsocket>,
|
||||
// for legacy auth
|
||||
passkey: &str,
|
||||
) -> anyhow::Result<()> {
|
||||
let res = async {
|
||||
let mut passkey = if passkey.is_empty() {
|
||||
core_config()
|
||||
.passkey
|
||||
.as_deref()
|
||||
.context("Periphery requires passkey auth")?
|
||||
.as_bytes()
|
||||
.to_vec()
|
||||
} else {
|
||||
passkey.as_bytes().to_vec()
|
||||
};
|
||||
passkey.push(MessageState::Successful.as_byte());
|
||||
|
||||
handler
|
||||
.socket
|
||||
.send(passkey.into())
|
||||
.await
|
||||
.context("Failed to send passkey")?;
|
||||
|
||||
// Receive login state message and return based on value
|
||||
let state_msg = handler
|
||||
.socket
|
||||
.recv_bytes()
|
||||
.await
|
||||
.context("Failed to receive authentication state message")?;
|
||||
let state = state_msg.last().context(
|
||||
"Authentication state message did not contain state byte",
|
||||
)?;
|
||||
match MessageState::from_byte(*state) {
|
||||
MessageState::Successful => anyhow::Ok(()),
|
||||
_ => Err(deserialize_error_bytes(
|
||||
&state_msg[..(state_msg.len() - 1)],
|
||||
)),
|
||||
}
|
||||
}
|
||||
.await;
|
||||
if let Err(e) = res {
|
||||
let mut bytes = serialize_error_bytes(&e);
|
||||
bytes.push(MessageState::Failed.as_byte());
|
||||
if let Err(e) = handler
|
||||
.socket
|
||||
.send(bytes.into())
|
||||
.await
|
||||
.context("Failed to send login failed to client")
|
||||
{
|
||||
// Log additional error
|
||||
warn!("{e:#}");
|
||||
}
|
||||
// Close socket
|
||||
let _ = handler.socket.close(None).await;
|
||||
// Return the original error
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn connect_websocket(
|
||||
url: &str,
|
||||
) -> anyhow::Result<(TungsteniteWebsocket, HeaderValue)> {
|
||||
|
||||
@@ -123,94 +123,102 @@ async fn handle_login(
|
||||
|
||||
match (&config.core_public_key, &config.passkeys) {
|
||||
(Some(_), _) | (_, None) => {
|
||||
// Send login type [0] (Noise auth)
|
||||
handler
|
||||
.socket
|
||||
// Noise handshake auth: [0]
|
||||
.send(Bytes::from_owner([0]))
|
||||
.await
|
||||
.context("Failed to send login type indicator")?;
|
||||
handler.login::<ServerLoginFlow>().await
|
||||
}
|
||||
(None, Some(passkeys)) => {
|
||||
warn!(
|
||||
"Authenticating using Passkeys. Set 'core_public_key' (PERIPHERY_CORE_PUBLIC_KEY) instead to enhance security."
|
||||
);
|
||||
let res = async {
|
||||
// Send login type
|
||||
handler
|
||||
.socket
|
||||
// Passkey auth: [1]
|
||||
.send(Bytes::from_owner([1]))
|
||||
.await
|
||||
.context("Failed to send login type indicator")?;
|
||||
handle_passkey_login(handler, passkeys).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Receieve passkey
|
||||
let bytes = handler
|
||||
.socket
|
||||
.recv_bytes()
|
||||
.await
|
||||
.context("Failed to receive passkey from Core")?;
|
||||
let passkey = match MessageState::from_byte(
|
||||
*bytes.last().context("passkey message is empty")?,
|
||||
) {
|
||||
MessageState::Successful => &bytes[..(bytes.len() - 1)],
|
||||
_ => {
|
||||
return Err(deserialize_error_bytes(
|
||||
&bytes[..(bytes.len() - 1)],
|
||||
));
|
||||
}
|
||||
};
|
||||
async fn handle_passkey_login(
|
||||
handler: &mut WebsocketHandler<'_, AxumWebsocket>,
|
||||
passkeys: &[String],
|
||||
) -> anyhow::Result<()> {
|
||||
warn!(
|
||||
"Authenticating using Passkeys. Set 'core_public_key' (PERIPHERY_CORE_PUBLIC_KEY) instead to enhance security."
|
||||
);
|
||||
let res = async {
|
||||
// Send login type
|
||||
handler
|
||||
.socket
|
||||
// Passkey auth: [1]
|
||||
.send(Bytes::from_owner([1]))
|
||||
.await
|
||||
.context("Failed to send login type indicator")?;
|
||||
|
||||
if passkeys.iter().any(|expected_passkey| {
|
||||
expected_passkey.as_bytes() == passkey
|
||||
}) {
|
||||
handler
|
||||
.socket
|
||||
.send(MessageState::Successful.into())
|
||||
.await
|
||||
.context("Failed to send login type indicator")?;
|
||||
Ok(())
|
||||
} else {
|
||||
let e = anyhow!("Invalid passkey");
|
||||
let mut bytes = serialize_error_bytes(&e);
|
||||
bytes.push(MessageState::Failed.as_byte());
|
||||
if let Err(e) = handler
|
||||
.socket
|
||||
.send(bytes.into())
|
||||
.await
|
||||
.context("Failed to send login failed")
|
||||
{
|
||||
// Log additional error
|
||||
warn!("{e:#}");
|
||||
// Close socket
|
||||
let _ = handler.socket.close(None).await;
|
||||
}
|
||||
// Return the original error
|
||||
Err(e)
|
||||
}
|
||||
// Receieve passkey
|
||||
let bytes = handler
|
||||
.socket
|
||||
.recv_bytes()
|
||||
.await
|
||||
.context("Failed to receive passkey from Core")?;
|
||||
let passkey = match MessageState::from_byte(
|
||||
*bytes.last().context("passkey message is empty")?,
|
||||
) {
|
||||
MessageState::Successful => &bytes[..(bytes.len() - 1)],
|
||||
_ => {
|
||||
return Err(deserialize_error_bytes(
|
||||
&bytes[..(bytes.len() - 1)],
|
||||
));
|
||||
}
|
||||
.await;
|
||||
if let Err(e) = res {
|
||||
let mut bytes = serialize_error_bytes(&e);
|
||||
bytes.push(MessageState::Failed.as_byte());
|
||||
if let Err(e) = handler
|
||||
.socket
|
||||
.send(bytes.into())
|
||||
.await
|
||||
.context("Failed to send login failed to client")
|
||||
{
|
||||
// Log additional error
|
||||
warn!("{e:#}");
|
||||
}
|
||||
};
|
||||
|
||||
if passkeys
|
||||
.iter()
|
||||
.any(|expected_passkey| expected_passkey.as_bytes() == passkey)
|
||||
{
|
||||
handler
|
||||
.socket
|
||||
.send(MessageState::Successful.into())
|
||||
.await
|
||||
.context("Failed to send login type indicator")?;
|
||||
Ok(())
|
||||
} else {
|
||||
let e = anyhow!("Invalid passkey");
|
||||
let mut bytes = serialize_error_bytes(&e);
|
||||
bytes.push(MessageState::Failed.as_byte());
|
||||
if let Err(e) = handler
|
||||
.socket
|
||||
.send(bytes.into())
|
||||
.await
|
||||
.context("Failed to send login failed")
|
||||
{
|
||||
// Log additional error
|
||||
warn!("{e:#}");
|
||||
// Close socket
|
||||
let _ = handler.socket.close(None).await;
|
||||
// Return the original error
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
// Return the original error
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
.await;
|
||||
if let Err(e) = res {
|
||||
let mut bytes = serialize_error_bytes(&e);
|
||||
bytes.push(MessageState::Failed.as_byte());
|
||||
if let Err(e) = handler
|
||||
.socket
|
||||
.send(bytes.into())
|
||||
.await
|
||||
.context("Failed to send login failed to client")
|
||||
{
|
||||
// Log additional error
|
||||
warn!("{e:#}");
|
||||
}
|
||||
// Close socket
|
||||
let _ = handler.socket.close(None).await;
|
||||
// Return the original error
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn guard_request_by_ip(
|
||||
|
||||
Reference in New Issue
Block a user