Advertisement
Guest User

Untitled

a guest
May 31st, 2017
1,347
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.09 KB | None | 0 0
  1.  
  2.         /// <summary>
  3.         /// enroll the authenticator with the server
  4.         /// </summary>
  5.         public bool Enroll(EnrollState state)
  6.         {
  7.             // clear error
  8.             state.Error = null;
  9.  
  10.             try
  11.             {
  12.                 var data = new NameValueCollection();
  13.                 var cookies = state.Cookies = state.Cookies ?? new CookieContainer();
  14.                 string response;
  15.  
  16.                 if (string.IsNullOrEmpty(state.OAuthToken) == true)
  17.                 {
  18.                     // get session
  19.                     if (cookies.Count == 0)
  20.                     {
  21.                         cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("mobileClientVersion", "3067969+%282.1.3%29"));
  22.                         cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("mobileClient", "android"));
  23.                         cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("steamid", ""));
  24.                         cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("steamLogin", ""));
  25.                         cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("Steam_Language", "english"));
  26.                         cookies.Add(new Uri(COMMUNITY_BASE + "/"), new Cookie("dob", ""));
  27.  
  28.                         NameValueCollection headers = new NameValueCollection();
  29.                         headers.Add("X-Requested-With", "com.valvesoftware.android.steam.community");
  30.  
  31.                         response = Request("https://steamcommunity.com/mobilelogin?oauth_client_id=DE45CD61&oauth_scope=read_profile%20write_profile%20read_client%20write_client", "GET", null, cookies, headers);
  32.                     }
  33.  
  34.                     // Steam strips any non-ascii chars from username and password
  35.                     state.Username = Regex.Replace(state.Username, @"[^\u0000-\u007F]", string.Empty);
  36.                     state.Password = Regex.Replace(state.Password, @"[^\u0000-\u007F]", string.Empty);
  37.  
  38.                     // get the user's RSA key
  39.                     data.Add("username", state.Username);
  40.                     response = Request(COMMUNITY_BASE + "/mobilelogin/getrsakey", "POST", data, cookies);
  41.                     var rsaresponse = JObject.Parse(response);
  42.                     if (rsaresponse.SelectToken("success").Value<bool>() != true)
  43.                     {
  44.                         throw new InvalidenrollResponseException("Cannot get steam information for user: " + state.Username);
  45.                     }
  46.  
  47.                     // encrypt password with RSA key
  48.                     RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
  49.                     byte[] encryptedPassword;
  50.                     using (var rsa = new RSACryptoServiceProvider())
  51.                     {
  52.                         var passwordBytes = Encoding.ASCII.GetBytes(state.Password);
  53.                         var p = rsa.ExportParameters(false);
  54.                         p.Exponent = Authenticator.StringToByteArray(rsaresponse.SelectToken("publickey_exp").Value<string>());
  55.                         p.Modulus = Authenticator.StringToByteArray(rsaresponse.SelectToken("publickey_mod").Value<string>());
  56.                         rsa.ImportParameters(p);
  57.                         encryptedPassword = rsa.Encrypt(passwordBytes, false);
  58.                     }
  59.  
  60.                     // login request
  61.                     data = new NameValueCollection();
  62.                     data.Add("password", Convert.ToBase64String(encryptedPassword));
  63.                     data.Add("username", state.Username);
  64.                     data.Add("twofactorcode", "");
  65.                     data.Add("emailauth", (state.EmailAuthText != null ? state.EmailAuthText : string.Empty));
  66.                     data.Add("loginfriendlyname", "#login_emailauth_friendlyname_mobile");
  67.                     data.Add("captchagid", (state.CaptchaId != null ? state.CaptchaId : "-1"));
  68.                     data.Add("captcha_text", (state.CaptchaText != null ? state.CaptchaText : "enter above characters"));
  69.                     data.Add("emailsteamid", (state.EmailAuthText != null ? state.SteamId ?? string.Empty : string.Empty));
  70.                     data.Add("rsatimestamp", rsaresponse.SelectToken("timestamp").Value<string>());
  71.                     data.Add("remember_login", "false");
  72.                     data.Add("oauth_client_id", "DE45CD61");
  73.                     data.Add("oauth_scope", "read_profile write_profile read_client write_client");
  74.                     data.Add("donotache", new DateTime().ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds.ToString());
  75.                     response = Request(COMMUNITY_BASE + "/mobilelogin/dologin/", "POST", data, cookies);
  76.                     Dictionary<string, object> loginresponse = JsonConvert.DeserializeObject<Dictionary<string, object>>(response);
  77.  
  78.                     if (loginresponse.ContainsKey("emailsteamid") == true)
  79.                     {
  80.                         state.SteamId = loginresponse["emailsteamid"] as string;
  81.                     }
  82.  
  83.                     // require captcha
  84.                     if (loginresponse.ContainsKey("captcha_needed") == true && (bool)loginresponse["captcha_needed"] == true)
  85.                     {
  86.                         state.RequiresCaptcha = true;
  87.                         state.CaptchaId = (string)loginresponse["captcha_gid"];
  88.                         state.CaptchaUrl = COMMUNITY_BASE + "/public/captcha.php?gid=" + state.CaptchaId;
  89.                     }
  90.                     else
  91.                     {
  92.                         state.RequiresCaptcha = false;
  93.                         state.CaptchaId = null;
  94.                         state.CaptchaUrl = null;
  95.                         state.CaptchaText = null;
  96.                     }
  97.  
  98.                     // require email auth
  99.                     if (loginresponse.ContainsKey("emailauth_needed") == true && (bool)loginresponse["emailauth_needed"] == true)
  100.                     {
  101.                         if (loginresponse.ContainsKey("emaildomain") == true)
  102.                         {
  103.                             var emaildomain = (string)loginresponse["emaildomain"];
  104.                             if (string.IsNullOrEmpty(emaildomain) == false)
  105.                             {
  106.                                 state.EmailDomain = emaildomain;
  107.                             }
  108.                         }
  109.                         state.RequiresEmailAuth = true;
  110.                     }
  111.                     else
  112.                     {
  113.                         state.EmailDomain = null;
  114.                         state.RequiresEmailAuth = false;
  115.                     }
  116.  
  117.                     // require email auth
  118.                     if (loginresponse.ContainsKey("requires_twofactor") == true && (bool)loginresponse["requires_twofactor"] == true)
  119.                     {
  120.                         state.Requires2FA = true;
  121.                     }
  122.                     else
  123.                     {
  124.                         state.Requires2FA = false;
  125.                     }
  126.  
  127.                     // if we didn't login, return the result
  128.                     if (loginresponse.ContainsKey("login_complete") == false || (bool)loginresponse["login_complete"] == false || loginresponse.ContainsKey("oauth") == false)
  129.                     {
  130.                         if (loginresponse.ContainsKey("oauth") == false)
  131.                         {
  132.                             state.Error = "Invalid response from Steam (No OAuth token)";
  133.                         }
  134.                         if (loginresponse.ContainsKey("message") == true)
  135.                         {
  136.                             state.Error = (string)loginresponse["message"];
  137.                         }
  138.                         return false;
  139.                     }
  140.  
  141.                     // get the OAuth token - is stringified json
  142.                     string oauth = (string)loginresponse["oauth"];
  143.                     var oauthjson = JObject.Parse(oauth);
  144.                     state.OAuthToken = oauthjson.SelectToken("oauth_token").Value<string>();
  145.                     if (oauthjson.SelectToken("steamid") != null)
  146.                     {
  147.                         state.SteamId = oauthjson.SelectToken("steamid").Value<string>();
  148.                     }
  149.                 }
  150.  
  151.                 // login to webapi
  152.                 data.Clear();
  153.                 data.Add("access_token", state.OAuthToken);
  154.                 response = Request(WEBAPI_BASE + "/ISteamWebUserPresenceOAuth/Logon/v0001", "POST", data);
  155.  
  156.                 var sessionid = cookies.GetCookies(new Uri(COMMUNITY_BASE + "/"))["sessionid"].Value;
  157.  
  158.                 if (state.RequiresActivation == false)
  159.                 {
  160.                     data.Clear();
  161.                     data.Add("op", "has_phone");
  162.                     data.Add("arg", "null");
  163.                     data.Add("sessionid", sessionid);
  164.  
  165.                     response = Request(COMMUNITY_BASE + "/steamguard/phoneajax", "POST", data, cookies);
  166.                     var jsonresponse = JObject.Parse(response);
  167.                     bool hasPhone = jsonresponse.SelectToken("has_phone").Value<Boolean>();
  168.                     if (hasPhone == false)
  169.                     {
  170.                         state.OAuthToken = null; // force new login
  171.                         state.RequiresLogin = true;
  172.                         state.Cookies = null;
  173.                         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.";
  174.                         return false;
  175.                     }
  176.  
  177.                     //response = Request(COMMUNITY_BASE + "/steamguard/phone_checksms?bForTwoFactor=1&bRevoke2fOnCancel=", "GET", null, cookies);
  178.  
  179.                     // add a new authenticator
  180.                     data.Clear();
  181.                     string deviceId = BuildRandomId();
  182.                     data.Add("access_token", state.OAuthToken);
  183.                     data.Add("steamid", state.SteamId);
  184.                     data.Add("authenticator_type", "1");
  185.                     data.Add("device_identifier", deviceId);
  186.                     data.Add("sms_phone_id", "1");
  187.                     response = Request(WEBAPI_BASE + "/ITwoFactorService/AddAuthenticator/v0001", "POST", data);
  188.                     var tfaresponse = JObject.Parse(response);
  189.                     if (response.IndexOf("status") == -1 && tfaresponse.SelectToken("response.status").Value<int>() == 84)
  190.                     {
  191.                         // invalid response
  192.                         state.OAuthToken = null; // force new login
  193.                         state.RequiresLogin = true;
  194.                         state.Cookies = null;
  195.                         state.Error = "Unable to send SMS. Check your phone is registered on your Steam account.";
  196.                         return false;
  197.                     }
  198.                     if (response.IndexOf("shared_secret") == -1)
  199.                     {
  200.                         // invalid response
  201.                         state.OAuthToken = null; // force new login
  202.                         state.RequiresLogin = true;
  203.                         state.Cookies = null;
  204.                         state.Error = "Invalid response from Steam: " + response;
  205.                         return false;
  206.                     }
  207.  
  208.                     // save data into this authenticator
  209.                     var secret = tfaresponse.SelectToken("response.shared_secret").Value<string>();
  210.                     this.SecretKey = Convert.FromBase64String(secret);
  211.                     this.Serial = tfaresponse.SelectToken("response.serial_number").Value<string>();
  212.                     this.DeviceId = deviceId;
  213.                     state.RevocationCode = tfaresponse.SelectToken("response.revocation_code").Value<string>();
  214.  
  215.                     // add the steamid into the data
  216.                     var steamdata = JObject.Parse(tfaresponse.SelectToken("response").ToString());
  217.                     if (steamdata.SelectToken("steamid") == null)
  218.                     {
  219.                         steamdata.Add("steamid", state.SteamId);
  220.                     }
  221.                     if (steamdata.SelectToken("steamguard_scheme") == null)
  222.                     {
  223.                         steamdata.Add("steamguard_scheme", "2");
  224.                     }
  225.                     this.SteamData = steamdata.ToString(Newtonsoft.Json.Formatting.None);
  226.  
  227.                     // calculate server drift
  228.                     long servertime = tfaresponse.SelectToken("response.server_time").Value<long>() * 1000;
  229.                     ServerTimeDiff = servertime - CurrentTime;
  230.                     LastServerTime = DateTime.Now.Ticks;
  231.  
  232.                     state.RequiresActivation = true;
  233.  
  234.                     return false;
  235.                 }
  236.  
  237.                 // finalize adding the authenticator
  238.                 data.Clear();
  239.                 data.Add("access_token", state.OAuthToken);
  240.                 data.Add("steamid", state.SteamId);
  241.                 data.Add("activation_code", state.ActivationCode);
  242.  
  243.                 // try and authorise
  244.                 var retries = 0;
  245.                 while (state.RequiresActivation == true && retries < enroll_ACTIVATE_RETRIES)
  246.                 {
  247.                     data.Add("authenticator_code", this.CalculateCode(false));
  248.                     data.Add("authenticator_time", this.ServerTime.ToString());
  249.                     response = Request(WEBAPI_BASE + "/ITwoFactorService/FinalizeAddAuthenticator/v0001", "POST", data);
  250.                     var finalizeresponse = JObject.Parse(response);
  251.                     if (response.IndexOf("status") != -1 && finalizeresponse.SelectToken("response.status").Value<int>() == INVALID_ACTIVATION_CODE)
  252.                     {
  253.                         state.Error = "Invalid activation code";
  254.                         return false;
  255.                     }
  256.  
  257.                     // reset our time
  258.                     if (response.IndexOf("server_time") != -1)
  259.                     {
  260.                         long servertime = finalizeresponse.SelectToken("response.server_time").Value<long>() * 1000;
  261.                         ServerTimeDiff = servertime - CurrentTime;
  262.                         LastServerTime = DateTime.Now.Ticks;
  263.                     }
  264.  
  265.                     // check success
  266.                     if (finalizeresponse.SelectToken("response.success").Value<bool>() == true)
  267.                     {
  268.                         if (response.IndexOf("want_more") != -1 && finalizeresponse.SelectToken("response.want_more").Value<bool>() == true)
  269.                         {
  270.                             ServerTimeDiff += 30000L;
  271.                             retries++;
  272.                             continue;
  273.                         }
  274.                         state.RequiresActivation = false;
  275.                         break;
  276.                     }
  277.  
  278.                     ServerTimeDiff += 30000L;
  279.                     retries++;
  280.                 }
  281.                 if (state.RequiresActivation == true)
  282.                 {
  283.                     state.Error = "There was a problem activating. There might be an issue with the Steam servers. Please try again later.";
  284.                     return false;
  285.                 }
  286.  
  287.                 // mark and successful and return key
  288.                 state.Success = true;
  289.                 state.SecretKey = Authenticator.ByteArrayToString(this.SecretKey);
  290.  
  291.                 // send confirmation email
  292.                 data.Clear();
  293.                 data.Add("access_token", state.OAuthToken);
  294.                 data.Add("steamid", state.SteamId);
  295.                 data.Add("email_type", "2");
  296.                 response = Request(WEBAPI_BASE + "/ITwoFactorService/SendEmail/v0001", "POST", data);
  297.  
  298.                 return true;
  299.             }
  300.             catch (UnauthorisedRequestException ex)
  301.             {
  302.                 throw new InvalidenrollResponseException("You are not allowed to add an authenticator. Have you enabled 'community-generated content' in Family View?", ex);
  303.             }
  304.             catch (InvalidRequestException ex)
  305.             {
  306.                 throw new InvalidenrollResponseException("Error enrolling new authenticator", ex);
  307.             }
  308.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement