add watch

This commit is contained in:
2026-05-13 00:41:26 +09:00
parent cde37d516b
commit 4e515ba964
13 changed files with 336 additions and 64 deletions

View File

@@ -1,8 +1,13 @@
use crate::state::AppState;
use anyhow::{anyhow, Result};
use argon2::password_hash::{PasswordHash, PasswordVerifier};
use argon2::Argon2;
use axum::extract::{Query, State};
use axum::http::StatusCode;
use serde::Deserialize;
use ssh_key::public::PublicKey;
use ssh_key::SshSig;
use std::sync::Arc;
pub fn verify_password(password: &str, hash: &str) -> bool {
let parsed = match PasswordHash::new(hash) {
@@ -27,3 +32,31 @@ pub fn find_key<'a>(keys: &'a [PublicKey], offered: &PublicKey) -> Option<&'a Pu
let fp = offered.fingerprint(Default::default());
keys.iter().find(|k| k.fingerprint(Default::default()) == fp)
}
#[derive(Deserialize)]
pub struct CheckAuthQuery {
s: String,
pw: Option<String>,
}
pub async fn check_auth_handler(
State(state): State<Arc<AppState>>,
Query(q): Query<CheckAuthQuery>,
) -> StatusCode {
let sessions = state.sessions.read().await;
let session = match sessions.get(&q.s) {
Some(s) => s.clone(),
None => return StatusCode::NOT_FOUND,
};
drop(sessions);
match &session.password_hash {
Some(hash) => {
if verify_password(&q.pw.unwrap_or_default(), hash) {
StatusCode::OK
} else {
StatusCode::UNAUTHORIZED
}
}
None => StatusCode::OK,
}
}

View File

@@ -28,22 +28,11 @@ else
fi
chmod +x "$TMP"
printf 'Password (empty for none): ' >&2
stty -echo </dev/tty 2>/dev/null || true
# Force read to use the actual terminal device
IFS= read -r PW < /dev/tty || PW=''
stty echo </dev/tty 2>/dev/null || true
echo >&2
"$TMP" auth --url "$WS" "$SESSION"
trap - EXIT
LOG="/tmp/rsh-${SESSION}.log"
if [ -n "$PW" ]; then
nohup "$TMP" --url "$WS/ws/stub" --session "$SESSION" --password "$PW" >"$LOG" 2>&1 &
else
nohup "$TMP" --url "$WS/ws/stub" --session "$SESSION" >"$LOG" 2>&1 &
fi
nohup "$TMP" stub --url "$WS/ws/stub" --session "$SESSION" >"$LOG" 2>&1 &
disown 2>/dev/null || true
printf 'rsh: stub running in background (pid %s, log: %s)\n' "$!" "$LOG" >&2
"#;

View File

@@ -53,6 +53,7 @@ async fn main() -> anyhow::Result<()> {
.route("/run.sh", get(dist::run_sh))
.route("/rsh/:arch", get(dist::stub))
.route("/healthz", get(|| async { "ok" }))
.route("/check-auth", get(auth::check_auth_handler))
.route("/ws/stub", get(ws_stub::handler))
.route("/ws/op", get(ws_op::handler))
.with_state(state.clone())