Copy stdin/stdout while waiting for sync
This should allow password authentication on ssh connect
This commit is contained in:
parent
7f8e14384e
commit
d4a8b041dd
1 changed files with 36 additions and 21 deletions
39
src/lib.rs
39
src/lib.rs
|
|
@ -161,22 +161,38 @@ async fn server_main<Reader: AsyncRead + Unpin, Writer: AsyncWrite + Unpin>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn client_sync<T: AsyncRead + Unpin>(reader: &mut T) -> Result<()> {
|
async fn client_sync<Read: AsyncRead + Unpin, Write: AsyncWrite + Unpin>(
|
||||||
// TODO: While we're waiting here we should be echoing everything we read.
|
reader: &mut Read,
|
||||||
// We should also be proxying *our* stdin to the processes stdin,
|
writer: &mut Write,
|
||||||
// and turn that off when we've synchronized. That way we can
|
) -> Result<(), tokio::io::Error> {
|
||||||
// handle passwords and the like for authentication.
|
|
||||||
eprintln!("> Waiting for synchronization marker...");
|
eprintln!("> Waiting for synchronization marker...");
|
||||||
|
|
||||||
|
// Run these two loops in parallel; the copy of stdin should stop when
|
||||||
|
// we've seen the marker from the client. If the pipe closes for whatever
|
||||||
|
// reason then obviously we quit.
|
||||||
|
let mut stdout = tokio::io::stdout();
|
||||||
|
tokio::select! {
|
||||||
|
result = async {
|
||||||
|
let mut stdin = tokio::io::stdin();
|
||||||
|
tokio::io::copy(&mut stdin, writer).await
|
||||||
|
} => match result {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
},
|
||||||
|
result = async {
|
||||||
let mut seen = 0;
|
let mut seen = 0;
|
||||||
while seen < 8 {
|
while seen < 8 {
|
||||||
let byte = reader.read_u8().await?;
|
let byte = reader.read_u8().await?;
|
||||||
if byte == 0 {
|
if byte == 0 {
|
||||||
seen += 1;
|
seen += 1;
|
||||||
} else {
|
} else {
|
||||||
tokio::io::stdout().write_u8(byte).await?;
|
stdout.write_u8(byte).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
|
Ok::<_, tokio::io::Error>(())
|
||||||
|
} => result,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn client_handle_connection(
|
async fn client_handle_connection(
|
||||||
|
|
@ -388,12 +404,10 @@ pub async fn run_client(remote: &str) {
|
||||||
// TODO: Drive a reconnect loop
|
// TODO: Drive a reconnect loop
|
||||||
let mut child = spawn_ssh(remote).await.expect("failed to spawn");
|
let mut child = spawn_ssh(remote).await.expect("failed to spawn");
|
||||||
|
|
||||||
let mut writer = MessageWriter::new(BufWriter::new(
|
let mut writer = child
|
||||||
child
|
|
||||||
.stdin
|
.stdin
|
||||||
.take()
|
.take()
|
||||||
.expect("child did not have a handle to stdout"),
|
.expect("child did not have a handle to stdin");
|
||||||
));
|
|
||||||
|
|
||||||
let mut reader = BufReader::new(
|
let mut reader = BufReader::new(
|
||||||
child
|
child
|
||||||
|
|
@ -402,11 +416,12 @@ pub async fn run_client(remote: &str) {
|
||||||
.expect("child did not have a handle to stdout"),
|
.expect("child did not have a handle to stdout"),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = client_sync(&mut reader).await {
|
if let Err(e) = client_sync(&mut reader, &mut writer).await {
|
||||||
eprintln!("Error synchronizing: {:?}", e);
|
eprintln!("Error synchronizing: {:?}", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut writer = MessageWriter::new(BufWriter::new(writer));
|
||||||
let mut reader = MessageReader::new(reader);
|
let mut reader = MessageReader::new(reader);
|
||||||
if let Err(e) = client_main(&mut reader, &mut writer).await {
|
if let Err(e) = client_main(&mut reader, &mut writer).await {
|
||||||
eprintln!("Error: {:?}", e);
|
eprintln!("Error: {:?}", e);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue