This commit is contained in:
parent
993a419793
commit
66e39b62a2
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3040,6 +3040,7 @@ dependencies = [
|
|||||||
"android_logger",
|
"android_logger",
|
||||||
"arboard",
|
"arboard",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"base64",
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -42,6 +42,7 @@ crc32fast = "1.3"
|
|||||||
uuid = { version = "0.8", features = ["v4"] }
|
uuid = { version = "0.8", features = ["v4"] }
|
||||||
clap = "2.34"
|
clap = "2.34"
|
||||||
rpassword = "5.0"
|
rpassword = "5.0"
|
||||||
|
base64 = "0.13"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android")))'.dependencies]
|
||||||
cpal = { git = "https://github.com/open-trade/cpal" }
|
cpal = { git = "https://github.com/open-trade/cpal" }
|
||||||
|
@ -359,7 +359,6 @@ message PublicKey {
|
|||||||
|
|
||||||
message SignedId {
|
message SignedId {
|
||||||
bytes id = 1;
|
bytes id = 1;
|
||||||
bytes pk = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message AudioFormat {
|
message AudioFormat {
|
||||||
|
@ -297,28 +297,51 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn secure_connection(peer_id: &str, pk: Vec<u8>, conn: &mut Stream) -> ResultType<()> {
|
async fn secure_connection(peer_id: &str, pk: Vec<u8>, conn: &mut Stream) -> ResultType<()> {
|
||||||
|
let mut pk = pk;
|
||||||
|
const RS_PK: &[u8; 32] = &[
|
||||||
|
177, 155, 15, 73, 116, 147, 172, 11, 55, 38, 92, 168, 30, 116, 213, 196, 12, 134, 130,
|
||||||
|
170, 181, 161, 192, 176, 132, 229, 139, 178, 17, 165, 150, 51,
|
||||||
|
];
|
||||||
|
if !pk.is_empty() {
|
||||||
|
let tmp = sign::PublicKey(*RS_PK);
|
||||||
|
if let Ok(data) = sign::verify(&pk, &tmp) {
|
||||||
|
pk = data;
|
||||||
|
} else {
|
||||||
|
log::error!("Handshake failed: invalid public key from rendezvous server");
|
||||||
|
pk.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
if pk.len() != sign::PUBLICKEYBYTES {
|
if pk.len() != sign::PUBLICKEYBYTES {
|
||||||
// send an empty message out in case server is setting up secure and waiting for first message
|
// send an empty message out in case server is setting up secure and waiting for first message
|
||||||
conn.send(&Message::new()).await?;
|
conn.send(&Message::new()).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let mut pk_ = [0u8; sign::PUBLICKEYBYTES];
|
let mut tmp = [0u8; sign::PUBLICKEYBYTES];
|
||||||
pk_[..].copy_from_slice(&pk);
|
tmp[..].copy_from_slice(&pk);
|
||||||
let pk = sign::PublicKey(pk_);
|
let sign_pk = sign::PublicKey(tmp);
|
||||||
match timeout(CONNECT_TIMEOUT, conn.next()).await? {
|
match timeout(CONNECT_TIMEOUT, conn.next()).await? {
|
||||||
Some(res) => {
|
Some(res) => {
|
||||||
let bytes = res?;
|
let bytes = res?;
|
||||||
if let Ok(msg_in) = Message::parse_from_bytes(&bytes) {
|
if let Ok(msg_in) = Message::parse_from_bytes(&bytes) {
|
||||||
if let Some(message::Union::signed_id(si)) = msg_in.union {
|
if let Some(message::Union::signed_id(si)) = msg_in.union {
|
||||||
let their_pk_b = if si.pk.len() == box_::PUBLICKEYBYTES {
|
if let Ok(data) = sign::verify(&si.id, &sign_pk) {
|
||||||
let mut pk_ = [0u8; box_::PUBLICKEYBYTES];
|
let s = String::from_utf8_lossy(&data);
|
||||||
pk_[..].copy_from_slice(&si.pk);
|
let mut it = s.split("\0");
|
||||||
box_::PublicKey(pk_)
|
let id = it.next().unwrap_or_default();
|
||||||
} else {
|
let pk =
|
||||||
bail!("Handshake failed: invalid public box key length from peer");
|
base64::decode(it.next().unwrap_or_default()).unwrap_or_default();
|
||||||
};
|
let their_pk_b = if pk.len() == box_::PUBLICKEYBYTES {
|
||||||
if let Ok(id) = sign::verify(&si.id, &pk) {
|
let mut pk_ = [0u8; box_::PUBLICKEYBYTES];
|
||||||
if id == peer_id.as_bytes() {
|
pk_[..].copy_from_slice(&pk);
|
||||||
|
box_::PublicKey(pk_)
|
||||||
|
} else {
|
||||||
|
log::error!(
|
||||||
|
"Handshake failed: invalid public box key length from peer"
|
||||||
|
);
|
||||||
|
conn.send(&Message::new()).await?;
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
if id == peer_id {
|
||||||
let (our_pk_b, out_sk_b) = box_::gen_keypair();
|
let (our_pk_b, out_sk_b) = box_::gen_keypair();
|
||||||
let key = secretbox::gen_key();
|
let key = secretbox::gen_key();
|
||||||
let nonce = box_::Nonce([0u8; box_::NONCEBYTES]);
|
let nonce = box_::Nonce([0u8; box_::NONCEBYTES]);
|
||||||
@ -332,7 +355,8 @@ impl Client {
|
|||||||
timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??;
|
timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??;
|
||||||
conn.set_key(key);
|
conn.set_key(key);
|
||||||
} else {
|
} else {
|
||||||
bail!("Handshake failed: sign failure");
|
log::error!("Handshake failed: sign failure");
|
||||||
|
conn.send(&Message::new()).await?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// fall back to non-secure connection in case pk mismatch
|
// fall back to non-secure connection in case pk mismatch
|
||||||
@ -342,10 +366,12 @@ impl Client {
|
|||||||
timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??;
|
timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bail!("Handshake failed: invalid message type");
|
log::error!("Handshake failed: invalid message type");
|
||||||
|
conn.send(&Message::new()).await?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bail!("Handshake failed: invalid message format");
|
log::error!("Handshake failed: invalid message format");
|
||||||
|
conn.send(&Message::new()).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::ipc::Data;
|
use crate::ipc::Data;
|
||||||
use connection::{ConnInner, Connection};
|
pub use connection::*;
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err,
|
allow_err,
|
||||||
anyhow::{anyhow, Context},
|
anyhow::{anyhow, Context},
|
||||||
@ -69,12 +69,12 @@ async fn accept_connection_(server: ServerPtr, socket: Stream, secure: bool) ->
|
|||||||
let listener = new_listener(local_addr, true).await?;
|
let listener = new_listener(local_addr, true).await?;
|
||||||
log::info!("Server listening on: {}", &listener.local_addr()?);
|
log::info!("Server listening on: {}", &listener.local_addr()?);
|
||||||
if let Ok((stream, addr)) = timeout(CONNECT_TIMEOUT, listener.accept()).await? {
|
if let Ok((stream, addr)) = timeout(CONNECT_TIMEOUT, listener.accept()).await? {
|
||||||
create_tcp_connection_(server, Stream::from(stream), addr, secure).await?;
|
create_tcp_connection(server, Stream::from(stream), addr, secure).await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tcp_connection_(
|
pub async fn create_tcp_connection(
|
||||||
server: ServerPtr,
|
server: ServerPtr,
|
||||||
stream: Stream,
|
stream: Stream,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
@ -92,11 +92,13 @@ async fn create_tcp_connection_(
|
|||||||
sk_[..].copy_from_slice(&sk);
|
sk_[..].copy_from_slice(&sk);
|
||||||
let sk = sign::SecretKey(sk_);
|
let sk = sign::SecretKey(sk_);
|
||||||
let mut msg_out = Message::new();
|
let mut msg_out = Message::new();
|
||||||
let signed_id = sign::sign(Config::get_id().as_bytes(), &sk);
|
|
||||||
let (our_pk_b, our_sk_b) = box_::gen_keypair();
|
let (our_pk_b, our_sk_b) = box_::gen_keypair();
|
||||||
|
let signed_id = sign::sign(
|
||||||
|
format!("{}\0{}", Config::get_id(), base64::encode(our_pk_b.0)).as_bytes(),
|
||||||
|
&sk,
|
||||||
|
);
|
||||||
msg_out.set_signed_id(SignedId {
|
msg_out.set_signed_id(SignedId {
|
||||||
id: signed_id,
|
id: signed_id,
|
||||||
pk: our_pk_b.0.into(),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
timeout(CONNECT_TIMEOUT, stream.send(&msg_out)).await??;
|
timeout(CONNECT_TIMEOUT, stream.send(&msg_out)).await??;
|
||||||
@ -122,8 +124,8 @@ async fn create_tcp_connection_(
|
|||||||
key[..].copy_from_slice(&symmetric_key);
|
key[..].copy_from_slice(&symmetric_key);
|
||||||
stream.set_key(secretbox::Key(key));
|
stream.set_key(secretbox::Key(key));
|
||||||
} else if pk.asymmetric_value.is_empty() {
|
} else if pk.asymmetric_value.is_empty() {
|
||||||
// force a trial to update_pk to rendezvous server
|
|
||||||
Config::set_key_confirmed(false);
|
Config::set_key_confirmed(false);
|
||||||
|
log::info!("Force to update pk");
|
||||||
} else {
|
} else {
|
||||||
bail!("Handshake failed: invalid public sign key length from peer");
|
bail!("Handshake failed: invalid public sign key length from peer");
|
||||||
}
|
}
|
||||||
@ -193,7 +195,7 @@ async fn create_relay_connection_(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
stream.send(&msg_out).await?;
|
stream.send(&msg_out).await?;
|
||||||
create_tcp_connection_(server, stream, peer_addr, secure).await?;
|
create_tcp_connection(server, stream, peer_addr, secure).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user