well, steam gives me an auth token now
This commit is contained in:
parent
6e2eb1aea0
commit
2331c7ecf1
79
Cargo.lock
generated
79
Cargo.lock
generated
|
@ -17,6 +17,12 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler2"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
@ -114,7 +120,7 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"miniz_oxide",
|
"miniz_oxide 0.7.4",
|
||||||
"object",
|
"object",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
]
|
]
|
||||||
|
@ -146,12 +152,24 @@ version = "3.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder-lite"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
|
@ -231,6 +249,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -328,6 +355,16 @@ version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"miniz_oxide 0.8.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -599,6 +636,17 @@ dependencies = [
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "image"
|
||||||
|
version = "0.25.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
"byteorder-lite",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indenter"
|
name = "indenter"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -709,6 +757,15 @@ dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
|
||||||
|
dependencies = [
|
||||||
|
"adler2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
@ -721,6 +778,15 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.32.2"
|
version = "0.32.2"
|
||||||
|
@ -897,6 +963,15 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "qrcode"
|
||||||
|
version = "0.14.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d68782463e408eb1e668cf6152704bd856c78c5b6417adaee3203d8f4c1fc9ec"
|
||||||
|
dependencies = [
|
||||||
|
"image",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quinn"
|
name = "quinn"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
|
@ -1617,11 +1692,13 @@ dependencies = [
|
||||||
"async-tungstenite",
|
"async-tungstenite",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"flate2",
|
||||||
"futures",
|
"futures",
|
||||||
"hex",
|
"hex",
|
||||||
"keyvalues-serde",
|
"keyvalues-serde",
|
||||||
"log",
|
"log",
|
||||||
"protobuf",
|
"protobuf",
|
||||||
|
"qrcode",
|
||||||
"rand",
|
"rand",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -7,13 +7,15 @@ version.workspace = true
|
||||||
async-tungstenite = { version = "0.27.0", features = ["tokio-rustls-native-certs"] }
|
async-tungstenite = { version = "0.27.0", features = ["tokio-rustls-native-certs"] }
|
||||||
color-eyre.workspace = true
|
color-eyre.workspace = true
|
||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
|
flate2 = "1.0.33"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
keyvalues-serde.workspace = true
|
keyvalues-serde.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
protobuf.workspace = true
|
protobuf.workspace = true
|
||||||
|
qrcode = "0.14.1"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
reqwest = { version = "0.12", features = ["rustls-tls-native-roots"], default-features = false}
|
reqwest = { version = "0.12", features = ["rustls-tls-native-roots"], default-features = false}
|
||||||
serde = { version = "1.0.209", features = ["derive"] }
|
serde = { version = "1.0.209", features = ["derive"] }
|
||||||
tokio = { version = "1.39", features = ["rt", "rt-multi-thread", "macros"]}
|
tokio = { version = "1.39", features = ["rt", "rt-multi-thread", "macros", "time"]}
|
||||||
vapore-proto.path = "../proto"
|
vapore-proto.path = "../proto"
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use core::time;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, HashMap, VecDeque},
|
collections::{BTreeMap, HashMap, VecDeque},
|
||||||
future::Future,
|
future::Future,
|
||||||
|
@ -16,7 +17,10 @@ use color_eyre::eyre::{self, bail, OptionExt};
|
||||||
use futures::{SinkExt as _, StreamExt};
|
use futures::{SinkExt as _, StreamExt};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
use vapore_proto::{enums_clientserver::EMsg, steammessages_base::CMsgProtoBufHeader};
|
use vapore_proto::{
|
||||||
|
enums_clientserver::EMsg, steammessages_base::CMsgProtoBufHeader,
|
||||||
|
steammessages_clientserver_login::CMsgClientHeartBeat,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::message::{CMProtoBufMessage, CMRawProtoBufMessage};
|
use crate::message::{CMProtoBufMessage, CMRawProtoBufMessage};
|
||||||
|
|
||||||
|
@ -235,9 +239,27 @@ impl CMSession {
|
||||||
|
|
||||||
tokio::spawn(context);
|
tokio::spawn(context);
|
||||||
|
|
||||||
Ok(Self {
|
let session = Self {
|
||||||
inner: inner_wrapped,
|
inner: inner_wrapped,
|
||||||
})
|
};
|
||||||
|
|
||||||
|
let session_cloned = session.clone();
|
||||||
|
tokio::spawn(async move { session_cloned.send_heartbeat_task().await });
|
||||||
|
|
||||||
|
Ok(session)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_heartbeat_task(mut self) -> eyre::Result<()> {
|
||||||
|
let mut interval = tokio::time::interval(time::Duration::from_secs(5));
|
||||||
|
loop {
|
||||||
|
interval.tick().await;
|
||||||
|
self.send_notification(EMsg::k_EMsgClientHeartBeat, CMsgClientHeartBeat::default())?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_client_session_id(&mut self, new_client_session_id: i32) {
|
||||||
|
let mut inner = self.inner.lock().expect("Lock was poisoned");
|
||||||
|
inner.client_session_id = new_client_session_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_service_method<T: protobuf::Message, U: protobuf::Message>(
|
pub fn call_service_method<T: protobuf::Message, U: protobuf::Message>(
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
use color_eyre::eyre;
|
use color_eyre::eyre;
|
||||||
|
use message::CMProtoBufMessage;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use vapore_proto::{
|
use vapore_proto::{
|
||||||
enums_clientserver::EMsg,
|
enums_clientserver::EMsg,
|
||||||
steammessages_auth_steamclient::{
|
steammessages_auth_steamclient::{
|
||||||
CAuthentication_BeginAuthSessionViaQR_Request,
|
CAuthentication_BeginAuthSessionViaQR_Request,
|
||||||
CAuthentication_BeginAuthSessionViaQR_Response, CAuthentication_DeviceDetails,
|
CAuthentication_BeginAuthSessionViaQR_Response, CAuthentication_DeviceDetails,
|
||||||
EAuthTokenPlatformType,
|
CAuthentication_PollAuthSessionStatus_Request,
|
||||||
|
CAuthentication_PollAuthSessionStatus_Response, EAuthTokenPlatformType,
|
||||||
},
|
},
|
||||||
steammessages_clientserver_login::CMsgClientHello,
|
steammessages_clientserver_login::{CMsgClientHello, CMsgClientLogonResponse},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod connection;
|
mod connection;
|
||||||
|
@ -82,5 +84,56 @@ pub async fn main() -> eyre::Result<()> {
|
||||||
|
|
||||||
log::debug!("Got response {:#x?}", response);
|
log::debug!("Got response {:#x?}", response);
|
||||||
|
|
||||||
|
let code = qrcode::QrCode::new(response.body.challenge_url()).unwrap();
|
||||||
|
log::info!(
|
||||||
|
"Got new QR code:\n{}",
|
||||||
|
code.render::<qrcode::render::unicode::Dense1x2>().build()
|
||||||
|
);
|
||||||
|
|
||||||
|
let cloned_session = session.clone();
|
||||||
|
let poll_task = tokio::spawn(async move {
|
||||||
|
let mut session = cloned_session;
|
||||||
|
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs_f32(
|
||||||
|
response.body.interval(),
|
||||||
|
));
|
||||||
|
|
||||||
|
loop {
|
||||||
|
interval.tick().await;
|
||||||
|
let request = CAuthentication_PollAuthSessionStatus_Request {
|
||||||
|
client_id: response.body.client_id.clone(),
|
||||||
|
request_id: response.body.request_id.clone(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let response: CMProtoBufMessage<CAuthentication_PollAuthSessionStatus_Response> =
|
||||||
|
session
|
||||||
|
.call_service_method(
|
||||||
|
"Authentication.PollAuthSessionStatus#1".to_string(),
|
||||||
|
request,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
log::debug!("Got auth poll status {:#?}", response.body);
|
||||||
|
|
||||||
|
if let Some(new_url) = response.body.new_challenge_url {
|
||||||
|
let code = qrcode::QrCode::new(new_url).unwrap();
|
||||||
|
log::info!(
|
||||||
|
"Got new QR code:\n{}",
|
||||||
|
code.render::<qrcode::render::unicode::Dense1x2>().build()
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut finish_receiver = session.subscribe_message_type(EMsg::k_EMsgClientLogOnResponse);
|
||||||
|
|
||||||
|
let raw_response = finish_receiver.recv().await?;
|
||||||
|
let response: CMProtoBufMessage<CMsgClientLogonResponse> =
|
||||||
|
CMProtoBufMessage::deserialize(raw_response)?;
|
||||||
|
|
||||||
|
poll_task.abort();
|
||||||
|
|
||||||
|
log::debug!("Got logon response: {:#x?}", response);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
use color_eyre::eyre;
|
use color_eyre::eyre;
|
||||||
|
use flate2::read::GzDecoder;
|
||||||
use protobuf::{Enum as _, Message as _};
|
use protobuf::{Enum as _, Message as _};
|
||||||
use vapore_proto::{
|
use vapore_proto::{
|
||||||
enums_clientserver::EMsg,
|
enums_clientserver::EMsg,
|
||||||
|
@ -82,12 +85,28 @@ impl CMRawProtoBufMessage {
|
||||||
// possibly gzipped bytes inside a protobuf.
|
// possibly gzipped bytes inside a protobuf.
|
||||||
// why, valve
|
// why, valve
|
||||||
let root = CMProtoBufMessage::<CMsgMulti>::deserialize(root_raw)?;
|
let root = CMProtoBufMessage::<CMsgMulti>::deserialize(root_raw)?;
|
||||||
if root.body.size_unzipped.is_some() {
|
let mut gzip_decompressed = Vec::new();
|
||||||
todo!("gzip support in CMsgMulti")
|
|
||||||
}
|
let mut body = if let Some(size_unzipped) = root.body.size_unzipped {
|
||||||
|
gzip_decompressed.reserve(size_unzipped as usize);
|
||||||
|
|
||||||
|
let mut gz = GzDecoder::new(root.body.message_body());
|
||||||
|
gz.read_to_end(&mut gzip_decompressed)?;
|
||||||
|
|
||||||
|
if gzip_decompressed.len() != size_unzipped as usize {
|
||||||
|
eyre::bail!(
|
||||||
|
"Expected decompressed len {}, got {}",
|
||||||
|
size_unzipped,
|
||||||
|
gzip_decompressed.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
&gzip_decompressed
|
||||||
|
} else {
|
||||||
|
root.body.message_body()
|
||||||
|
};
|
||||||
|
|
||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
let mut body = root.body.message_body();
|
|
||||||
while body.len() >= 4 {
|
while body.len() >= 4 {
|
||||||
let full_length = u32::from_le_bytes(body[0..4].try_into().unwrap());
|
let full_length = u32::from_le_bytes(body[0..4].try_into().unwrap());
|
||||||
let message_end = 4 + full_length as usize;
|
let message_end = 4 + full_length as usize;
|
||||||
|
|
Loading…
Reference in a new issue