Add bad logon function
This commit is contained in:
parent
e64e563e11
commit
d92b6f2bac
29
lib/examples/login_steamguard_new.rs
Normal file
29
lib/examples/login_steamguard_new.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use color_eyre::eyre::{self};
|
||||
use vapore::client::SteamClient;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() -> eyre::Result<()> {
|
||||
env_logger::init();
|
||||
color_eyre::install()?;
|
||||
|
||||
let servers = vapore::selection::bootstrap_find_servers().await?;
|
||||
log::debug!("Found servers: {:?}", servers);
|
||||
|
||||
let client = SteamClient::connect(&servers).await?;
|
||||
|
||||
let username = dialoguer::Input::<String>::new()
|
||||
.with_prompt("Username")
|
||||
.interact_text()?;
|
||||
let password = dialoguer::Password::new()
|
||||
.with_prompt("Password")
|
||||
.interact()?;
|
||||
let guard_code = dialoguer::Input::<String>::new()
|
||||
.with_prompt("Steam Guard Code")
|
||||
.interact_text()?;
|
||||
|
||||
client
|
||||
.auth_password(username, password, Some(guard_code))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use base64::Engine as _;
|
||||
use base64::{prelude::BASE64_STANDARD, Engine as _};
|
||||
use snafu::prelude::*;
|
||||
use vapore_proto::{
|
||||
enums::ESessionPersistence,
|
||||
|
@ -9,14 +9,22 @@ use vapore_proto::{
|
|||
CAuthentication_BeginAuthSessionViaCredentials_Request,
|
||||
CAuthentication_BeginAuthSessionViaCredentials_Response, CAuthentication_DeviceDetails,
|
||||
CAuthentication_GetPasswordRSAPublicKey_Request,
|
||||
CAuthentication_GetPasswordRSAPublicKey_Response, EAuthTokenPlatformType,
|
||||
CAuthentication_GetPasswordRSAPublicKey_Response,
|
||||
CAuthentication_PollAuthSessionStatus_Request,
|
||||
CAuthentication_PollAuthSessionStatus_Response,
|
||||
CAuthentication_UpdateAuthSessionWithSteamGuardCode_Request,
|
||||
CAuthentication_UpdateAuthSessionWithSteamGuardCode_Response, EAuthSessionGuardType,
|
||||
EAuthTokenPlatformType,
|
||||
},
|
||||
steammessages_clientserver_login::CMsgClientHello,
|
||||
steammessages_base::{cmsg_ipaddress, CMsgIPAddress},
|
||||
steammessages_clientserver_login::{CMsgClientHello, CMsgClientLogon, CMsgClientLogonResponse},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
connection::CMSession,
|
||||
error::{RSAEncryptSnafu, RSAParameterParseSnafu, RSAParseSnafu},
|
||||
error::{
|
||||
ListenRecvSnafu, MissingFieldSnafu, RSAEncryptSnafu, RSAParameterParseSnafu, RSAParseSnafu,
|
||||
},
|
||||
message::CMProtoBufMessage,
|
||||
platform::generate_machine_id,
|
||||
state::apps::AppsHandler,
|
||||
|
@ -41,8 +49,8 @@ pub struct SteamClient {
|
|||
}
|
||||
|
||||
impl SteamClient {
|
||||
pub async fn connect(servers: &[&str]) -> Result<Self, ClientError> {
|
||||
let (session, context) = CMSession::connect(servers[0]).await?;
|
||||
pub async fn connect(servers: &[String]) -> Result<Self, ClientError> {
|
||||
let (session, context) = CMSession::connect(&servers[0]).await?;
|
||||
|
||||
let inner = Arc::new(SteamClientInner {
|
||||
apps: AppsHandler::listen(&session),
|
||||
|
@ -84,6 +92,8 @@ impl SteamClient {
|
|||
)
|
||||
.await?;
|
||||
|
||||
password_key_response.ok()?;
|
||||
|
||||
let password_key = rsa::RsaPublicKey::new(
|
||||
rsa::BigUint::parse_bytes(password_key_response.body.publickey_mod().as_bytes(), 16)
|
||||
.context(RSAParameterParseSnafu {})?,
|
||||
|
@ -107,13 +117,9 @@ impl SteamClient {
|
|||
"Authentication.BeginAuthSessionViaCredentials#1".to_string(),
|
||||
CAuthentication_BeginAuthSessionViaCredentials_Request {
|
||||
account_name: Some(username.clone()),
|
||||
encrypted_password: Some(
|
||||
base64::engine::general_purpose::STANDARD.encode(&encrypted_password),
|
||||
),
|
||||
encrypted_password: Some(BASE64_STANDARD.encode(&encrypted_password)),
|
||||
encryption_timestamp: password_key_response.body.timestamp,
|
||||
persistence: Some(protobuf::EnumOrUnknown::new(
|
||||
ESessionPersistence::k_ESessionPersistence_Ephemeral,
|
||||
)),
|
||||
persistence: Some(ESessionPersistence::k_ESessionPersistence_Ephemeral.into()),
|
||||
device_details: protobuf::MessageField::some(CAuthentication_DeviceDetails {
|
||||
device_friendly_name: Some("vapore".to_string()),
|
||||
platform_type: Some(protobuf::EnumOrUnknown::new(
|
||||
|
@ -128,6 +134,122 @@ impl SteamClient {
|
|||
},
|
||||
)
|
||||
.await?;
|
||||
log::debug!("Got auth response {:#x?}", auth_session_response);
|
||||
auth_session_response.ok()?;
|
||||
|
||||
let confirmation_type = auth_session_response
|
||||
.body
|
||||
.allowed_confirmations
|
||||
.first()
|
||||
.unwrap_or_default()
|
||||
.confirmation_type();
|
||||
|
||||
if confirmation_type == EAuthSessionGuardType::k_EAuthSessionGuardType_Unknown {
|
||||
return Err(ClientError::NoAllowedConfirmations);
|
||||
} else if confirmation_type == EAuthSessionGuardType::k_EAuthSessionGuardType_None {
|
||||
// No required confirmation, we can go directly to login
|
||||
} else if confirmation_type == EAuthSessionGuardType::k_EAuthSessionGuardType_EmailCode
|
||||
|| confirmation_type == EAuthSessionGuardType::k_EAuthSessionGuardType_DeviceCode
|
||||
{
|
||||
let update_response: CMProtoBufMessage<
|
||||
CAuthentication_UpdateAuthSessionWithSteamGuardCode_Response,
|
||||
> = self
|
||||
.inner
|
||||
.session
|
||||
.call_service_method(
|
||||
"Authentication.UpdateAuthSessionWithSteamGuardCode#1".to_string(),
|
||||
CAuthentication_UpdateAuthSessionWithSteamGuardCode_Request {
|
||||
client_id: auth_session_response.body.client_id,
|
||||
steamid: auth_session_response.body.steamid,
|
||||
code,
|
||||
code_type: Some(confirmation_type.into()),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
update_response.ok()?;
|
||||
} else {
|
||||
return Err(ClientError::UnsupportedConfirmation {
|
||||
typ: confirmation_type,
|
||||
});
|
||||
}
|
||||
|
||||
let poll_response: CMProtoBufMessage<CAuthentication_PollAuthSessionStatus_Response> = self
|
||||
.inner
|
||||
.session
|
||||
.call_service_method(
|
||||
"Authentication.PollAuthSessionStatus#1".to_string(),
|
||||
CAuthentication_PollAuthSessionStatus_Request {
|
||||
client_id: auth_session_response.body.client_id,
|
||||
request_id: auth_session_response.body.request_id.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
poll_response.ok()?;
|
||||
log::debug!("Got poll response: {:#?}", poll_response);
|
||||
|
||||
let mut logon_receiver = self
|
||||
.inner
|
||||
.session
|
||||
.subscribe_message_type(EMsg::k_EMsgClientLogOnResponse);
|
||||
|
||||
let account_name = poll_response.body.account_name.context(MissingFieldSnafu {
|
||||
field: "account_name",
|
||||
})?;
|
||||
let refresh_token = poll_response
|
||||
.body
|
||||
.refresh_token
|
||||
.context(MissingFieldSnafu {
|
||||
field: "refresh_token",
|
||||
})?;
|
||||
|
||||
log::debug!(
|
||||
"Got account name {}, access token {}",
|
||||
account_name,
|
||||
refresh_token
|
||||
);
|
||||
|
||||
// normal user, desktop instance, public universe
|
||||
self.inner.session.set_steam_id(0x0110_0001_0000_0000);
|
||||
|
||||
self.inner.session.send_notification(
|
||||
EMsg::k_EMsgClientLogon,
|
||||
CMsgClientLogon {
|
||||
account_name: Some(account_name),
|
||||
access_token: Some(refresh_token),
|
||||
machine_name: Some("vapore".to_string()),
|
||||
machine_id: Some(machine_id),
|
||||
client_language: Some("english".to_string()),
|
||||
protocol_version: Some(0x1002c),
|
||||
client_os_type: Some(20),
|
||||
client_package_version: Some(1771),
|
||||
supports_rate_limit_response: Some(true),
|
||||
should_remember_password: Some(true),
|
||||
obfuscated_private_ip: protobuf::MessageField::some(CMsgIPAddress {
|
||||
ip: Some(cmsg_ipaddress::Ip::V4(0xc0a8_0102 ^ 0xbaad_f00d)),
|
||||
..Default::default()
|
||||
}),
|
||||
deprecated_obfustucated_private_ip: Some(0xc0a8_0102 ^ 0xbaad_f00d),
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
||||
let raw_logon = logon_receiver.recv().await.context(ListenRecvSnafu {})?;
|
||||
let logon: CMProtoBufMessage<CMsgClientLogonResponse> =
|
||||
CMProtoBufMessage::deserialize(raw_logon)?;
|
||||
|
||||
self.inner.session.set_steam_id(logon.header.steamid());
|
||||
self.inner
|
||||
.session
|
||||
.set_client_session_id(logon.header.client_sessionid());
|
||||
|
||||
if let Some(heartbeat_seconds) = logon.body.heartbeat_seconds {
|
||||
if heartbeat_seconds >= 5 {
|
||||
self.inner.session.begin_heartbeat(heartbeat_seconds as u32);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use snafu::prelude::*;
|
||||
use vapore_proto::steammessages_auth_steamclient::EAuthSessionGuardType;
|
||||
use vapore_struct::eresult::EResult;
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
|
@ -38,6 +39,9 @@ pub enum ClientError {
|
|||
#[snafu(display("Protobuf Serialization error"))]
|
||||
ProtobufSer { source: protobuf::Error },
|
||||
|
||||
#[snafu(display("Struct Missing Field `{field}`"))]
|
||||
MissingField { field: &'static str },
|
||||
|
||||
#[snafu(display("Invalid WebSocket message type from server"))]
|
||||
BadWSMessageType,
|
||||
|
||||
|
@ -77,6 +81,17 @@ pub enum ClientError {
|
|||
|
||||
#[snafu(display("Unable to encrupt with RSA"))]
|
||||
RSAEncrypt { source: rsa::Error },
|
||||
|
||||
#[snafu(display("Unsupported Confirmation type {typ:?}"))]
|
||||
UnsupportedConfirmation { typ: EAuthSessionGuardType },
|
||||
|
||||
#[snafu(display("No allowed confirmations"))]
|
||||
NoAllowedConfirmations,
|
||||
|
||||
#[snafu(display("Unable to fetch messages from listen thread"))]
|
||||
ListenRecv {
|
||||
source: tokio::sync::broadcast::error::RecvError,
|
||||
},
|
||||
}
|
||||
|
||||
impl<T> From<std::sync::PoisonError<T>> for ClientError {
|
||||
|
|
Loading…
Reference in a new issue