private bool _checkSMSCode(string smsCode) { var postData = new NameValueCollection(); postData.Add("op", "check_sms_code"); postData.Add("arg", smsCode); postData.Add("checkfortos", "0"); postData.Add("skipvoip", "1"); postData.Add("sessionid", _session.SessionID); string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "POST", postData, _cookies); if (response == null) { return(false); } var addPhoneNumberResponse = JsonConvert.DeserializeObject <AddPhoneResponse>(response); if (!addPhoneNumberResponse.Success) { Thread.Sleep(3500); //It seems that Steam needs a few seconds to finalize the phone number on the account. return(_hasPhoneAttached()); } return(true); }
public bool DeactivateAuthenticator() { var postData = new NameValueCollection(); postData.Add("steamid", this.Session.SteamID.ToString()); postData.Add("steamguard_scheme", "2"); postData.Add("revocation_code", this.RevocationCode); postData.Add("access_token", this.Session.OAuthToken); try { string response = SteamWeb.MobileLoginRequest(APIEndpoints.STEAMAPI_BASE + "/ITwoFactorService/RemoveAuthenticator/v0001", "POST", postData); var removeResponse = JsonConvert.DeserializeObject <RemoveAuthenticatorResponse>(response); if (removeResponse == null || removeResponse.Response == null || !removeResponse.Response.Success) { return(false); } return(true); } catch (Exception e) { return(false); } }
private ConfirmationDetailsResponse _getConfirmationDetails(Confirmation conf) { string url = APIEndpoints.COMMUNITY_BASE + "/mobileconf/details/" + conf.ID + "?"; string queryString = GenerateConfirmationQueryParams("details"); url += queryString; CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string referer = GenerateConfirmationURL(); string response = SteamWeb.Request(url, "GET", "", cookies, null); if (String.IsNullOrEmpty(response)) { return(null); } var confResponse = JsonConvert.DeserializeObject <ConfirmationDetailsResponse>(response); if (confResponse == null) { return(null); } return(confResponse); }
private bool _addPhoneNumber() { string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax?op=add_phone_number&arg=" + WebUtility.UrlEncode(PhoneNumber), "GET", null, _cookies); var addPhoneNumberResponse = JsonConvert.DeserializeObject <AddPhoneResponse>(response); return(addPhoneNumberResponse.Success); }
private bool _sendMultiConfirmationAjax(Confirmation[] confs, string op) { string url = APIEndpoints.COMMUNITY_BASE + "/mobileconf/multiajaxop"; string query = "op=" + op + "&" + GenerateConfirmationQueryParams(op); foreach (var conf in confs) { query += "&cid[]=" + conf.ID + "&ck[]=" + conf.Key; } CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string referer = GenerateConfirmationURL(); string response = SteamWeb.Request(url, "POST", query, cookies, null); if (response == null) { return(false); } SendConfirmationResponse confResponse = JsonConvert.DeserializeObject <SendConfirmationResponse>(response); return(confResponse.Success); }
/// <summary> /// Refreshes the Steam session. Necessary to perform confirmations if your session has expired or changed. /// </summary> /// <returns></returns> public bool RefreshSession() { string url = APIEndpoints.MOBILEAUTH_GETWGTOKEN; NameValueCollection postData = new NameValueCollection(); postData.Add("access_token", this.Session.OAuthToken); string response = SteamWeb.Request(url, "POST", postData); if (response == null) { return(false); } try { var refreshResponse = JsonConvert.DeserializeObject <RefreshSessionDataResponse>(response); if (refreshResponse == null || refreshResponse.Response == null || String.IsNullOrEmpty(refreshResponse.Response.Token)) { return(false); } string token = this.Session.SteamID + "%7C%7C" + refreshResponse.Response.Token; string tokenSecure = this.Session.SteamID + "%7C%7C" + refreshResponse.Response.TokenSecure; this.Session.SteamLogin = token; this.Session.SteamLoginSecure = tokenSecure; return(true); } catch (Exception e) { return(false); } }
private bool _sendConfirmationAjax(Confirmation conf, string op) { string url = APIEndpoints.COMMUNITY_BASE + "/mobileconf/ajaxop"; string queryString = "?op=" + op + "&"; queryString += _generateConfirmationQueryParams(op); queryString += "&cid=" + conf.ConfirmationID + "&ck=" + conf.ConfirmationKey; url += queryString; CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string referer = _generateConfirmationURL(); string response = SteamWeb.Request(url + queryString, "GET", null, cookies, null); if (response == null) { return(false); } SendConfirmationResponse confResponse = JsonConvert.DeserializeObject <SendConfirmationResponse>(response); return(confResponse.Success); }
public LinkResult AddAuthenticator() { bool hasPhone = _hasPhoneAttached(); if (hasPhone && PhoneNumber != null) { return(LinkResult.MustRemovePhoneNumber); } if (!hasPhone && PhoneNumber == null) { return(LinkResult.MustProvidePhoneNumber); } if (!hasPhone) { if (!_addPhoneNumber()) { return(LinkResult.GeneralFailure); } } var postData = new NameValueCollection(); postData.Add("access_token", _session.OAuthToken); postData.Add("steamid", _session.SteamID.ToString()); postData.Add("authenticator_type", "1"); postData.Add("device_identifier", this.DeviceID); postData.Add("sms_phone_id", "1"); string response = SteamWeb.MobileLoginRequest(APIEndpoints.STEAMAPI_BASE + "/ITwoFactorService/AddAuthenticator/v0001", "POST", postData); if (response == null) { return(LinkResult.GeneralFailure); } var addAuthenticatorResponse = JsonConvert.DeserializeObject <AddAuthenticatorResponse>(response); if (addAuthenticatorResponse == null || addAuthenticatorResponse.Response == null) { return(LinkResult.GeneralFailure); } if (addAuthenticatorResponse.Response.Status == 29) { return(LinkResult.AuthenticatorPresent); } if (addAuthenticatorResponse.Response.Status != 1) { return(LinkResult.GeneralFailure); } this.LinkedAccount = addAuthenticatorResponse.Response; LinkedAccount.Session = this._session; LinkedAccount.DeviceID = this.DeviceID; return(LinkResult.AwaitingFinalization); }
public Confirmation[] FetchConfirmations() { string url = this.GenerateConfirmationURL(); CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string response = SteamWeb.Request(url, "GET", "", cookies); File.WriteAllText("test.txt", response); /*So you're going to see this abomination and you're going to be upset. * It's understandable. But the thing is, regex for HTML -- while awful -- makes this way faster than parsing a DOM, plus we don't need another library. * And because the data is always in the same place and same format... It's not as if we're trying to naturally understand HTML here. Just extract strings. * I'm sorry. */ Regex confIDRegex = new Regex("data-confid=\"(\\d+)\""); Regex confKeyRegex = new Regex("data-key=\"(\\d+)\""); Regex confDescRegex = new Regex("<div>((Confirm|Trade with|Sell -) .+)</div>"); if (response == null || !(confIDRegex.IsMatch(response) && confKeyRegex.IsMatch(response) && confDescRegex.IsMatch(response))) { if (response == null || !response.Contains("<div>Nothing to confirm</div>")) { throw new WGTokenInvalidException(); } return(new Confirmation[0]); } MatchCollection confIDs = confIDRegex.Matches(response); MatchCollection confKeys = confKeyRegex.Matches(response); MatchCollection confDescs = confDescRegex.Matches(response); List <Confirmation> ret = new List <Confirmation>(); for (int i = 0; i < confIDs.Count; i++) { try { string confID = confIDs[i].Groups[1].Value; string confKey = confKeys[i].Groups[1].Value; string confDesc = HttpUtility.HtmlDecode(confDescs[i].Groups[1].Value); Confirmation conf = new Confirmation() { Description = confDesc, ID = confID, Key = confKey }; ret.Add(conf); } catch { /*fak u*/ } } return(ret.ToArray()); }
private bool _hasPhoneAttached() { var postData = new NameValueCollection(); postData.Add("op", "has_phone"); postData.Add("arg", "null"); string response = SteamWeb.MobileLoginRequest(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "GET", postData, _cookies); var hasPhoneResponse = JsonConvert.DeserializeObject <HasPhoneResponse>(response); return(hasPhoneResponse.HasPhone); }
public async Task <Confirmation[]> FetchConfirmationsAsync() { string url = this.GenerateConfirmationURL(); CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string response = await SteamWeb.RequestAsync(url, "GET", null, cookies); return(FetchConfirmationInternal(response)); }
public async Task <Confirmation[]> FetchConfirmationsAsync() { string url = this.GenerateConfirmationURL(); CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string response = await SteamWeb.RequestAsync(url, "GET", null, cookies); /*So you're going to see this abomination and you're going to be upset. * It's understandable. But the thing is, regex for HTML -- while awful -- makes this way faster than parsing a DOM, plus we don't need another library. * And because the data is always in the same place and same format... It's not as if we're trying to naturally understand HTML here. Just extract strings. * I'm sorry. */ Regex confRegex = new Regex("<div class=\"mobileconf_list_entry\" id=\"conf[0-9]+\" data-confid=\"(\\d+)\" data-key=\"(\\d+)\" data-type=\"(\\d+)\" data-creator=\"(\\d+)\""); if (response == null || !confRegex.IsMatch(response)) { if (response == null || !response.Contains("<div>Nothing to confirm</div>")) { throw new WGTokenInvalidException(); } return(new Confirmation[0]); } MatchCollection confirmations = confRegex.Matches(response); List <Confirmation> ret = new List <Confirmation>(); foreach (Match confirmation in confirmations) { if (confirmation.Groups.Count != 5) { continue; } ulong confID, confKey, confCreator; int confType; if (!ulong.TryParse(confirmation.Groups[1].Value, out confID) || !ulong.TryParse(confirmation.Groups[2].Value, out confKey) || !int.TryParse(confirmation.Groups[3].Value, out confType) || !ulong.TryParse(confirmation.Groups[4].Value, out confCreator)) { continue; } ret.Add(new Confirmation(confID, confKey, confType, confCreator)); } return(ret.ToArray()); }
public Confirmation[] FetchConfirmations() { string url = this.GenerateConfirmationURL(); CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string response = SteamWeb.Request(url, "GET", "", cookies); return(FetchConfirmationInternal(response)); }
public Confirmation[] FetchConfirmations() { string url = this._generateConfirmationURL(); CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string response = SteamWeb.Request(url, "GET", null, cookies); /*So you're going to see this abomination and you're going to be upset. * It's understandable. But the thing is, regex for HTML -- while awful -- makes this way faster than parsing a DOM, plus we don't need another library. * And because the data is always in the same place and same format... It's not as if we're trying to naturally understand HTML here. Just extract strings. * I'm sorry. */ Regex confIDRegex = new Regex("data-confid=\"(\\d+)\""); Regex confKeyRegex = new Regex("data-key=\"(\\d+)\""); Regex confDescRegex = new Regex("<div>((Confirm|Trade with) .+)</div>"); if (!(confIDRegex.IsMatch(response) && confKeyRegex.IsMatch(response) && confDescRegex.IsMatch(response))) { return(new Confirmation[0]); } MatchCollection confIDs = confIDRegex.Matches(response); MatchCollection confKeys = confKeyRegex.Matches(response); MatchCollection confDescs = confDescRegex.Matches(response); List <Confirmation> ret = new List <Confirmation>(); for (int i = 0; i < confIDs.Count; i++) { string confID = confIDs[i].Groups[1].Value; string confKey = confKeys[i].Groups[1].Value; string confDesc = confDescs[i].Groups[1].Value; Confirmation conf = new Confirmation() { ConfirmationDescription = confDesc, ConfirmationID = confID, ConfirmationKey = confKey }; ret.Add(conf); } return(ret.ToArray()); }
private bool _checkSMSCode(string smsCode) { var postData = new NameValueCollection(); postData.Add("op", "check_sms_code"); postData.Add("arg", smsCode); postData.Add("sessionid", _session.SessionID); string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "POST", postData, _cookies); if (response == null) { return(false); } var addPhoneNumberResponse = JsonConvert.DeserializeObject <AddPhoneResponse>(response); return(addPhoneNumberResponse.Success); }
private bool _checkEmailConfirmation() { var postData = new NameValueCollection(); postData.Add("op", "email_confirmation"); postData.Add("arg", ""); postData.Add("sessionid", _session.SessionID); string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "POST", postData, _cookies); if (response == null) { return(false); } var emailConfirmationResponse = JsonConvert.DeserializeObject <AddPhoneResponse>(response); return(emailConfirmationResponse.Success); }
private bool _hasPhoneAttached() { var postData = new NameValueCollection(); postData.Add("op", "has_phone"); postData.Add("arg", "null"); postData.Add("sessionid", _session.SessionID); string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "POST", postData, _cookies); if (response == null) { return(false); } var hasPhoneResponse = JsonConvert.DeserializeObject <HasPhoneResponse>(response); return(hasPhoneResponse.HasPhone); }
public FinalizeResult FinalizeAddAuthenticator(string smsCode) { bool smsCodeGood = false; var postData = new NameValueCollection(); postData.Add("steamid", _session.SteamID.ToString()); postData.Add("access_token", _session.OAuthToken); postData.Add("activation_code", smsCode); postData.Add("authenticator_code", ""); int tries = 0; while (tries <= 30) { postData.Set("authenticator_code", tries == 0 ? "" : LinkedAccount.GenerateSteamGuardCode()); postData.Add("authenticator_time", TimeAligner.GetSteamTime().ToString()); if (smsCodeGood) { postData.Set("activation_code", ""); } string response = SteamWeb.MobileLoginRequest(APIEndpoints.STEAMAPI_BASE + "/ITwoFactorService/FinalizeAddAuthenticator/v0001", "POST", postData); if (response == null) { return(FinalizeResult.GeneralFailure); } var finalizeResponse = JsonConvert.DeserializeObject <FinalizeAuthenticatorResponse>(response); if (finalizeResponse == null || finalizeResponse.Response == null) { return(FinalizeResult.GeneralFailure); } if (finalizeResponse.Response.Status == 89) { return(FinalizeResult.BadSMSCode); } if (finalizeResponse.Response.Status == 88) { if (tries >= 30) { return(FinalizeResult.UnableToGenerateCorrectCodes); } } if (!finalizeResponse.Response.Success) { return(FinalizeResult.GeneralFailure); } if (finalizeResponse.Response.WantMore) { smsCodeGood = true; tries++; continue; } this.LinkedAccount.FullyEnrolled = true; return(FinalizeResult.Success); } return(FinalizeResult.GeneralFailure); }
public Confirmation[] FetchConfirmations() { if (fetchingLock.WaitOne(500)) { try { int msec = (int)Math.Floor(10000 - DateTime.Now.Subtract(lastConfirmationFetchTime).TotalMilliseconds); if (msec > 0) { Thread.Sleep(msec); } string url = this.GenerateConfirmationURL(); CookieContainer cookies = new CookieContainer(); this.Session.AddCookies(cookies); string response = SteamWeb.Request(url, "GET", "", cookies); lastConfirmationFetchTime = DateTime.Now; /*So you're going to see this abomination and you're going to be upset. * It's understandable. But the thing is, regex for HTML -- while awful -- makes this way faster than parsing a DOM, plus we don't need another library. * And because the data is always in the same place and same format... It's not as if we're trying to naturally understand HTML here. Just extract strings. * I'm sorry. */ Regex confRegex = new Regex("<div class=\"mobileconf_list_entry\" id=\"conf[0-9]+\" data-confid=\"(\\d+)\" data-key=\"(\\d+)\" data-type=\"(\\d+)\" data-creator=\"(\\d+)\""); if (response == null || !confRegex.IsMatch(response)) { if (response == null || !response.Contains("<div>Nothing to confirm</div>")) { throw new WGTokenInvalidException(); } return(new Confirmation[0]); } MatchCollection confirmations = confRegex.Matches(response); List <Confirmation> ret = new List <Confirmation>(); foreach (Match confirmation in confirmations) { if (confirmation.Groups.Count != 5) { continue; } if (!ulong.TryParse(confirmation.Groups[1].Value, out ulong confID) || !ulong.TryParse(confirmation.Groups[2].Value, out ulong confKey) || !int.TryParse(confirmation.Groups[3].Value, out int confType) || !ulong.TryParse(confirmation.Groups[4].Value, out ulong confCreator)) { continue; } ret.Add(new Confirmation(confID, confKey, confType, confCreator)); } return(ret.ToArray()); } finally { fetchingLock.ReleaseMutex(); } } else { //kinda nothing to confirm, don't bother it will probably be confirmed by another thread. return(new Confirmation[0]); } }
public LoginResult DoLogin() { var postData = new NameValueCollection(); var cookies = _cookies; string response = null; if (cookies.Count == 0) { //Generate a SessionID cookies.Add(new Cookie("mobileClientVersion", "0 (2.1.3)", "/", ".steamcommunity.com")); cookies.Add(new Cookie("mobileClient", "android", "/", ".steamcommunity.com")); cookies.Add(new Cookie("Steam_Language", "english", "/", ".steamcommunity.com")); NameValueCollection headers = new NameValueCollection(); headers.Add("X-Requested-With", "com.valvesoftware.android.steam.community"); SteamWeb.MobileLoginRequest("https://steamcommunity.com/login?oauth_client_id=DE45CD61&oauth_scope=read_profile%20write_profile%20read_client%20write_client", "GET", null, cookies, headers); } postData.Add("username", this.Username); response = SteamWeb.MobileLoginRequest(APIEndpoints.COMMUNITY_BASE + "/login/getrsakey", "POST", postData, cookies); if (response == null || response.Contains("<BODY>\nAn error occurred while processing your request.")) { return(LoginResult.GeneralFailure); } var rsaResponse = JsonConvert.DeserializeObject <RSAResponse>(response); if (!rsaResponse.Success) { return(LoginResult.BadRSA); } RNGCryptoServiceProvider secureRandom = new RNGCryptoServiceProvider(); byte[] encryptedPasswordBytes; using (var rsaEncryptor = new RSACryptoServiceProvider()) { var passwordBytes = Encoding.ASCII.GetBytes(this.Password); var rsaParameters = rsaEncryptor.ExportParameters(false); rsaParameters.Exponent = Util.HexStringToByteArray(rsaResponse.Exponent); rsaParameters.Modulus = Util.HexStringToByteArray(rsaResponse.Modulus); rsaEncryptor.ImportParameters(rsaParameters); encryptedPasswordBytes = rsaEncryptor.Encrypt(passwordBytes, false); } string encryptedPassword = Convert.ToBase64String(encryptedPasswordBytes); postData.Clear(); postData.Add("username", this.Username); postData.Add("password", encryptedPassword); postData.Add("twofactorcode", this.TwoFactorCode ?? ""); postData.Add("captchagid", this.RequiresCaptcha ? this.CaptchaGID : "-1"); postData.Add("captcha_text", this.RequiresCaptcha ? this.CaptchaText : ""); postData.Add("emailsteamid", (this.Requires2FA || this.RequiresEmail) ? this.SteamID.ToString() : ""); postData.Add("emailauth", this.RequiresEmail ? this.EmailCode : ""); postData.Add("rsatimestamp", rsaResponse.Timestamp); postData.Add("remember_login", "false"); postData.Add("oauth_client_id", "DE45CD61"); postData.Add("oauth_scope", "read_profile write_profile read_client write_client"); postData.Add("loginfriendlyname", "#login_emailauth_friendlyname_mobile"); postData.Add("donotcache", Util.GetSystemUnixTime().ToString()); response = SteamWeb.MobileLoginRequest(APIEndpoints.COMMUNITY_BASE + "/login/dologin", "POST", postData, cookies); if (response == null) { return(LoginResult.GeneralFailure); } var loginResponse = JsonConvert.DeserializeObject <LoginResponse>(response); if (loginResponse.Message != null && loginResponse.Message.Contains("Incorrect login")) { return(LoginResult.BadCredentials); } if (loginResponse.CaptchaNeeded) { this.RequiresCaptcha = true; this.CaptchaGID = loginResponse.CaptchaGID; return(LoginResult.NeedCaptcha); } if (loginResponse.EmailAuthNeeded) { this.RequiresEmail = true; this.SteamID = loginResponse.EmailSteamID; return(LoginResult.NeedEmail); } if (loginResponse.TwoFactorNeeded && !loginResponse.Success) { this.Requires2FA = true; return(LoginResult.Need2FA); } if (loginResponse.Message != null && loginResponse.Message.Contains("too many login failures")) { return(LoginResult.TooManyFailedLogins); } if (loginResponse.OAuthData == null || loginResponse.OAuthData.OAuthToken == null || loginResponse.OAuthData.OAuthToken.Length == 0) { return(LoginResult.GeneralFailure); } if (!loginResponse.LoginComplete) { return(LoginResult.BadCredentials); } else { var readableCookies = cookies.GetCookies(new Uri("https://steamcommunity.com")); var oAuthData = loginResponse.OAuthData; SessionData session = new SessionData(); session.OAuthToken = oAuthData.OAuthToken; session.SteamID = oAuthData.SteamID; session.SteamLogin = session.SteamID + "%7C%7C" + oAuthData.SteamLogin; session.SteamLoginSecure = session.SteamID + "%7C%7C" + oAuthData.SteamLoginSecure; session.WebCookie = oAuthData.Webcookie; session.SessionID = readableCookies["sessionid"].Value; this.Session = session; this.LoggedIn = true; return(LoginResult.LoginOkay); } return(LoginResult.GeneralFailure); }
public FinalizeResult FinalizeAddAuthenticator(string smsCode) { //The act of checking the SMS code is necessary for Steam to finalize adding the phone number to the account. //Of course, we only want to check it if we're adding a phone number in the first place... if (!String.IsNullOrEmpty(this.PhoneNumber) && !this._checkSMSCode(smsCode)) { return(FinalizeResult.BadSMSCode); } var postData = new NameValueCollection(); postData.Add("steamid", _session.SteamID.ToString()); postData.Add("access_token", _session.OAuthToken); postData.Add("activation_code", smsCode); int tries = 0; while (tries <= 30) { postData.Set("authenticator_code", LinkedAccount.GenerateSteamGuardCode()); postData.Set("authenticator_time", TimeAligner.GetSteamTime().ToString()); string response = SteamWeb.MobileLoginRequest(APIEndpoints.STEAMAPI_BASE + "/ITwoFactorService/FinalizeAddAuthenticator/v0001", "POST", postData); if (response == null) { return(FinalizeResult.GeneralFailure); } var finalizeResponse = JsonConvert.DeserializeObject <FinalizeAuthenticatorResponse>(response); if (finalizeResponse == null || finalizeResponse.Response == null) { return(FinalizeResult.GeneralFailure); } if (finalizeResponse.Response.Status == 89) { return(FinalizeResult.BadSMSCode); } if (finalizeResponse.Response.Status == 88) { if (tries >= 30) { return(FinalizeResult.UnableToGenerateCorrectCodes); } } if (!finalizeResponse.Response.Success) { return(FinalizeResult.GeneralFailure); } if (finalizeResponse.Response.WantMore) { tries++; continue; } this.LinkedAccount.FullyEnrolled = true; return(FinalizeResult.Success); } return(FinalizeResult.GeneralFailure); }