Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// <summary>
- /// enroll the authenticator with the server
- /// </summary>
- public bool Enroll(EnrollState state)
- {
- // clear error
- state.Error = null;
- try
- {
- var data = new NameValueCollection();
- var cookies = state.Cookies = state.Cookies ?? new CookieContainer();
- string response;
- if (string.IsNullOrEmpty(state.OAuthToken) == true)
- {
- // get session
- if (cookies.Count == 0)
- {
- cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("mobileClientVersion", "3067969+%282.1.3%29"));
- cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("mobileClient", "android"));
- cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("steamid", ""));
- cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("steamLogin", ""));
- cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("Steam_Language", "english"));
- cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("dob", ""));
- NameValueCollection headers = new NameValueCollection();
- headers.Add("X-Requested-With", "com.valvesoftware.android.steam.community");
- response = Request("https://steamcommunity.com/mobilelogin?oauth_client_id=DE45CD61&oauth_scope=read_profile%20write_profile%20read_client%20write_client", "GET", null, cookies, headers);
- }
- // Steam strips any non-ascii chars from username and password
- state.Username = Regex.Replace(state.Username, @"[^\u0000-\u007F]", string.Empty);
- state.Password = Regex.Replace(state.Password, @"[^\u0000-\u007F]", string.Empty);
- // get the user's RSA key
- data.Add("username", state.Username);
- response = Request(COMMUNITY_BASE + "/mobilelogin/getrsakey", "POST", data, cookies);
- var rsaresponse = JObject.Parse(response);
- if (rsaresponse.SelectToken("success").Value<bool>() != true)
- {
- throw new InvalidenrollResponseException("Cannot get steam information for user: " + state.Username);
- }
- // encrypt password with RSA key
- RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
- byte[] encryptedPassword;
- using (var rsa = new RSACryptoServiceProvider())
- {
- var passwordBytes = Encoding.ASCII.GetBytes(state.Password);
- var p = rsa.ExportParameters(false);
- p.Exponent = Authenticator.StringToByteArray(rsaresponse.SelectToken("publickey_exp").Value<string>());
- p.Modulus = Authenticator.StringToByteArray(rsaresponse.SelectToken("publickey_mod").Value<string>());
- rsa.ImportParameters(p);
- encryptedPassword = rsa.Encrypt(passwordBytes, false);
- }
- // login request
- data = new NameValueCollection();
- data.Add("password", Convert.ToBase64String(encryptedPassword));
- data.Add("username", state.Username);
- data.Add("twofactorcode", "");
- data.Add("emailauth", (state.EmailAuthText != null ? state.EmailAuthText : string.Empty));
- data.Add("loginfriendlyname", "#login_emailauth_friendlyname_mobile");
- data.Add("captchagid", (state.CaptchaId != null ? state.CaptchaId : "-1"));
- data.Add("captcha_text", (state.CaptchaText != null ? state.CaptchaText : "enter above characters"));
- data.Add("emailsteamid", (state.EmailAuthText != null ? state.SteamId ?? string.Empty : string.Empty));
- data.Add("rsatimestamp", rsaresponse.SelectToken("timestamp").Value<string>());
- data.Add("remember_login", "false");
- data.Add("oauth_client_id", "DE45CD61");
- data.Add("oauth_scope", "read_profile write_profile read_client write_client");
- data.Add("donotache", new DateTime().ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds.ToString());
- response = Request(COMMUNITY_BASE + "/mobilelogin/dologin/", "POST", data, cookies);
- Dictionary<string, object> loginresponse = JsonConvert.DeserializeObject<Dictionary<string, object>>(response);
- if (loginresponse.ContainsKey("emailsteamid") == true)
- {
- state.SteamId = loginresponse["emailsteamid"] as string;
- }
- // require captcha
- if (loginresponse.ContainsKey("captcha_needed") == true && (bool)loginresponse["captcha_needed"] == true)
- {
- state.RequiresCaptcha = true;
- state.CaptchaId = (string)loginresponse["captcha_gid"];
- state.CaptchaUrl = COMMUNITY_BASE + "/public/captcha.php?gid=" + state.CaptchaId;
- }
- else
- {
- state.RequiresCaptcha = false;
- state.CaptchaId = null;
- state.CaptchaUrl = null;
- state.CaptchaText = null;
- }
- // require email auth
- if (loginresponse.ContainsKey("emailauth_needed") == true && (bool)loginresponse["emailauth_needed"] == true)
- {
- if (loginresponse.ContainsKey("emaildomain") == true)
- {
- var emaildomain = (string)loginresponse["emaildomain"];
- if (string.IsNullOrEmpty(emaildomain) == false)
- {
- state.EmailDomain = emaildomain;
- }
- }
- state.RequiresEmailAuth = true;
- }
- else
- {
- state.EmailDomain = null;
- state.RequiresEmailAuth = false;
- }
- // require email auth
- if (loginresponse.ContainsKey("requires_twofactor") == true && (bool)loginresponse["requires_twofactor"] == true)
- {
- state.Requires2FA = true;
- }
- else
- {
- state.Requires2FA = false;
- }
- // if we didn't login, return the result
- if (loginresponse.ContainsKey("login_complete") == false || (bool)loginresponse["login_complete"] == false || loginresponse.ContainsKey("oauth") == false)
- {
- if (loginresponse.ContainsKey("oauth") == false)
- {
- state.Error = "Invalid response from Steam (No OAuth token)";
- }
- if (loginresponse.ContainsKey("message") == true)
- {
- state.Error = (string)loginresponse["message"];
- }
- return false;
- }
- // get the OAuth token - is stringified json
- string oauth = (string)loginresponse["oauth"];
- var oauthjson = JObject.Parse(oauth);
- state.OAuthToken = oauthjson.SelectToken("oauth_token").Value<string>();
- if (oauthjson.SelectToken("steamid") != null)
- {
- state.SteamId = oauthjson.SelectToken("steamid").Value<string>();
- }
- }
- // login to webapi
- data.Clear();
- data.Add("access_token", state.OAuthToken);
- response = Request(WEBAPI_BASE + "/ISteamWebUserPresenceOAuth/Logon/v0001", "POST", data);
- var sessionid = cookies.GetCookies(new Uri(COMMUNITY_BASE + "/"))["sessionid"].Value;
- if (state.RequiresActivation == false)
- {
- data.Clear();
- data.Add("op", "has_phone");
- data.Add("arg", "null");
- data.Add("sessionid", sessionid);
- response = Request(COMMUNITY_BASE + "/steamguard/phoneajax", "POST", data, cookies);
- var jsonresponse = JObject.Parse(response);
- bool hasPhone = jsonresponse.SelectToken("has_phone").Value<Boolean>();
- if (hasPhone == false)
- {
- state.OAuthToken = null; // force new login
- state.RequiresLogin = true;
- state.Cookies = null;
- state.Error = "Your Steam account must have a SMS-capable phone number attached. Go into Account Details of the Steam client or Steam website and click Add a Phone Number.";
- return false;
- }
- //response = Request(COMMUNITY_BASE + "/steamguard/phone_checksms?bForTwoFactor=1&bRevoke2fOnCancel=", "GET", null, cookies);
- // add a new authenticator
- data.Clear();
- string deviceId = BuildRandomId();
- data.Add("access_token", state.OAuthToken);
- data.Add("steamid", state.SteamId);
- data.Add("authenticator_type", "1");
- data.Add("device_identifier", deviceId);
- data.Add("sms_phone_id", "1");
- response = Request(WEBAPI_BASE + "/ITwoFactorService/AddAuthenticator/v0001", "POST", data);
- var tfaresponse = JObject.Parse(response);
- if (response.IndexOf("status") == -1 && tfaresponse.SelectToken("response.status").Value<int>() == 84)
- {
- // invalid response
- state.OAuthToken = null; // force new login
- state.RequiresLogin = true;
- state.Cookies = null;
- state.Error = "Unable to send SMS. Check your phone is registered on your Steam account.";
- return false;
- }
- if (response.IndexOf("shared_secret") == -1)
- {
- // invalid response
- state.OAuthToken = null; // force new login
- state.RequiresLogin = true;
- state.Cookies = null;
- state.Error = "Invalid response from Steam: " + response;
- return false;
- }
- // save data into this authenticator
- var secret = tfaresponse.SelectToken("response.shared_secret").Value<string>();
- this.SecretKey = Convert.FromBase64String(secret);
- this.Serial = tfaresponse.SelectToken("response.serial_number").Value<string>();
- this.DeviceId = deviceId;
- state.RevocationCode = tfaresponse.SelectToken("response.revocation_code").Value<string>();
- // add the steamid into the data
- var steamdata = JObject.Parse(tfaresponse.SelectToken("response").ToString());
- if (steamdata.SelectToken("steamid") == null)
- {
- steamdata.Add("steamid", state.SteamId);
- }
- if (steamdata.SelectToken("steamguard_scheme") == null)
- {
- steamdata.Add("steamguard_scheme", "2");
- }
- this.SteamData = steamdata.ToString(Newtonsoft.Json.Formatting.None);
- // calculate server drift
- long servertime = tfaresponse.SelectToken("response.server_time").Value<long>() * 1000;
- ServerTimeDiff = servertime - CurrentTime;
- LastServerTime = DateTime.Now.Ticks;
- state.RequiresActivation = true;
- return false;
- }
- // finalize adding the authenticator
- data.Clear();
- data.Add("access_token", state.OAuthToken);
- data.Add("steamid", state.SteamId);
- data.Add("activation_code", state.ActivationCode);
- // try and authorise
- var retries = 0;
- while (state.RequiresActivation == true && retries < enroll_ACTIVATE_RETRIES)
- {
- data.Add("authenticator_code", this.CalculateCode(false));
- data.Add("authenticator_time", this.ServerTime.ToString());
- response = Request(WEBAPI_BASE + "/ITwoFactorService/FinalizeAddAuthenticator/v0001", "POST", data);
- var finalizeresponse = JObject.Parse(response);
- if (response.IndexOf("status") != -1 && finalizeresponse.SelectToken("response.status").Value<int>() == INVALID_ACTIVATION_CODE)
- {
- state.Error = "Invalid activation code";
- return false;
- }
- // reset our time
- if (response.IndexOf("server_time") != -1)
- {
- long servertime = finalizeresponse.SelectToken("response.server_time").Value<long>() * 1000;
- ServerTimeDiff = servertime - CurrentTime;
- LastServerTime = DateTime.Now.Ticks;
- }
- // check success
- if (finalizeresponse.SelectToken("response.success").Value<bool>() == true)
- {
- if (response.IndexOf("want_more") != -1 && finalizeresponse.SelectToken("response.want_more").Value<bool>() == true)
- {
- ServerTimeDiff += 30000L;
- retries++;
- continue;
- }
- state.RequiresActivation = false;
- break;
- }
- ServerTimeDiff += 30000L;
- retries++;
- }
- if (state.RequiresActivation == true)
- {
- state.Error = "There was a problem activating. There might be an issue with the Steam servers. Please try again later.";
- return false;
- }
- // mark and successful and return key
- state.Success = true;
- state.SecretKey = Authenticator.ByteArrayToString(this.SecretKey);
- // send confirmation email
- data.Clear();
- data.Add("access_token", state.OAuthToken);
- data.Add("steamid", state.SteamId);
- data.Add("email_type", "2");
- response = Request(WEBAPI_BASE + "/ITwoFactorService/SendEmail/v0001", "POST", data);
- return true;
- }
- catch (UnauthorisedRequestException ex)
- {
- throw new InvalidenrollResponseException("You are not allowed to add an authenticator. Have you enabled 'community-generated content' in Family View?", ex);
- }
- catch (InvalidRequestException ex)
- {
- throw new InvalidenrollResponseException("Error enrolling new authenticator", ex);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement