diff --git a/adb_client/src/device/adb_message_device.rs b/adb_client/src/device/adb_message_device.rs index 6964f8c..8f9c67a 100644 --- a/adb_client/src/device/adb_message_device.rs +++ b/adb_client/src/device/adb_message_device.rs @@ -1,10 +1,10 @@ +use super::{ADBRsaKey, ADBTransportMessage, MessageCommand, models::MessageSubcommand}; +use crate::device::adb_transport_message::{AUTH_RSAPUBLICKEY, AUTH_SIGNATURE, AUTH_TOKEN}; +use crate::{ADBMessageTransport, AdbStatResponse, Result, RustADBError, constants::BUFFER_SIZE}; use byteorder::{LittleEndian, ReadBytesExt}; use rand::Rng; use std::io::{Cursor, Read, Seek}; - -use crate::{ADBMessageTransport, AdbStatResponse, Result, RustADBError, constants::BUFFER_SIZE}; - -use super::{ADBTransportMessage, MessageCommand, models::MessageSubcommand}; +use std::time::Duration; /// Generic structure representing an ADB device reachable over an [`ADBMessageTransport`]. /// Structure is totally agnostic over which transport is truly used. @@ -33,6 +33,66 @@ impl ADBMessageDevice { &mut self.transport } + pub(crate) fn auth_handshake( + &mut self, + message: ADBTransportMessage, + private_key: &ADBRsaKey, + ) -> Result<()> { + match message.header().command() { + MessageCommand::Auth => { + log::debug!("Authentication required"); + } + _ => return Ok(()), + } + + // At this point, we should have received an AUTH message with arg0 == 1 + let auth_message = match message.header().arg0() { + AUTH_TOKEN => message, + v => { + return Err(RustADBError::ADBRequestFailed(format!( + "Received AUTH message with type != 1 ({v})" + ))); + } + }; + + let sign = private_key.sign(auth_message.into_payload())?; + + let message = ADBTransportMessage::new(MessageCommand::Auth, AUTH_SIGNATURE, 0, &sign); + + self.get_transport_mut().write_message(message)?; + + let received_response = self.get_transport_mut().read_message()?; + + if received_response.header().command() == MessageCommand::Cnxn { + log::info!( + "Authentication OK, device info {}", + String::from_utf8(received_response.into_payload())? + ); + return Ok(()); + } + + let mut pubkey = private_key.android_pubkey_encode()?.into_bytes(); + pubkey.push(b'\0'); + + let message = ADBTransportMessage::new(MessageCommand::Auth, AUTH_RSAPUBLICKEY, 0, &pubkey); + + self.get_transport_mut().write_message(message)?; + + let response = self + .get_transport_mut() + .read_message_with_timeout(Duration::from_secs(10)) + .and_then(|message| { + message.assert_command(MessageCommand::Cnxn)?; + Ok(message) + })?; + + log::info!( + "Authentication OK, device info {}", + String::from_utf8(response.into_payload())? + ); + Ok(()) + } + /// Receive a message and acknowledge it by replying with an `OKAY` command pub(crate) fn recv_and_reply_okay(&mut self) -> Result { let message = self.transport.read_message()?; diff --git a/adb_client/src/device/adb_tcp_device.rs b/adb_client/src/device/adb_tcp_device.rs index fe18b7c..1b15183 100644 --- a/adb_client/src/device/adb_tcp_device.rs +++ b/adb_client/src/device/adb_tcp_device.rs @@ -1,14 +1,12 @@ use std::io::Write; use std::path::{Path, PathBuf}; -use std::time::Duration; use std::{io::Read, net::SocketAddr}; use super::adb_message_device::ADBMessageDevice; use super::models::MessageCommand; use super::{ADBRsaKey, ADBTransportMessage, get_default_adb_key_path}; -use crate::device::adb_transport_message::{AUTH_RSAPUBLICKEY, AUTH_SIGNATURE, AUTH_TOKEN}; use crate::device::adb_usb_device::read_adb_private_key; -use crate::{ADBDeviceExt, ADBMessageTransport, ADBTransport, Result, RustADBError, TcpTransport}; +use crate::{ADBDeviceExt, ADBMessageTransport, ADBTransport, Result, TcpTransport}; /// Represent a device reached and available over USB. #[derive(Debug)] @@ -78,6 +76,7 @@ impl ADBTcpDevice { } MessageCommand::Auth => { log::debug!("Authentication required"); + return self.inner.auth_handshake(message, &self.private_key); } _ => { return Err(crate::RustADBError::WrongResponseReceived( @@ -86,54 +85,6 @@ impl ADBTcpDevice { )); } } - - // At this point, we should have receive an AUTH message with arg0 == 1 - let auth_message = match message.header().arg0() { - AUTH_TOKEN => message, - v => { - return Err(RustADBError::ADBRequestFailed(format!( - "Received AUTH message with type != 1 ({v})" - ))); - } - }; - - let sign = self.private_key.sign(auth_message.into_payload())?; - - let message = ADBTransportMessage::new(MessageCommand::Auth, AUTH_SIGNATURE, 0, &sign); - - self.get_transport_mut().write_message(message)?; - - let received_response = self.get_transport_mut().read_message()?; - - if received_response.header().command() == MessageCommand::Cnxn { - log::info!( - "Authentication OK, device info {}", - String::from_utf8(received_response.into_payload())? - ); - return Ok(()); - } - - let mut pubkey = self.private_key.android_pubkey_encode()?.into_bytes(); - pubkey.push(b'\0'); - - let message = ADBTransportMessage::new(MessageCommand::Auth, AUTH_RSAPUBLICKEY, 0, &pubkey); - - self.get_transport_mut().write_message(message)?; - - let response = self - .get_transport_mut() - .read_message_with_timeout(Duration::from_secs(10)) - .and_then(|message| { - message.assert_command(MessageCommand::Cnxn)?; - Ok(message) - })?; - - log::info!( - "Authentication OK, device info {}", - String::from_utf8(response.into_payload())? - ); - - Ok(()) } #[inline] diff --git a/adb_client/src/device/adb_usb_device.rs b/adb_client/src/device/adb_usb_device.rs index 83ee812..c4b1099 100644 --- a/adb_client/src/device/adb_usb_device.rs +++ b/adb_client/src/device/adb_usb_device.rs @@ -7,7 +7,6 @@ use std::io::Read; use std::io::Write; use std::path::Path; use std::path::PathBuf; -use std::time::Duration; use super::adb_message_device::ADBMessageDevice; use super::models::MessageCommand; @@ -15,7 +14,6 @@ use super::{ADBRsaKey, ADBTransportMessage}; use crate::ADBDeviceExt; use crate::ADBMessageTransport; use crate::ADBTransport; -use crate::device::adb_transport_message::{AUTH_RSAPUBLICKEY, AUTH_SIGNATURE, AUTH_TOKEN}; use crate::{Result, RustADBError, USBTransport}; pub fn read_adb_private_key>(private_key_path: P) -> Result> { @@ -195,55 +193,9 @@ impl ADBUSBDevice { if message.header().command() == MessageCommand::Cnxn { return Ok(()); } + message.assert_command(MessageCommand::Auth)?; - - // At this point, we should have receive an AUTH message with arg0 == 1 - let auth_message = match message.header().arg0() { - AUTH_TOKEN => message, - v => { - return Err(RustADBError::ADBRequestFailed(format!( - "Received AUTH message with type != 1 ({v})" - ))); - } - }; - - let sign = self.private_key.sign(auth_message.into_payload())?; - - let message = ADBTransportMessage::new(MessageCommand::Auth, AUTH_SIGNATURE, 0, &sign); - - self.get_transport_mut().write_message(message)?; - - let received_response = self.get_transport_mut().read_message()?; - - if received_response.header().command() == MessageCommand::Cnxn { - log::info!( - "Authentication OK, device info {}", - String::from_utf8(received_response.into_payload())? - ); - return Ok(()); - } - - let mut pubkey = self.private_key.android_pubkey_encode()?.into_bytes(); - pubkey.push(b'\0'); - - let message = ADBTransportMessage::new(MessageCommand::Auth, AUTH_RSAPUBLICKEY, 0, &pubkey); - - self.get_transport_mut().write_message(message)?; - - let response = self - .get_transport_mut() - .read_message_with_timeout(Duration::from_secs(10)) - .and_then(|message| { - message.assert_command(MessageCommand::Cnxn)?; - Ok(message) - })?; - - log::info!( - "Authentication OK, device info {}", - String::from_utf8(response.into_payload())? - ); - - Ok(()) + self.inner.auth_handshake(message, &self.private_key) } #[inline]