From 6c34a8f2df03c87c037283f77b657853effb3f7d Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Sat, 31 Jul 2021 16:57:51 -0400 Subject: [PATCH] refactor confirmations parsing, fixes #66 --- Cargo.lock | 452 +++++++++++++++++- src/main.rs | 4 - steamguard/Cargo.toml | 1 + steamguard/src/confirmation.rs | 6 +- .../confirmations/multiple-confirmations.html | 273 +++++++++++ steamguard/src/lib.rs | 116 +++-- 6 files changed, 781 insertions(+), 71 deletions(-) create mode 100644 steamguard/src/fixtures/confirmations/multiple-confirmations.html diff --git a/Cargo.lock b/Cargo.lock index 09b3e5a..19343f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -162,6 +162,12 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "cookie" version = "0.14.4" @@ -221,10 +227,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b32a398eb1ccfbe7e4f452bc749c44d38dd732e9a253f19da224c416f00ee7f4" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.2", "subtle", ] +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "matches", + "phf", + "proc-macro2", + "quote", + "smallvec", + "syn", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "der" version = "0.4.0" @@ -235,6 +268,19 @@ dependencies = [ "crypto-bigint", ] +[[package]] +name = "derive_more" +version = "0.99.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.3.3", + "syn", +] + [[package]] name = "digest" version = "0.9.0" @@ -250,6 +296,27 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + +[[package]] +name = "dtoa-short" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +dependencies = [ + "dtoa", +] + +[[package]] +name = "ego-tree" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" + [[package]] name = "encoding_rs" version = "0.8.28" @@ -302,6 +369,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" +dependencies = [ + "mac", + "new_debug_unreachable", +] + [[package]] name = "futures-channel" version = "0.3.13" @@ -350,6 +427,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.14.4" @@ -360,6 +446,26 @@ dependencies = [ "version_check", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.2" @@ -368,7 +474,7 @@ checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -414,6 +520,20 @@ dependencies = [ "sha1 0.2.0", ] +[[package]] +name = "html5ever" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "http" version = "0.2.3" @@ -563,6 +683,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "markup5ever" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +dependencies = [ + "log", + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + [[package]] name = "matches" version = "0.1.8" @@ -632,6 +772,18 @@ dependencies = [ "tempfile", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + [[package]] name = "ntapi" version = "0.3.6" @@ -654,7 +806,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.4", "smallvec", "zeroize", ] @@ -760,6 +912,69 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared", + "rand 0.7.3", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.0.5" @@ -828,6 +1043,12 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -862,6 +1083,20 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + [[package]] name = "rand" version = "0.8.4" @@ -869,9 +1104,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "rand_chacha 0.3.0", + "rand_core 0.6.2", + "rand_hc 0.3.0", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -881,7 +1126,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -890,7 +1144,16 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" dependencies = [ - "getrandom", + "getrandom 0.2.2", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -899,7 +1162,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" dependencies = [ - "rand_core", + "rand_core 0.6.2", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -1011,7 +1283,7 @@ dependencies = [ "num-traits", "pkcs1", "pkcs8", - "rand", + "rand 0.8.4", "subtle", "zeroize", ] @@ -1022,7 +1294,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver", + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", ] [[package]] @@ -1041,6 +1322,22 @@ dependencies = [ "winapi", ] +[[package]] +name = "scraper" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e02aa790c80c2e494130dec6a522033b6a23603ffc06360e9fe6c611ea2c12" +dependencies = [ + "cssparser", + "ego-tree", + "getopts", + "html5ever", + "matches", + "selectors", + "smallvec", + "tendril", +] + [[package]] name = "security-framework" version = "2.1.2" @@ -1064,13 +1361,42 @@ dependencies = [ "libc", ] +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser", + "semver-parser 0.7.0", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser 0.10.2", ] [[package]] @@ -1079,6 +1405,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.124" @@ -1122,6 +1457,16 @@ dependencies = [ "serde", ] +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + [[package]] name = "sha1" version = "0.2.0" @@ -1134,6 +1479,12 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +[[package]] +name = "siphasher" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" + [[package]] name = "slab" version = "0.4.2" @@ -1172,6 +1523,12 @@ dependencies = [ "der", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "standback" version = "0.2.17" @@ -1201,7 +1558,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" dependencies = [ "discard", - "rustc_version", + "rustc_version 0.2.3", "stdweb-derive", "stdweb-internal-macros", "stdweb-internal-runtime", @@ -1253,10 +1610,11 @@ dependencies = [ "hmac-sha1", "lazy_static 1.4.0", "log", - "rand", + "rand 0.8.4", "regex", "reqwest", "rsa", + "scraper", "serde", "serde_json", "standback", @@ -1274,7 +1632,7 @@ dependencies = [ "hmac-sha1", "lazy_static 1.4.0", "log", - "rand", + "rand 0.8.4", "regex", "reqwest", "rpassword", @@ -1289,6 +1647,31 @@ dependencies = [ "uuid", ] +[[package]] +name = "string_cache" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a" +dependencies = [ + "lazy_static 1.4.0", + "new_debug_unreachable", + "phf_shared", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", +] + [[package]] name = "strsim" version = "0.8.0" @@ -1332,12 +1715,23 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if", "libc", - "rand", + "rand 0.8.4", "redox_syscall", "remove_dir_all", "winapi", ] +[[package]] +name = "tendril" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ef557cb397a4f0a5a3a628f06515f78563f2209e64d47055d9dc6052bf5e33" +dependencies = [ + "futf", + "mac", + "utf-8", +] + [[package]] name = "termcolor" version = "1.1.2" @@ -1374,6 +1768,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + [[package]] name = "thread_local" version = "0.3.4" @@ -1524,6 +1924,12 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -1575,13 +1981,19 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom", + "getrandom 0.2.2", ] [[package]] @@ -1618,6 +2030,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" diff --git a/src/main.rs b/src/main.rs index 15278e0..5e1f2d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -374,28 +374,24 @@ fn demo_confirmation_menu() { id: 1234, key: 12345, conf_type: ConfirmationType::Trade, - int_type: 0, creator: 09870987, }, Confirmation { id: 1234, key: 12345, conf_type: ConfirmationType::MarketSell, - int_type: 0, creator: 09870987, }, Confirmation { id: 1234, key: 12345, conf_type: ConfirmationType::AccountRecovery, - int_type: 0, creator: 09870987, }, Confirmation { id: 1234, key: 12345, conf_type: ConfirmationType::Trade, - int_type: 0, creator: 09870987, }, ]); diff --git a/steamguard/Cargo.toml b/steamguard/Cargo.toml index d31c89c..16fdc81 100644 --- a/steamguard/Cargo.toml +++ b/steamguard/Cargo.toml @@ -21,3 +21,4 @@ regex = "1" lazy_static = "1.4.0" uuid = { version = "0.8", features = ["v4"] } log = "0.4.14" +scraper = "0.12.0" diff --git a/steamguard/src/confirmation.rs b/steamguard/src/confirmation.rs index ddecc6a..343dc0c 100644 --- a/steamguard/src/confirmation.rs +++ b/steamguard/src/confirmation.rs @@ -1,10 +1,8 @@ /// A mobile confirmation. There are multiple things that can be confirmed, like trade offers. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct Confirmation { pub id: u64, pub key: u64, - /// Comes from the `data-type` attribute in the HTML - pub int_type: i32, /// Trade offer ID or market transaction ID pub creator: u64, pub conf_type: ConfirmationType, @@ -17,7 +15,7 @@ impl Confirmation { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ConfirmationType { Generic = 1, Trade = 2, diff --git a/steamguard/src/fixtures/confirmations/multiple-confirmations.html b/steamguard/src/fixtures/confirmations/multiple-confirmations.html new file mode 100644 index 0000000..23bc936 --- /dev/null +++ b/steamguard/src/fixtures/confirmations/multiple-confirmations.html @@ -0,0 +1,273 @@ + + + + + + + Steam Community :: Confirmations + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+ +
+
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+ + + +
+ +
+
+
+
+
+ +
+
+
Sell - Summer 2021 - Horror
+
$0.05 ($0.03)
+
2 minutes ago
+
+
+ +
+
+
+
+
+
+ +
+
+
Sell - Summer 2021 - Horror
+
$0.05 ($0.03)
+
2 minutes ago
+
+
+ +
+
+
+
+
+
+ +
+
+
Sell - Summer 2021 - Horror
+
$0.05 ($0.03)
+
2 minutes ago
+
+
+ +
+
+
+
+
+
+ +
+
+
Sell - Summer 2021 - Rogue
+
$0.05 ($0.03)
+
2 minutes ago
+
+
+ +
+
+
+
+
+
+ +
+
+
Sell - Summer 2021 - Horror
+
$0.05 ($0.03)
+
2 minutes ago
+
+
+ +
+
+
+ + + + + + + + +
+ + + + + +
+ +
+ + \ No newline at end of file diff --git a/steamguard/src/lib.rs b/steamguard/src/lib.rs index c5acf98..cbbf11c 100644 --- a/steamguard/src/lib.rs +++ b/steamguard/src/lib.rs @@ -2,10 +2,10 @@ use std::{collections::HashMap, convert::TryInto, thread, time}; use anyhow::Result; pub use confirmation::{Confirmation, ConfirmationType}; use hmacsha1::hmac_sha1; -use regex::Regex; use reqwest::{Url, cookie::CookieStore, header::{COOKIE, USER_AGENT}}; use serde::{Serialize, Deserialize}; use log::*; +use scraper::{Html, Selector}; #[macro_use] extern crate lazy_static; #[macro_use] @@ -21,11 +21,6 @@ mod confirmation; // const TWO_FACTOR_BASE: String = STEAMAPI_BASE + "/ITwoFactorService/%s/v0001"; // static TWO_FACTOR_TIME_QUERY: String = TWO_FACTOR_BASE.Replace("%s", "QueryTime"); -lazy_static! { - static ref CONFIRMATION_REGEX: Regex = Regex::new("
((Confirm|Trade|Account recovery|Sell -) .+)
").unwrap(); -} - extern crate hmacsha1; extern crate base64; extern crate cookie; @@ -144,51 +139,19 @@ impl SteamGuardAccount { .cookie_store(true) .build()?; - match client + let resp = client .get("https://steamcommunity.com/mobileconf/conf".parse::().unwrap()) .header("X-Requested-With", "com.valvesoftware.android.steam.community") .header(USER_AGENT, "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; Google Nexus 4 - 4.1.1 - API 16 - 768x1280 Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30") .header(COOKIE, cookies.cookies(&url).unwrap()) .query(&self.get_confirmation_query_params("conf")) - .send() { - Ok(resp) => { - trace!("{:?}", resp); - let text = resp.text().unwrap(); - trace!("text: {:?}", text); - println!("{}", text); - // possible errors: - // - // Invalid authenticator: - //
Invalid authenticator
- //
It looks like your Steam Guard Mobile Authenticator is providing incorrect Steam Guard codes. This could be caused by an inaccurate clock or bad timezone settings on your device. If your time settings are correct, it could be that a different device has been set up to provide the Steam Guard codes for your account, which means the authenticator on this device is no longer valid.
- // - //
Nothing to confirm
- match CONFIRMATION_REGEX.captures(text.as_str()) { - Some(caps) => { - let conf_id = caps[1].parse()?; - let conf_key = caps[2].parse()?; - let conf_type = caps[3].try_into().unwrap_or(ConfirmationType::Unknown); - let conf_creator = caps[4].parse()?; - debug!("conf_id={} conf_key={} conf_type={:?} conf_creator={}", conf_id, conf_key, conf_type, conf_creator); - return Ok(vec![Confirmation { - id: conf_id, - key: conf_key, - conf_type: conf_type, - creator: conf_creator, - int_type: 0, - }]); - } - _ => { - info!("No confirmations"); - return Ok(vec![]); - } - }; - } - Err(e) => { - error!("error: {:?}", e); - bail!(e); - } - } + .send()?; + + trace!("{:?}", resp); + let text = resp.text().unwrap(); + trace!("text: {:?}", text); + println!("{}", text); + return parse_confirmations(text); } /// Respond to a confirmation. @@ -263,6 +226,30 @@ impl SteamGuardAccount { } } +fn parse_confirmations(text: String) -> anyhow::Result> { + // possible errors: + // + // Invalid authenticator: + //
Invalid authenticator
+ //
It looks like your Steam Guard Mobile Authenticator is providing incorrect Steam Guard codes. This could be caused by an inaccurate clock or bad timezone settings on your device. If your time settings are correct, it could be that a different device has been set up to provide the Steam Guard codes for your account, which means the authenticator on this device is no longer valid.
+ // + //
Nothing to confirm
+ + let fragment = Html::parse_fragment(&text); + let selector = Selector::parse(".mobileconf_list_entry").unwrap(); + let mut confirmations = vec![]; + for elem in fragment.select(&selector) { + let conf = Confirmation { + id: elem.value().attr("data-confid").unwrap().parse()?, + key: elem.value().attr("data-key").unwrap().parse()?, + conf_type: elem.value().attr("data-type").unwrap().try_into().unwrap_or(ConfirmationType::Unknown), + creator: elem.value().attr("data-creator").unwrap().parse()?, + }; + confirmations.push(conf); + } + return Ok(confirmations); +} + #[cfg(test)] mod tests { use super::*; @@ -287,4 +274,41 @@ mod tests { fn test_generate_confirmation_hash_for_time() { assert_eq!(generate_confirmation_hash_for_time(1617591917, "conf", &String::from("GQP46b73Ws7gr8GmZFR0sDuau5c=")), String::from("NaL8EIMhfy/7vBounJ0CvpKbrPk=")); } + + #[test] + fn test_parse_multiple_confirmations() { + let text = include_str!("fixtures/confirmations/multiple-confirmations.html"); + let confirmations = parse_confirmations(text.into()).unwrap(); + assert_eq!(confirmations.len(), 5); + assert_eq!(confirmations[0], Confirmation { + id: 9890792058, + key: 15509106087034649470, + conf_type: ConfirmationType::MarketSell, + creator: 3392884950693131245, + }); + assert_eq!(confirmations[1], Confirmation { + id: 9890791666, + key: 2661901169510258722, + conf_type: ConfirmationType::MarketSell, + creator: 3392884950693130525, + }); + assert_eq!(confirmations[2], Confirmation { + id: 9890791241, + key: 15784514761287735229, + conf_type: ConfirmationType::MarketSell, + creator: 3392884950693129565, + }); + assert_eq!(confirmations[3], Confirmation { + id: 9890790828, + key: 5049250785011653560, + conf_type: ConfirmationType::MarketSell, + creator: 3392884950693128685, + }); + assert_eq!(confirmations[4], Confirmation { + id: 9890790159, + key: 6133112455066694993, + conf_type: ConfirmationType::MarketSell, + creator: 3392884950693127345, + }); + } }