├── .gitattributes ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── Steam Desktop Authenticator ├── App.config ├── BrowserRequestHandler.cs ├── CaptchaForm.Designer.cs ├── CaptchaForm.cs ├── CaptchaForm.resx ├── CommandLineOptions.cs ├── ConfirmationFormWeb.Designer.cs ├── ConfirmationFormWeb.cs ├── ConfirmationFormWeb.resx ├── DeleteAllCookiesVisitor.cs ├── FileEncryptor.cs ├── ImportAccountForm.Designer.cs ├── ImportAccountForm.cs ├── ImportAccountForm.resx ├── InputForm.Designer.cs ├── InputForm.cs ├── InputForm.resx ├── InstallRedistribForm.Designer.cs ├── InstallRedistribForm.cs ├── InstallRedistribForm.resx ├── ListInputForm.Designer.cs ├── ListInputForm.cs ├── ListInputForm.resx ├── LoginForm.Designer.cs ├── LoginForm.cs ├── LoginForm.resx ├── MaFileEncryptedException.cs ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── Manifest.cs ├── ManifestParseException.cs ├── PhoneBridge.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── ResourceResponseFilter.cs ├── SettingsForm.Designer.cs ├── SettingsForm.cs ├── SettingsForm.resx ├── Steam Desktop Authenticator.csproj ├── Steam Desktop Authenticator.sln ├── TradePopupForm.Designer.cs ├── TradePopupForm.cs ├── TradePopupForm.resx ├── WelcomeForm.Designer.cs ├── WelcomeForm.cs ├── WelcomeForm.resx ├── icon.ico └── packages.config ├── icon.png ├── lib └── SteamAuth │ ├── LICENSE │ ├── README.md │ ├── SteamAuth │ ├── APIEndpoints.cs │ ├── AuthenticatorLinker.cs │ ├── Confirmation.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SessionData.cs │ ├── SteamAuth.csproj │ ├── SteamAuth.sln │ ├── SteamGuardAccount.cs │ ├── SteamGuardAccount.cs.txt │ ├── SteamWeb.cs │ ├── TimeAligner.cs │ ├── UserLogin.cs │ ├── Util.cs │ ├── bin │ │ └── Debug │ │ │ └── netstandard2.0 │ │ │ ├── SteamAuth.deps.json │ │ │ ├── SteamAuth.dll │ │ │ └── SteamAuth.pdb │ └── obj │ │ ├── Debug │ │ └── netstandard2.0 │ │ │ ├── SteamAuth.AssemblyInfo.cs │ │ │ ├── SteamAuth.AssemblyInfoInputs.cache │ │ │ ├── SteamAuth.GeneratedMSBuildEditorConfig.editorconfig │ │ │ ├── SteamAuth.assets.cache │ │ │ ├── SteamAuth.csproj.AssemblyReference.cache │ │ │ ├── SteamAuth.csproj.CoreCompileInputs.cache │ │ │ ├── SteamAuth.csproj.FileListAbsolute.txt │ │ │ ├── SteamAuth.dll │ │ │ └── SteamAuth.pdb │ │ ├── SteamAuth.csproj.nuget.dgspec.json │ │ ├── SteamAuth.csproj.nuget.g.props │ │ ├── SteamAuth.csproj.nuget.g.targets │ │ ├── project.assets.json │ │ └── project.nuget.cache │ └── TestBed │ ├── App.config │ ├── Program.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── TestBed.csproj │ └── packages.config └── prepare-release.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Coverlet is a free, cross platform Code Coverage Tool 141 | coverage*[.json, .xml, .info] 142 | 143 | # Visual Studio code coverage results 144 | *.coverage 145 | *.coveragexml 146 | 147 | # NCrunch 148 | _NCrunch_* 149 | .*crunch*.local.xml 150 | nCrunchTemp_* 151 | 152 | # MightyMoose 153 | *.mm.* 154 | AutoTest.Net/ 155 | 156 | # Web workbench (sass) 157 | .sass-cache/ 158 | 159 | # Installshield output folder 160 | [Ee]xpress/ 161 | 162 | # DocProject is a documentation generator add-in 163 | DocProject/buildhelp/ 164 | DocProject/Help/*.HxT 165 | DocProject/Help/*.HxC 166 | DocProject/Help/*.hhc 167 | DocProject/Help/*.hhk 168 | DocProject/Help/*.hhp 169 | DocProject/Help/Html2 170 | DocProject/Help/html 171 | 172 | # Click-Once directory 173 | publish/ 174 | 175 | # Publish Web Output 176 | *.[Pp]ublish.xml 177 | *.azurePubxml 178 | # Note: Comment the next line if you want to checkin your web deploy settings, 179 | # but database connection strings (with potential passwords) will be unencrypted 180 | *.pubxml 181 | *.publishproj 182 | 183 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 184 | # checkin your Azure Web App publish settings, but sensitive information contained 185 | # in these scripts will be unencrypted 186 | PublishScripts/ 187 | 188 | # NuGet Packages 189 | *.nupkg 190 | # NuGet Symbol Packages 191 | *.snupkg 192 | # The packages folder can be ignored because of Package Restore 193 | **/[Pp]ackages/* 194 | # except build/, which is used as an MSBuild target. 195 | !**/[Pp]ackages/build/ 196 | # Uncomment if necessary however generally it will be regenerated when needed 197 | #!**/[Pp]ackages/repositories.config 198 | # NuGet v3's project.json files produces more ignorable files 199 | *.nuget.props 200 | *.nuget.targets 201 | 202 | # Microsoft Azure Build Output 203 | csx/ 204 | *.build.csdef 205 | 206 | # Microsoft Azure Emulator 207 | ecf/ 208 | rcf/ 209 | 210 | # Windows Store app package directories and files 211 | AppPackages/ 212 | BundleArtifacts/ 213 | Package.StoreAssociation.xml 214 | _pkginfo.txt 215 | *.appx 216 | *.appxbundle 217 | *.appxupload 218 | 219 | # Visual Studio cache files 220 | # files ending in .cache can be ignored 221 | *.[Cc]ache 222 | # but keep track of directories ending in .cache 223 | !?*.[Cc]ache/ 224 | 225 | # Others 226 | ClientBin/ 227 | ~$* 228 | *~ 229 | *.dbmdl 230 | *.dbproj.schemaview 231 | *.jfm 232 | *.pfx 233 | *.publishsettings 234 | orleans.codegen.cs 235 | 236 | # Including strong name files can present a security risk 237 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 238 | #*.snk 239 | 240 | # Since there are multiple workflows, uncomment next line to ignore bower_components 241 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 242 | #bower_components/ 243 | 244 | # RIA/Silverlight projects 245 | Generated_Code/ 246 | 247 | # Backup & report files from converting an old project file 248 | # to a newer Visual Studio version. Backup files are not needed, 249 | # because we have git ;-) 250 | _UpgradeReport_Files/ 251 | Backup*/ 252 | UpgradeLog*.XML 253 | UpgradeLog*.htm 254 | ServiceFabricBackup/ 255 | *.rptproj.bak 256 | 257 | # SQL Server files 258 | *.mdf 259 | *.ldf 260 | *.ndf 261 | 262 | # Business Intelligence projects 263 | *.rdl.data 264 | *.bim.layout 265 | *.bim_*.settings 266 | *.rptproj.rsuser 267 | *- [Bb]ackup.rdl 268 | *- [Bb]ackup ([0-9]).rdl 269 | *- [Bb]ackup ([0-9][0-9]).rdl 270 | 271 | # Microsoft Fakes 272 | FakesAssemblies/ 273 | 274 | # GhostDoc plugin setting file 275 | *.GhostDoc.xml 276 | 277 | # Node.js Tools for Visual Studio 278 | .ntvs_analysis.dat 279 | node_modules/ 280 | 281 | # Visual Studio 6 build log 282 | *.plg 283 | 284 | # Visual Studio 6 workspace options file 285 | *.opt 286 | 287 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 288 | *.vbw 289 | 290 | # Visual Studio LightSwitch build output 291 | **/*.HTMLClient/GeneratedArtifacts 292 | **/*.DesktopClient/GeneratedArtifacts 293 | **/*.DesktopClient/ModelManifest.xml 294 | **/*.Server/GeneratedArtifacts 295 | **/*.Server/ModelManifest.xml 296 | _Pvt_Extensions 297 | 298 | # Paket dependency manager 299 | .paket/paket.exe 300 | paket-files/ 301 | 302 | # FAKE - F# Make 303 | .fake/ 304 | 305 | # CodeRush personal settings 306 | .cr/personal 307 | 308 | # Python Tools for Visual Studio (PTVS) 309 | __pycache__/ 310 | *.pyc 311 | 312 | # Cake - Uncomment if you are using it 313 | # tools/** 314 | # !tools/packages.config 315 | 316 | # Tabs Studio 317 | *.tss 318 | 319 | # Telerik's JustMock configuration file 320 | *.jmconfig 321 | 322 | # BizTalk build output 323 | *.btp.cs 324 | *.btm.cs 325 | *.odx.cs 326 | *.xsd.cs 327 | 328 | # OpenCover UI analysis results 329 | OpenCover/ 330 | 331 | # Azure Stream Analytics local run output 332 | ASALocalRun/ 333 | 334 | # MSBuild Binary and Structured Log 335 | *.binlog 336 | 337 | # NVidia Nsight GPU debugger configuration file 338 | *.nvuser 339 | 340 | # MFractors (Xamarin productivity tool) working folder 341 | .mfractor/ 342 | 343 | # Local History for Visual Studio 344 | .localhistory/ 345 | 346 | # BeatPulse healthcheck temp database 347 | healthchecksdb 348 | 349 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 350 | MigrationBackup/ 351 | 352 | # Ionide (cross platform F# VS Code tools) working folder 353 | .ionide/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/SteamAuth"] 2 | path = lib/SteamAuth 3 | url = git://github.com/geel9/SteamAuth 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jesse Cardone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |
4 | Steam Desktop Authenticator 5 |

6 |

7 | A desktop implementation of Steam's mobile authenticator app.
8 | We are not affiliated with Steam or Scrap.TF in any way! This project is run by community volunteers. 9 |

10 |

11 | WARNING: Recently there have been fake versions of SDA floating around that will steal your Steam account. Never download SDA from any place other than this github repo! 12 |

13 |

14 | Download here 15 | 16 |

17 |

Supports Windows 7 and up.

18 |
19 | 20 | **Clicking "Download ZIP" will not work!** This project uses git submodules so you must use git to download it properly. Using [GitHub Desktop](https://desktop.github.com/) is an easy way to do that. 21 | 22 | **DISCLAIMER: We provide no support for you when using Steam Desktop Authenticator! This project is run by community volunteers and is not affiliated with Steam or Scrap.TF. You use this program at your own risk, and accept the responsibility to make backups and prevent unauthorized access to your computer!** 23 | 24 | **REMEMBER: Always make backups of your `maFiles` directory! If you lose your encryption key or delete `maFiles` by accident AND you didn't save your revocation code, you are screwed.** 25 | 26 | **FINALLY: Using this application is a bad idea, because it COMPLETELY DEFEATS THE PURPOSE of two-factor authentication! If your desktop is infected with a virus, it will be able to hijack the authenticator app and completely subvert the protection. THIS APPLICATION DOES NOT PROTECT YOUR ACCOUNT; IT ONLY ALLOWS YOU TO USE STEAM FEATURES THAT REQUIRE THE AUTHENTICATOR WITHOUT HAVING A PHONE. If you have a phone that supports the Mobile Authenticator, you really shouldn't use this application!** 27 | 28 | IF you lost your `maFiles` OR lost your encryption key, go [here](https://store.steampowered.com/twofactor/manage) and click "Remove Authenticator" then enter your revocation code that you wrote down when you first added your account to SDA. 29 | 30 | If you did not follow the directions and did not write your revocation code down, you're well and truly screwed. The only option is beg to [Steam Support](https://support.steampowered.com/) and say you lost your mobile authenticator and the revocation code. 31 | 32 | ## Detailed setup instructions 33 | - Download & Install [.NET Framework 4.6.2](https://www.microsoft.com/net/download/dotnet-framework-runtime/net462) if you're using Windows 7. Windows 8 and above should do this automatically for you. 34 | - Visit [the releases page](https://github.com/Jessecar96/SteamDesktopAuthenticator/releases) and download the latest .zip (not the source code one). 35 | - Extract the files somewhere very safe on your computer. If you lose the files you can lose access to your Steam account. 36 | - Run `Steam Desktop Authenticator.exe` and click the button to set up a new account. 37 | - Login to Steam and follow the instructions to set it up. **Note: you still need a mobile phone that can receive SMS.** 38 | - You may be asked to set up encryption, this is to make sure if someone gains access to your computer they can't steal your Steam account from this program. This is optional but highly recommended. 39 | - Select your account from the list to view the current login code, and click `Trade Confirmations` to see pending trade confirmations. 40 | - For your safety, remember to get Steam Guard backup codes! Follow [this link](https://store.steampowered.com/twofactor/manage) and click "Get Backup Codes," then print out that page and save it in a safe place. You can use these codes if you lose access to your authenticator. 41 | 42 | [How to update SDA.](https://github.com/Jessecar96/SteamDesktopAuthenticator/wiki/Updating) 43 | 44 | [How to use SDA on multiple computers.](https://github.com/Jessecar96/SteamDesktopAuthenticator/wiki/Using-SDA-on-multiple-computers) 45 | 46 | 47 | ## Command line options 48 | ``` 49 | -k [encryption key] 50 | Set your encryption key when opened 51 | -s 52 | Auto-minimize to tray when opened 53 | ``` 54 | 55 | ## Troubleshooting 56 | - **Trade confirmation list is just white or a blank screen** 57 | - First open the "Selected Account" menu, then click "Force session refresh". If it still doesn't work after that, open the "Selected Account" menu again, then click "Login again" and login to your Steam account. 58 | 59 | If your problem doesn't appear on the list or none of the solutions worked, submit an issue on the issue tracker. When posting logs in an issue, please upload it to some site like [Pastebin](http://www.pastebin.com). 60 | 61 | ## Building on linux 62 | - First, you will need to install the `mono` and `monodevelop` packages, usually available from your standard package repository. 63 | - Open monodevelop and select File -> Open. Navigate to the folder where you cloned this program to and open the file "Steam Desktop Authenticator/Steam Desktop Authenticator.sln" 64 | - If you initialized submodules correctly, you should see two tree hirarchies on the left side of the screen, one labeled **SteamDesktopAuthenticator** and the other **SteamAuth**. (If you didn't, an error will be displayed; go update them!) For both of them, select "Packages", right click on "Newtonsoft.Json", and click update. Remember to do this for **both SteamDesktopAuthenticator and SteamAuth** 65 | - Select Project->Active Configuration->Release (this will make this application run faster) 66 | - Select Build->Build All. The package should now build successfully. 67 | - The resulting executable and files will be in "Steam Desktop Authenticator/bin/Release" 68 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/BrowserRequestHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using CefSharp; 8 | using System.Diagnostics; 9 | using System.IO; 10 | using Newtonsoft.Json; 11 | using System.Security.Cryptography.X509Certificates; 12 | 13 | namespace Steam_Desktop_Authenticator 14 | { 15 | class BrowserRequestHandler : IRequestHandler 16 | { 17 | public string Cookies; 18 | 19 | public static readonly string VersionNumberString = String.Format("Chromium: {0}, CEF: {1}, CefSharp: {2}", 20 | Cef.ChromiumVersion, Cef.CefVersion, Cef.CefSharpVersion); 21 | 22 | bool IRequestHandler.OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect) 23 | { 24 | return false; 25 | } 26 | 27 | bool IRequestHandler.OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) 28 | { 29 | return OnOpenUrlFromTab(browserControl, browser, frame, targetUrl, targetDisposition, userGesture); 30 | } 31 | 32 | protected virtual bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) 33 | { 34 | return false; 35 | } 36 | 37 | bool IRequestHandler.OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback) 38 | { 39 | callback.Dispose(); 40 | return false; 41 | } 42 | 43 | void IRequestHandler.OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath) 44 | { 45 | // TODO: Add your own code here for handling scenarios where a plugin crashed, for one reason or another. 46 | } 47 | 48 | CefReturnValue IRequestHandler.OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) 49 | { 50 | // Check if the session is expired 51 | if (request.Url == "steammobile://lostauth") 52 | { 53 | MessageBox.Show("Failed to load confirmations.\nUse the \"Login again\" option under the \"Selected Account\" menu.", "Confirmations", MessageBoxButtons.OK, MessageBoxIcon.Error); 54 | return CefReturnValue.Cancel; 55 | } 56 | 57 | // For some reason, in order to set cookies manually using a hdeader you need to clear the real cookies every time :/ 58 | Cef.GetGlobalCookieManager().VisitAllCookies(new DeleteAllCookiesVisitor()); 59 | 60 | if (request.Url.StartsWith("steammobile://")) 61 | { 62 | // Cancel all steammobile:// requests (for the app) 63 | return CefReturnValue.Cancel; 64 | } 65 | else 66 | { 67 | var headers = request.Headers; 68 | headers.Add("Cookie", Cookies); 69 | headers.Add("X-Requested-With", "com.valvesoftware.android.steam.community"); 70 | request.Headers = headers; 71 | return CefReturnValue.Continue; 72 | } 73 | } 74 | 75 | bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback) 76 | { 77 | callback.Dispose(); 78 | return false; 79 | } 80 | 81 | void IRequestHandler.OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status) 82 | { 83 | 84 | } 85 | 86 | bool IRequestHandler.OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback) 87 | { 88 | return false; 89 | } 90 | 91 | bool IRequestHandler.OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url) 92 | { 93 | return false; 94 | } 95 | 96 | void IRequestHandler.OnRenderViewReady(IWebBrowser browserControl, IBrowser browser) 97 | { 98 | 99 | } 100 | 101 | bool IRequestHandler.OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) 102 | { 103 | return false; 104 | } 105 | 106 | public void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) 107 | { 108 | 109 | } 110 | 111 | public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) 112 | { 113 | return new ResourceResponseFilter(); 114 | } 115 | 116 | public bool OnSelectClientCertificate(IWebBrowser browserControl, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback) 117 | { 118 | return true; 119 | } 120 | 121 | public void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl) 122 | { 123 | 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/CaptchaForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class CaptchaForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CaptchaForm)); 32 | this.labelText = new System.Windows.Forms.Label(); 33 | this.txtBox = new System.Windows.Forms.TextBox(); 34 | this.btnAccept = new System.Windows.Forms.Button(); 35 | this.btnCancel = new System.Windows.Forms.Button(); 36 | this.pictureBoxCaptcha = new System.Windows.Forms.PictureBox(); 37 | ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCaptcha)).BeginInit(); 38 | this.SuspendLayout(); 39 | // 40 | // labelText 41 | // 42 | this.labelText.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 43 | this.labelText.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 44 | this.labelText.ForeColor = System.Drawing.SystemColors.ControlText; 45 | this.labelText.Location = new System.Drawing.Point(-1, 14); 46 | this.labelText.Name = "labelText"; 47 | this.labelText.Size = new System.Drawing.Size(233, 18); 48 | this.labelText.TabIndex = 0; 49 | this.labelText.Text = "Please enter the following captcha code:"; 50 | this.labelText.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 51 | // 52 | // txtBox 53 | // 54 | this.txtBox.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 55 | this.txtBox.Location = new System.Drawing.Point(12, 84); 56 | this.txtBox.Name = "txtBox"; 57 | this.txtBox.Size = new System.Drawing.Size(206, 33); 58 | this.txtBox.TabIndex = 1; 59 | // 60 | // btnAccept 61 | // 62 | this.btnAccept.Location = new System.Drawing.Point(11, 123); 63 | this.btnAccept.Name = "btnAccept"; 64 | this.btnAccept.Size = new System.Drawing.Size(98, 28); 65 | this.btnAccept.TabIndex = 2; 66 | this.btnAccept.Text = "Submit"; 67 | this.btnAccept.UseVisualStyleBackColor = true; 68 | this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click); 69 | // 70 | // btnCancel 71 | // 72 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 73 | this.btnCancel.Location = new System.Drawing.Point(120, 123); 74 | this.btnCancel.Name = "btnCancel"; 75 | this.btnCancel.Size = new System.Drawing.Size(98, 28); 76 | this.btnCancel.TabIndex = 3; 77 | this.btnCancel.Text = "Cancel"; 78 | this.btnCancel.UseVisualStyleBackColor = true; 79 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); 80 | // 81 | // pictureBoxCaptcha 82 | // 83 | this.pictureBoxCaptcha.Location = new System.Drawing.Point(12, 37); 84 | this.pictureBoxCaptcha.Name = "pictureBoxCaptcha"; 85 | this.pictureBoxCaptcha.Size = new System.Drawing.Size(206, 40); 86 | this.pictureBoxCaptcha.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; 87 | this.pictureBoxCaptcha.TabIndex = 4; 88 | this.pictureBoxCaptcha.TabStop = false; 89 | // 90 | // CaptchaForm 91 | // 92 | this.AcceptButton = this.btnAccept; 93 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 94 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 95 | this.CancelButton = this.btnCancel; 96 | this.ClientSize = new System.Drawing.Size(232, 164); 97 | this.Controls.Add(this.pictureBoxCaptcha); 98 | this.Controls.Add(this.btnCancel); 99 | this.Controls.Add(this.btnAccept); 100 | this.Controls.Add(this.txtBox); 101 | this.Controls.Add(this.labelText); 102 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 103 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 104 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 105 | this.Name = "CaptchaForm"; 106 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 107 | ((System.ComponentModel.ISupportInitialize)(this.pictureBoxCaptcha)).EndInit(); 108 | this.ResumeLayout(false); 109 | this.PerformLayout(); 110 | 111 | } 112 | 113 | #endregion 114 | 115 | private System.Windows.Forms.Label labelText; 116 | public System.Windows.Forms.TextBox txtBox; 117 | private System.Windows.Forms.Button btnAccept; 118 | private System.Windows.Forms.Button btnCancel; 119 | private System.Windows.Forms.PictureBox pictureBoxCaptcha; 120 | } 121 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/CaptchaForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace Steam_Desktop_Authenticator 12 | { 13 | public partial class CaptchaForm : Form 14 | { 15 | public bool Canceled = false; 16 | public string CaptchaGID = ""; 17 | public string CaptchaURL = ""; 18 | public string CaptchaCode 19 | { 20 | get 21 | { 22 | return this.txtBox.Text; 23 | } 24 | } 25 | 26 | public CaptchaForm(string GID) 27 | { 28 | this.CaptchaGID = GID; 29 | this.CaptchaURL = "https://steamcommunity.com/public/captcha.php?gid=" + GID; 30 | InitializeComponent(); 31 | this.pictureBoxCaptcha.Load(CaptchaURL); 32 | } 33 | 34 | private void btnAccept_Click(object sender, EventArgs e) 35 | { 36 | this.Canceled = false; 37 | this.Close(); 38 | } 39 | 40 | private void btnCancel_Click(object sender, EventArgs e) 41 | { 42 | this.Canceled = true; 43 | this.Close(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/CommandLineOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | using CommandLine.Text; 3 | 4 | namespace Steam_Desktop_Authenticator 5 | { 6 | class CommandLineOptions 7 | { 8 | [Option('k', "encryption-key", Required = false, 9 | HelpText = "Encryption key for manifest")] 10 | public string EncryptionKey { get; set; } 11 | 12 | [Option('s', "silent", Required = false, 13 | HelpText = "Start minimized")] 14 | public bool Silent { get; set; } 15 | 16 | [ParserState] 17 | public IParserState LastParserState { get; set; } 18 | 19 | [HelpOption] 20 | public string GetUsage() 21 | { 22 | return HelpText.AutoBuild(this, 23 | (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/ConfirmationFormWeb.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class ConfirmationFormWeb 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConfirmationFormWeb)); 32 | this.splitContainer1 = new System.Windows.Forms.SplitContainer(); 33 | this.btnRefresh = new System.Windows.Forms.Button(); 34 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); 35 | this.splitContainer1.Panel1.SuspendLayout(); 36 | this.splitContainer1.SuspendLayout(); 37 | this.SuspendLayout(); 38 | // 39 | // splitContainer1 40 | // 41 | this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; 42 | this.splitContainer1.IsSplitterFixed = true; 43 | this.splitContainer1.Location = new System.Drawing.Point(0, 0); 44 | this.splitContainer1.Name = "splitContainer1"; 45 | this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; 46 | // 47 | // splitContainer1.Panel1 48 | // 49 | this.splitContainer1.Panel1.Controls.Add(this.btnRefresh); 50 | this.splitContainer1.Size = new System.Drawing.Size(431, 641); 51 | this.splitContainer1.SplitterDistance = 30; 52 | this.splitContainer1.SplitterWidth = 1; 53 | this.splitContainer1.TabIndex = 0; 54 | // 55 | // btnRefresh 56 | // 57 | this.btnRefresh.Dock = System.Windows.Forms.DockStyle.Fill; 58 | this.btnRefresh.Location = new System.Drawing.Point(0, 0); 59 | this.btnRefresh.Name = "btnRefresh"; 60 | this.btnRefresh.Size = new System.Drawing.Size(431, 30); 61 | this.btnRefresh.TabIndex = 0; 62 | this.btnRefresh.Text = "Refresh"; 63 | this.btnRefresh.UseVisualStyleBackColor = true; 64 | this.btnRefresh.Click += new System.EventHandler(this.btnRefresh_Click); 65 | // 66 | // ConfirmationFormWeb 67 | // 68 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 69 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 70 | this.ClientSize = new System.Drawing.Size(431, 641); 71 | this.Controls.Add(this.splitContainer1); 72 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 73 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 74 | this.Name = "ConfirmationFormWeb"; 75 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 76 | this.Text = "Trade Confirmations"; 77 | this.splitContainer1.Panel1.ResumeLayout(false); 78 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); 79 | this.splitContainer1.ResumeLayout(false); 80 | this.ResumeLayout(false); 81 | 82 | } 83 | 84 | #endregion 85 | 86 | private System.Windows.Forms.SplitContainer splitContainer1; 87 | private System.Windows.Forms.Button btnRefresh; 88 | } 89 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/ConfirmationFormWeb.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | using System.Diagnostics; 12 | using CefSharp; 13 | using CefSharp.WinForms; 14 | using SteamAuth; 15 | 16 | namespace Steam_Desktop_Authenticator 17 | { 18 | public partial class ConfirmationFormWeb : Form 19 | { 20 | private readonly ChromiumWebBrowser browser; 21 | private string steamCookies; 22 | private SteamGuardAccount steamAccount; 23 | private string tradeID; 24 | 25 | public ConfirmationFormWeb(SteamGuardAccount steamAccount) 26 | { 27 | InitializeComponent(); 28 | this.steamAccount = steamAccount; 29 | this.Text = String.Format("Trade Confirmations - {0}", steamAccount.AccountName); 30 | 31 | CefSettings settings = new CefSettings(); 32 | settings.PersistSessionCookies = false; 33 | settings.Locale = "en-US"; 34 | settings.UserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 6P Build/XXXXX; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/47.0.2526.68 Mobile Safari/537.36"; 35 | steamCookies = String.Format("mobileClientVersion=0 (2.1.3); mobileClient=android; steamid={0}; steamLoginSecure={1}; Steam_Language=english; dob=;", steamAccount.Session.SteamID.ToString(), steamAccount.Session.SteamLoginSecure); 36 | 37 | if (!Cef.IsInitialized) 38 | { 39 | Cef.Initialize(settings); 40 | } 41 | 42 | browser = new ChromiumWebBrowser(steamAccount.GenerateConfirmationURL()) 43 | { 44 | Dock = DockStyle.Fill, 45 | }; 46 | this.splitContainer1.Panel2.Controls.Add(browser); 47 | 48 | BrowserRequestHandler handler = new BrowserRequestHandler(); 49 | handler.Cookies = steamCookies; 50 | browser.RequestHandler = handler; 51 | browser.AddressChanged += Browser_AddressChanged; 52 | browser.LoadingStateChanged += Browser_LoadingStateChanged; 53 | } 54 | 55 | private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e) 56 | { 57 | // This looks really ugly, but it's easier than implementing steam's steammobile:// protocol using CefSharp 58 | // We override the page's GetValueFromLocalURL() to pass in the keys for sending ajax requests 59 | Debug.WriteLine("IsLoading: " + e.IsLoading); 60 | if (e.IsLoading == false) 61 | { 62 | // Generate url for details 63 | string urlParams = steamAccount.GenerateConfirmationQueryParams("details" + tradeID); 64 | 65 | var script = string.Format(@"window.GetValueFromLocalURL = 66 | function(url, timeout, success, error, fatal) {{ 67 | console.log(url); 68 | if(url.indexOf('steammobile://steamguard?op=conftag&arg1=allow') !== -1) {{ 69 | // send confirmation (allow) 70 | success('{0}'); 71 | }} else if(url.indexOf('steammobile://steamguard?op=conftag&arg1=cancel') !== -1) {{ 72 | // send confirmation (cancel) 73 | success('{1}'); 74 | }} else if(url.indexOf('steammobile://steamguard?op=conftag&arg1=details') !== -1) {{ 75 | // get details 76 | success('{2}'); 77 | }} 78 | }}", steamAccount.GenerateConfirmationQueryParams("allow"), steamAccount.GenerateConfirmationQueryParams("cancel"), urlParams); 79 | try 80 | { 81 | browser.ExecuteScriptAsync(script); 82 | } 83 | catch (Exception) 84 | { 85 | Debug.WriteLine("Failed to execute script"); 86 | } 87 | } 88 | } 89 | 90 | private void Browser_AddressChanged(object sender, AddressChangedEventArgs e) 91 | { 92 | string[] urlparts = browser.Address.Split('#'); 93 | if (urlparts.Length > 1) 94 | { 95 | tradeID = urlparts[1].Replace("conf_", ""); 96 | } 97 | } 98 | 99 | private void btnRefresh_Click(object sender, EventArgs e) 100 | { 101 | browser.Load(steamAccount.GenerateConfirmationURL()); 102 | } 103 | 104 | protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 105 | { 106 | bool bHandled = false; 107 | switch (keyData) 108 | { 109 | case Keys.F5: 110 | browser.Load(steamAccount.GenerateConfirmationURL()); 111 | bHandled = true; 112 | break; 113 | case Keys.F1: 114 | browser.ShowDevTools(); 115 | bHandled = true; 116 | break; 117 | } 118 | return bHandled; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/DeleteAllCookiesVisitor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using CefSharp; 7 | 8 | namespace Steam_Desktop_Authenticator 9 | { 10 | public class DeleteAllCookiesVisitor : ICookieVisitor 11 | { 12 | public void Dispose() 13 | { 14 | 15 | } 16 | 17 | public bool Visit(Cookie cookie, int count, int total, ref bool deleteCookie) 18 | { 19 | deleteCookie = true; 20 | return true; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/FileEncryptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Security.Cryptography; 7 | using System.IO; 8 | 9 | namespace Steam_Desktop_Authenticator 10 | { 11 | /// 12 | /// This class provides the controls that will encrypt and decrypt the *.maFile files 13 | /// 14 | /// Passwords entered will be passed into 100k rounds of PBKDF2 (RFC2898) with a cryptographically random salt. 15 | /// The generated key will then be passed into AES-256 (RijndalManaged) which will encrypt the data 16 | /// in cypher block chaining (CBC) mode, and then write both the PBKDF2 salt and encrypted data onto the disk. 17 | /// 18 | public static class FileEncryptor 19 | { 20 | private const int PBKDF2_ITERATIONS = 50000; //Set to 50k to make program not unbearably slow. May increase in future. 21 | private const int SALT_LENGTH = 8; 22 | private const int KEY_SIZE_BYTES = 32; 23 | private const int IV_LENGTH = 16; 24 | 25 | /// 26 | /// Returns an 8-byte cryptographically random salt in base64 encoding 27 | /// 28 | /// 29 | public static string GetRandomSalt() 30 | { 31 | byte[] salt = new byte[SALT_LENGTH]; 32 | using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 33 | { 34 | rng.GetBytes(salt); 35 | } 36 | return Convert.ToBase64String(salt); 37 | } 38 | 39 | /// 40 | /// Returns a 16-byte cryptographically random initialization vector (IV) in base64 encoding 41 | /// 42 | /// 43 | public static string GetInitializationVector() 44 | { 45 | byte[] IV = new byte[IV_LENGTH]; 46 | using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 47 | { 48 | rng.GetBytes(IV); 49 | } 50 | return Convert.ToBase64String(IV); 51 | } 52 | 53 | 54 | /// 55 | /// Generates an encryption key derived using a password, a random salt, and specified number of rounds of PBKDF2 56 | /// 57 | /// TODO: pass in password via SecureString? 58 | /// 59 | /// 60 | /// 61 | /// 62 | private static byte[] GetEncryptionKey(string password, string salt) 63 | { 64 | if (string.IsNullOrEmpty(password)) 65 | { 66 | throw new ArgumentException("Password is empty"); 67 | } 68 | if (string.IsNullOrEmpty(salt)) 69 | { 70 | throw new ArgumentException("Salt is empty"); 71 | } 72 | using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, Convert.FromBase64String(salt), PBKDF2_ITERATIONS)) 73 | { 74 | return pbkdf2.GetBytes(KEY_SIZE_BYTES); 75 | } 76 | } 77 | 78 | /// 79 | /// Tries to decrypt and return data given an encrypted base64 encoded string. Must use the same 80 | /// password, salt, IV, and ciphertext that was used during the original encryption of the data. 81 | /// 82 | /// 83 | /// 84 | /// Initialization Vector 85 | /// 86 | /// 87 | public static string DecryptData(string password, string passwordSalt, string IV, string encryptedData) 88 | { 89 | if (string.IsNullOrEmpty(password)) 90 | { 91 | throw new ArgumentException("Password is empty"); 92 | } 93 | if (string.IsNullOrEmpty(passwordSalt)) 94 | { 95 | throw new ArgumentException("Salt is empty"); 96 | } 97 | if (string.IsNullOrEmpty(IV)) 98 | { 99 | throw new ArgumentException("Initialization Vector is empty"); 100 | } 101 | if (string.IsNullOrEmpty(encryptedData)) 102 | { 103 | throw new ArgumentException("Encrypted data is empty"); 104 | } 105 | 106 | byte[] cipherText = Convert.FromBase64String(encryptedData); 107 | byte[] key = GetEncryptionKey(password, passwordSalt); 108 | string plaintext = null; 109 | 110 | using (RijndaelManaged aes256 = new RijndaelManaged()) 111 | { 112 | aes256.IV = Convert.FromBase64String(IV); 113 | aes256.Key = key; 114 | aes256.Padding = PaddingMode.PKCS7; 115 | aes256.Mode = CipherMode.CBC; 116 | 117 | //create decryptor to perform the stream transform 118 | ICryptoTransform decryptor = aes256.CreateDecryptor(aes256.Key, aes256.IV); 119 | 120 | //wrap in a try since a bad password yields a bad key, which would throw an exception on decrypt 121 | try 122 | { 123 | using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 124 | { 125 | using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 126 | { 127 | using (StreamReader srDecrypt = new StreamReader(csDecrypt)) 128 | { 129 | plaintext = srDecrypt.ReadToEnd(); 130 | } 131 | } 132 | } 133 | } 134 | catch (CryptographicException) 135 | { 136 | plaintext = null; 137 | } 138 | } 139 | return plaintext; 140 | } 141 | 142 | /// 143 | /// Encrypts a string given a password, salt, and initialization vector, then returns result in base64 encoded string. 144 | /// 145 | /// To retrieve this data, you must decrypt with the same password, salt, IV, and cyphertext that was used during encryption 146 | /// 147 | /// 148 | /// 149 | /// 150 | /// 151 | /// 152 | public static string EncryptData(string password, string passwordSalt, string IV, string plaintext) 153 | { 154 | if (string.IsNullOrEmpty(password)) 155 | { 156 | throw new ArgumentException("Password is empty"); 157 | } 158 | if (string.IsNullOrEmpty(passwordSalt)) 159 | { 160 | throw new ArgumentException("Salt is empty"); 161 | } 162 | if (string.IsNullOrEmpty(IV)) 163 | { 164 | throw new ArgumentException("Initialization Vector is empty"); 165 | } 166 | if (string.IsNullOrEmpty(plaintext)) 167 | { 168 | throw new ArgumentException("Plaintext data is empty"); 169 | } 170 | byte[] key = GetEncryptionKey(password, passwordSalt); 171 | byte[] ciphertext; 172 | 173 | using (RijndaelManaged aes256 = new RijndaelManaged()) 174 | { 175 | aes256.Key = key; 176 | aes256.IV = Convert.FromBase64String(IV); 177 | aes256.Padding = PaddingMode.PKCS7; 178 | aes256.Mode = CipherMode.CBC; 179 | 180 | ICryptoTransform encryptor = aes256.CreateEncryptor(aes256.Key, aes256.IV); 181 | 182 | using (MemoryStream msEncrypt = new MemoryStream()) 183 | { 184 | using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 185 | { 186 | using (StreamWriter swEncypt = new StreamWriter(csEncrypt)) 187 | { 188 | swEncypt.Write(plaintext); 189 | } 190 | ciphertext = msEncrypt.ToArray(); 191 | } 192 | } 193 | } 194 | return Convert.ToBase64String(ciphertext); 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/ImportAccountForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class ImportAccountForm 4 | { 5 | #region Windows Form Designer generated code 6 | 7 | /// 8 | /// Required method for Designer support - do not modify 9 | /// the contents of this method with the code editor. 10 | /// 11 | private void InitializeComponent() 12 | { 13 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImportAccountForm)); 14 | this.labelText = new System.Windows.Forms.Label(); 15 | this.txtBox = new System.Windows.Forms.TextBox(); 16 | this.btnImport = new System.Windows.Forms.Button(); 17 | this.btnCancel = new System.Windows.Forms.Button(); 18 | this.label1 = new System.Windows.Forms.Label(); 19 | this.SuspendLayout(); 20 | // 21 | // labelText 22 | // 23 | this.labelText.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 24 | this.labelText.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 25 | this.labelText.ForeColor = System.Drawing.SystemColors.ControlText; 26 | this.labelText.Location = new System.Drawing.Point(15, 14); 27 | this.labelText.Name = "labelText"; 28 | this.labelText.Size = new System.Drawing.Size(317, 25); 29 | this.labelText.TabIndex = 0; 30 | this.labelText.Text = "Enter your encryption passkey if your .maFile is encrypted:"; 31 | // 32 | // txtBox 33 | // 34 | this.txtBox.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 35 | this.txtBox.Location = new System.Drawing.Point(15, 42); 36 | this.txtBox.Name = "txtBox"; 37 | this.txtBox.Size = new System.Drawing.Size(307, 33); 38 | this.txtBox.TabIndex = 1; 39 | // 40 | // btnImport 41 | // 42 | this.btnImport.Location = new System.Drawing.Point(135, 131); 43 | this.btnImport.Name = "btnImport"; 44 | this.btnImport.Size = new System.Drawing.Size(187, 28); 45 | this.btnImport.TabIndex = 3; 46 | this.btnImport.Text = "Select .maFile file to Import"; 47 | this.btnImport.UseVisualStyleBackColor = true; 48 | this.btnImport.Click += new System.EventHandler(this.btnImport_Click); 49 | // 50 | // btnCancel 51 | // 52 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 53 | this.btnCancel.Location = new System.Drawing.Point(41, 131); 54 | this.btnCancel.Name = "btnCancel"; 55 | this.btnCancel.Size = new System.Drawing.Size(88, 28); 56 | this.btnCancel.TabIndex = 4; 57 | this.btnCancel.Text = "Cancel"; 58 | this.btnCancel.UseVisualStyleBackColor = true; 59 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); 60 | // 61 | // label1 62 | // 63 | this.label1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 64 | this.label1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 65 | this.label1.ForeColor = System.Drawing.SystemColors.ControlText; 66 | this.label1.Location = new System.Drawing.Point(15, 83); 67 | this.label1.Name = "label1"; 68 | this.label1.Size = new System.Drawing.Size(307, 40); 69 | this.label1.TabIndex = 2; 70 | this.label1.Text = "If you import an encrypted .maFile, the manifest file must be next to it."; 71 | // 72 | // ImportAccountForm 73 | // 74 | this.AcceptButton = this.btnImport; 75 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 76 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 77 | this.CancelButton = this.btnCancel; 78 | this.ClientSize = new System.Drawing.Size(336, 171); 79 | this.Controls.Add(this.label1); 80 | this.Controls.Add(this.btnCancel); 81 | this.Controls.Add(this.btnImport); 82 | this.Controls.Add(this.txtBox); 83 | this.Controls.Add(this.labelText); 84 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 85 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 86 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 87 | this.MaximizeBox = false; 88 | this.Name = "ImportAccountForm"; 89 | this.ShowInTaskbar = false; 90 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 91 | this.Text = "Import Account"; 92 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Import_maFile_Form_FormClosing); 93 | this.ResumeLayout(false); 94 | this.PerformLayout(); 95 | 96 | } 97 | 98 | #endregion 99 | 100 | private System.Windows.Forms.Label labelText; 101 | private System.Windows.Forms.TextBox txtBox; 102 | private System.Windows.Forms.Button btnImport; 103 | private System.Windows.Forms.Button btnCancel; 104 | private System.Windows.Forms.Label label1; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/ImportAccountForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using SteamAuth; 11 | using Newtonsoft.Json; 12 | using Newtonsoft.Json.Linq; 13 | using System.IO; 14 | 15 | namespace Steam_Desktop_Authenticator 16 | { 17 | public partial class ImportAccountForm : Form 18 | { 19 | private Manifest mManifest; 20 | 21 | public ImportAccountForm() 22 | { 23 | InitializeComponent(); 24 | this.mManifest = Manifest.GetManifest(); 25 | } 26 | 27 | private void btnImport_Click(object sender, EventArgs e) 28 | { 29 | // check if data already added is encripted 30 | #region check if data already added is encripted 31 | string ContiuneImport = "0"; 32 | 33 | string ManifestFile = "maFiles/manifest.json"; 34 | if (File.Exists(ManifestFile)) 35 | { 36 | string AppManifestContents = File.ReadAllText(ManifestFile); 37 | AppManifest AppManifestData = JsonConvert.DeserializeObject(AppManifestContents); 38 | bool AppManifestData_encrypted = AppManifestData.Encrypted; 39 | if (AppManifestData_encrypted == true) 40 | { 41 | MessageBox.Show("You can't import an .maFile because the existing account in the app is encrypted.\nDecrypt it and try again."); 42 | this.Close(); 43 | } 44 | else if (AppManifestData_encrypted == false) 45 | { 46 | ContiuneImport = "1"; 47 | } 48 | else 49 | { 50 | MessageBox.Show("invalid value for variable 'encrypted' inside manifest.json"); 51 | this.Close(); 52 | } 53 | } 54 | else 55 | { 56 | MessageBox.Show("An Error occurred, Restart the program!"); 57 | } 58 | #endregion 59 | 60 | // Continue 61 | #region Continue 62 | if (ContiuneImport == "1") 63 | { 64 | this.Close(); 65 | 66 | // read EncriptionKey from imput box 67 | string ImportUsingEncriptionKey = txtBox.Text; 68 | 69 | // Open file browser > to select the file 70 | OpenFileDialog openFileDialog1 = new OpenFileDialog(); 71 | 72 | // Set filter options and filter index. 73 | openFileDialog1.Filter = "maFiles (.maFile)|*.maFile|All Files (*.*)|*.*"; 74 | openFileDialog1.FilterIndex = 1; 75 | openFileDialog1.Multiselect = false; 76 | 77 | // Call the ShowDialog method to show the dialog box. 78 | DialogResult userClickedOK = openFileDialog1.ShowDialog(); 79 | 80 | // Process input if the user clicked OK. 81 | if (userClickedOK == DialogResult.OK) 82 | { 83 | // Open the selected file to read. 84 | System.IO.Stream fileStream = openFileDialog1.OpenFile(); 85 | string fileContents = null; 86 | 87 | using (System.IO.StreamReader reader = new System.IO.StreamReader(fileStream)) 88 | { 89 | fileContents = reader.ReadToEnd(); 90 | } 91 | fileStream.Close(); 92 | 93 | try 94 | { 95 | if (ImportUsingEncriptionKey == "") 96 | { 97 | // Import maFile 98 | //------------------------------------------- 99 | #region Import maFile 100 | SteamGuardAccount maFile = JsonConvert.DeserializeObject(fileContents); 101 | if (maFile.Session.SteamID != 0) 102 | { 103 | mManifest.SaveAccount(maFile, false); 104 | MessageBox.Show("Account Imported!"); 105 | } 106 | else 107 | { 108 | throw new Exception("Invalid SteamID"); 109 | } 110 | #endregion 111 | } 112 | else 113 | { 114 | // Import Encripted maFile 115 | //------------------------------------------- 116 | #region Import Encripted maFile 117 | //Read manifest.json encryption_iv encryption_salt 118 | string ImportFileName_Found = "0"; 119 | string Salt_Found = null; 120 | string IV_Found = null; 121 | string ReadManifestEx = "0"; 122 | 123 | //No directory means no manifest file anyways. 124 | ImportManifest newImportManifest = new ImportManifest(); 125 | newImportManifest.Encrypted = false; 126 | newImportManifest.Entries = new List(); 127 | 128 | // extract folder path 129 | string fullPath = openFileDialog1.FileName; 130 | string fileName = openFileDialog1.SafeFileName; 131 | string path = fullPath.Replace(fileName, ""); 132 | 133 | // extract fileName 134 | string ImportFileName = fullPath.Replace(path, ""); 135 | 136 | string ImportManifestFile = path + "manifest.json"; 137 | 138 | 139 | if (File.Exists(ImportManifestFile)) 140 | { 141 | string ImportManifestContents = File.ReadAllText(ImportManifestFile); 142 | 143 | 144 | try 145 | { 146 | ImportManifest account = JsonConvert.DeserializeObject(ImportManifestContents); 147 | //bool Import_encrypted = account.Encrypted; 148 | 149 | List newEntries = new List(); 150 | 151 | foreach (var entry in account.Entries) 152 | { 153 | string FileName = entry.Filename; 154 | string encryption_iv = entry.IV; 155 | string encryption_salt = entry.Salt; 156 | 157 | if (ImportFileName == FileName) 158 | { 159 | ImportFileName_Found = "1"; 160 | IV_Found = entry.IV; 161 | Salt_Found = entry.Salt; 162 | } 163 | } 164 | } 165 | catch (Exception) 166 | { 167 | ReadManifestEx = "1"; 168 | MessageBox.Show("Invalid content inside manifest.json!\nImport Failed."); 169 | } 170 | 171 | 172 | // DECRIPT & Import 173 | //-------------------- 174 | #region DECRIPT & Import 175 | if (ReadManifestEx == "0") 176 | { 177 | if (ImportFileName_Found == "1" && Salt_Found != null && IV_Found != null) 178 | { 179 | string decryptedText = FileEncryptor.DecryptData(ImportUsingEncriptionKey, Salt_Found, IV_Found, fileContents); 180 | 181 | if (decryptedText == null) 182 | { 183 | MessageBox.Show("Decryption Failed.\nImport Failed."); 184 | } 185 | else 186 | { 187 | string fileText = decryptedText; 188 | 189 | SteamGuardAccount maFile = JsonConvert.DeserializeObject(fileText); 190 | if (maFile.Session.SteamID != 0) 191 | { 192 | mManifest.SaveAccount(maFile, false); 193 | MessageBox.Show("Account Imported!\nYour Account in now Decrypted!"); 194 | //MainForm.loadAccountsList(); 195 | } 196 | else 197 | { 198 | MessageBox.Show("Invalid SteamID.\nImport Failed."); 199 | } 200 | } 201 | } 202 | else 203 | { 204 | if (ImportFileName_Found == "0") 205 | { 206 | MessageBox.Show("Account not found inside manifest.json.\nImport Failed."); 207 | } 208 | else if (Salt_Found == null && IV_Found == null) 209 | { 210 | MessageBox.Show("manifest.json does not contain encrypted data.\nYour account may be unencrypted!\nImport Failed."); 211 | } 212 | else 213 | { 214 | if (IV_Found == null) 215 | { 216 | MessageBox.Show("manifest.json does not contain: encryption_iv\nImport Failed."); 217 | } 218 | else if (IV_Found == null) 219 | { 220 | MessageBox.Show("manifest.json does not contain: encryption_salt\nImport Failed."); 221 | } 222 | } 223 | } 224 | } 225 | #endregion //DECRIPT & Import END 226 | 227 | 228 | } 229 | else 230 | { 231 | MessageBox.Show("manifest.json is missing!\nImport Failed."); 232 | } 233 | #endregion //Import Encripted maFile END 234 | } 235 | 236 | } 237 | catch (Exception) 238 | { 239 | MessageBox.Show("This file is not a valid SteamAuth maFile.\nImport Failed."); 240 | } 241 | } 242 | } 243 | #endregion // Continue End 244 | } 245 | 246 | private void btnCancel_Click(object sender, EventArgs e) 247 | { 248 | this.Close(); 249 | } 250 | 251 | private void Import_maFile_Form_FormClosing(object sender, FormClosingEventArgs e) 252 | { 253 | } 254 | } 255 | 256 | 257 | public class AppManifest 258 | { 259 | [JsonProperty("encrypted")] 260 | public bool Encrypted { get; set; } 261 | } 262 | 263 | 264 | public class ImportManifest 265 | { 266 | [JsonProperty("encrypted")] 267 | public bool Encrypted { get; set; } 268 | 269 | [JsonProperty("entries")] 270 | public List Entries { get; set; } 271 | } 272 | 273 | public class ImportManifestEntry 274 | { 275 | [JsonProperty("encryption_iv")] 276 | public string IV { get; set; } 277 | 278 | [JsonProperty("encryption_salt")] 279 | public string Salt { get; set; } 280 | 281 | [JsonProperty("filename")] 282 | public string Filename { get; set; } 283 | 284 | [JsonProperty("steamid")] 285 | public ulong SteamID { get; set; } 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/InputForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class InputForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InputForm)); 32 | this.labelText = new System.Windows.Forms.Label(); 33 | this.txtBox = new System.Windows.Forms.TextBox(); 34 | this.btnAccept = new System.Windows.Forms.Button(); 35 | this.btnCancel = new System.Windows.Forms.Button(); 36 | this.SuspendLayout(); 37 | // 38 | // labelText 39 | // 40 | this.labelText.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 41 | this.labelText.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 42 | this.labelText.ForeColor = System.Drawing.SystemColors.ControlText; 43 | this.labelText.Location = new System.Drawing.Point(12, 9); 44 | this.labelText.Name = "labelText"; 45 | this.labelText.Size = new System.Drawing.Size(383, 159); 46 | this.labelText.TabIndex = 0; 47 | this.labelText.Text = "Sample Text~~~"; 48 | // 49 | // txtBox 50 | // 51 | this.txtBox.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 52 | this.txtBox.Location = new System.Drawing.Point(12, 171); 53 | this.txtBox.Name = "txtBox"; 54 | this.txtBox.Size = new System.Drawing.Size(383, 33); 55 | this.txtBox.TabIndex = 1; 56 | // 57 | // btnAccept 58 | // 59 | this.btnAccept.Location = new System.Drawing.Point(15, 210); 60 | this.btnAccept.Name = "btnAccept"; 61 | this.btnAccept.Size = new System.Drawing.Size(98, 28); 62 | this.btnAccept.TabIndex = 2; 63 | this.btnAccept.Text = "Accept"; 64 | this.btnAccept.UseVisualStyleBackColor = true; 65 | this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click); 66 | // 67 | // btnCancel 68 | // 69 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 70 | this.btnCancel.Location = new System.Drawing.Point(297, 210); 71 | this.btnCancel.Name = "btnCancel"; 72 | this.btnCancel.Size = new System.Drawing.Size(98, 28); 73 | this.btnCancel.TabIndex = 3; 74 | this.btnCancel.Text = "Cancel"; 75 | this.btnCancel.UseVisualStyleBackColor = true; 76 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); 77 | // 78 | // InputForm 79 | // 80 | this.AcceptButton = this.btnAccept; 81 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 82 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 83 | this.CancelButton = this.btnCancel; 84 | this.ClientSize = new System.Drawing.Size(407, 250); 85 | this.Controls.Add(this.btnCancel); 86 | this.Controls.Add(this.btnAccept); 87 | this.Controls.Add(this.txtBox); 88 | this.Controls.Add(this.labelText); 89 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 90 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 91 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 92 | this.MaximizeBox = false; 93 | this.Name = "InputForm"; 94 | this.ShowInTaskbar = false; 95 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 96 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.InputForm_FormClosing); 97 | this.ResumeLayout(false); 98 | this.PerformLayout(); 99 | 100 | } 101 | 102 | #endregion 103 | 104 | private System.Windows.Forms.Label labelText; 105 | public System.Windows.Forms.TextBox txtBox; 106 | private System.Windows.Forms.Button btnAccept; 107 | private System.Windows.Forms.Button btnCancel; 108 | } 109 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/InputForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace Steam_Desktop_Authenticator 12 | { 13 | public partial class InputForm : Form 14 | { 15 | public bool Canceled = false; 16 | private bool userClosed = true; 17 | 18 | public InputForm(string label, bool password = false) 19 | { 20 | InitializeComponent(); 21 | this.labelText.Text = label; 22 | 23 | if (password) 24 | { 25 | this.txtBox.PasswordChar = '*'; 26 | } 27 | } 28 | 29 | private void btnAccept_Click(object sender, EventArgs e) 30 | { 31 | if (string.IsNullOrEmpty(this.txtBox.Text)) 32 | { 33 | this.Canceled = true; 34 | this.userClosed = false; 35 | this.Close(); 36 | } 37 | else 38 | { 39 | this.Canceled = false; 40 | this.userClosed = false; 41 | this.Close(); 42 | } 43 | } 44 | 45 | private void btnCancel_Click(object sender, EventArgs e) 46 | { 47 | this.Canceled = true; 48 | this.userClosed = false; 49 | this.Close(); 50 | } 51 | 52 | private void InputForm_FormClosing(object sender, FormClosingEventArgs e) 53 | { 54 | if (this.userClosed) 55 | { 56 | // Set Canceled = true when the user hits the X button. 57 | this.Canceled = true; 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/InstallRedistribForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class InstallRedistribForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InstallRedistribForm)); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.progressBar1 = new System.Windows.Forms.ProgressBar(); 34 | this.SuspendLayout(); 35 | // 36 | // label1 37 | // 38 | this.label1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 39 | this.label1.Location = new System.Drawing.Point(12, 9); 40 | this.label1.Name = "label1"; 41 | this.label1.Size = new System.Drawing.Size(289, 45); 42 | this.label1.TabIndex = 0; 43 | this.label1.Text = "Installing Visual C++ Redistributable 2013..."; 44 | this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 45 | // 46 | // progressBar1 47 | // 48 | this.progressBar1.Location = new System.Drawing.Point(12, 57); 49 | this.progressBar1.Name = "progressBar1"; 50 | this.progressBar1.Size = new System.Drawing.Size(289, 28); 51 | this.progressBar1.TabIndex = 1; 52 | // 53 | // InstallRedistribForm 54 | // 55 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 56 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 57 | this.ClientSize = new System.Drawing.Size(313, 97); 58 | this.Controls.Add(this.progressBar1); 59 | this.Controls.Add(this.label1); 60 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 61 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 62 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 63 | this.MaximizeBox = false; 64 | this.Name = "InstallRedistribForm"; 65 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 66 | this.Text = "Installing"; 67 | this.ResumeLayout(false); 68 | 69 | } 70 | 71 | #endregion 72 | 73 | private System.Windows.Forms.Label label1; 74 | private System.Windows.Forms.ProgressBar progressBar1; 75 | } 76 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/InstallRedistribForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.Net; 11 | using System.Diagnostics; 12 | 13 | namespace Steam_Desktop_Authenticator 14 | { 15 | public partial class InstallRedistribForm : Form 16 | { 17 | private bool inlineInstall = false; 18 | 19 | public InstallRedistribForm(bool inlineInstall = false) 20 | { 21 | InitializeComponent(); 22 | progressBar1.Minimum = 0; 23 | 24 | string path = Manifest.GetExecutableDir() + "/vcredist_x86.exe"; 25 | 26 | WebClient client = new WebClient(); 27 | client.DownloadFileAsync(new Uri("https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe"), path); 28 | client.DownloadProgressChanged += Client_DownloadProgressChanged; 29 | client.DownloadFileCompleted += Client_DownloadFileCompleted; 30 | } 31 | 32 | private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 33 | { 34 | progressBar1.Style = ProgressBarStyle.Marquee; 35 | try 36 | { 37 | ProcessStartInfo startInfo = new ProcessStartInfo(); 38 | startInfo.FileName = Manifest.GetExecutableDir() + "/vcredist_x86.exe"; 39 | startInfo.Verb = "runas"; 40 | startInfo.Arguments = "/q"; 41 | startInfo.WindowStyle = ProcessWindowStyle.Normal; 42 | 43 | Process installProcess = new Process(); 44 | installProcess.StartInfo = startInfo; 45 | installProcess.EnableRaisingEvents = true; 46 | installProcess.Exited += InstallProcess_Exited; 47 | installProcess.Start(); 48 | } 49 | catch (Exception) 50 | { 51 | this.Close(); 52 | } 53 | } 54 | 55 | private void InstallProcess_Exited(object sender, EventArgs e) 56 | { 57 | if (inlineInstall) 58 | { 59 | MessageBox.Show("Install complete! You may need to restart Steam Desktop Authenticator to view trade confirmations.", "Visual C++ Redistributable 2013", MessageBoxButtons.OK, MessageBoxIcon.Information); 60 | } 61 | 62 | this.Invoke((MethodInvoker)delegate 63 | { 64 | this.Close(); 65 | }); 66 | } 67 | 68 | private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 69 | { 70 | progressBar1.Maximum = (int)e.TotalBytesToReceive; 71 | progressBar1.Value = (int)e.BytesReceived; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/ListInputForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class ListInputForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ListInputForm)); 32 | this.lbItems = new System.Windows.Forms.ListBox(); 33 | this.btnAccept = new System.Windows.Forms.Button(); 34 | this.btnCancel = new System.Windows.Forms.Button(); 35 | this.SuspendLayout(); 36 | // 37 | // lbItems 38 | // 39 | this.lbItems.FormattingEnabled = true; 40 | this.lbItems.Location = new System.Drawing.Point(23, 63); 41 | this.lbItems.Name = "lbItems"; 42 | this.lbItems.Size = new System.Drawing.Size(248, 82); 43 | this.lbItems.TabIndex = 0; 44 | // 45 | // btnAccept 46 | // 47 | this.btnAccept.Location = new System.Drawing.Point(277, 63); 48 | this.btnAccept.Name = "btnAccept"; 49 | this.btnAccept.Size = new System.Drawing.Size(75, 23); 50 | this.btnAccept.TabIndex = 1; 51 | this.btnAccept.Text = "Accept"; 52 | this.btnAccept.UseVisualStyleBackColor = true; 53 | this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click); 54 | // 55 | // btnCancel 56 | // 57 | this.btnCancel.Location = new System.Drawing.Point(277, 122); 58 | this.btnCancel.Name = "btnCancel"; 59 | this.btnCancel.Size = new System.Drawing.Size(75, 23); 60 | this.btnCancel.TabIndex = 2; 61 | this.btnCancel.Text = "Cancel"; 62 | this.btnCancel.UseVisualStyleBackColor = true; 63 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); 64 | // 65 | // ListInputForm 66 | // 67 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 68 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 69 | this.ClientSize = new System.Drawing.Size(372, 172); 70 | this.Controls.Add(this.btnCancel); 71 | this.Controls.Add(this.btnAccept); 72 | this.Controls.Add(this.lbItems); 73 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 74 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 75 | this.Name = "ListInputForm"; 76 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 77 | this.Text = "Select one"; 78 | this.Load += new System.EventHandler(this.ListInputForm_Load); 79 | this.ResumeLayout(false); 80 | 81 | } 82 | 83 | #endregion 84 | 85 | private System.Windows.Forms.ListBox lbItems; 86 | private System.Windows.Forms.Button btnAccept; 87 | private System.Windows.Forms.Button btnCancel; 88 | } 89 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/ListInputForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace Steam_Desktop_Authenticator 12 | { 13 | public partial class ListInputForm : Form 14 | { 15 | public ListInputForm(List options) 16 | { 17 | Items = options; 18 | InitializeComponent(); 19 | } 20 | 21 | public int SelectedIndex; 22 | List Items; 23 | 24 | private void ListInputForm_Load(object sender, EventArgs e) 25 | { 26 | foreach (var item in Items) 27 | { 28 | lbItems.Items.Add(item); 29 | } 30 | } 31 | 32 | private void btnAccept_Click(object sender, EventArgs e) 33 | { 34 | if (lbItems.SelectedIndex != -1) 35 | { 36 | SelectedIndex = lbItems.SelectedIndex; 37 | this.Close(); 38 | } 39 | } 40 | 41 | private void btnCancel_Click(object sender, EventArgs e) 42 | { 43 | this.Close(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/LoginForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class LoginForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LoginForm)); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.txtUsername = new System.Windows.Forms.TextBox(); 34 | this.txtPassword = new System.Windows.Forms.TextBox(); 35 | this.label2 = new System.Windows.Forms.Label(); 36 | this.btnSteamLogin = new System.Windows.Forms.Button(); 37 | this.labelLoginExplanation = new System.Windows.Forms.Label(); 38 | this.SuspendLayout(); 39 | // 40 | // label1 41 | // 42 | this.label1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 43 | this.label1.ForeColor = System.Drawing.SystemColors.ControlText; 44 | this.label1.Location = new System.Drawing.Point(12, 30); 45 | this.label1.Name = "label1"; 46 | this.label1.Size = new System.Drawing.Size(86, 25); 47 | this.label1.TabIndex = 0; 48 | this.label1.Text = "Username:"; 49 | this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 50 | // 51 | // txtUsername 52 | // 53 | this.txtUsername.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 54 | this.txtUsername.Location = new System.Drawing.Point(101, 31); 55 | this.txtUsername.Name = "txtUsername"; 56 | this.txtUsername.Size = new System.Drawing.Size(220, 25); 57 | this.txtUsername.TabIndex = 1; 58 | // 59 | // txtPassword 60 | // 61 | this.txtPassword.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 62 | this.txtPassword.Location = new System.Drawing.Point(101, 63); 63 | this.txtPassword.Name = "txtPassword"; 64 | this.txtPassword.PasswordChar = '*'; 65 | this.txtPassword.Size = new System.Drawing.Size(220, 25); 66 | this.txtPassword.TabIndex = 3; 67 | // 68 | // label2 69 | // 70 | this.label2.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 71 | this.label2.ForeColor = System.Drawing.SystemColors.ControlText; 72 | this.label2.Location = new System.Drawing.Point(12, 62); 73 | this.label2.Name = "label2"; 74 | this.label2.Size = new System.Drawing.Size(83, 25); 75 | this.label2.TabIndex = 2; 76 | this.label2.Text = "Password:"; 77 | this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 78 | // 79 | // btnSteamLogin 80 | // 81 | this.btnSteamLogin.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 82 | this.btnSteamLogin.Location = new System.Drawing.Point(224, 147); 83 | this.btnSteamLogin.Name = "btnSteamLogin"; 84 | this.btnSteamLogin.Size = new System.Drawing.Size(110, 33); 85 | this.btnSteamLogin.TabIndex = 4; 86 | this.btnSteamLogin.Text = "Login"; 87 | this.btnSteamLogin.UseVisualStyleBackColor = true; 88 | this.btnSteamLogin.Click += new System.EventHandler(this.btnSteamLogin_Click); 89 | // 90 | // labelLoginExplanation 91 | // 92 | this.labelLoginExplanation.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 93 | this.labelLoginExplanation.Location = new System.Drawing.Point(15, 98); 94 | this.labelLoginExplanation.Name = "labelLoginExplanation"; 95 | this.labelLoginExplanation.Size = new System.Drawing.Size(306, 46); 96 | this.labelLoginExplanation.TabIndex = 5; 97 | this.labelLoginExplanation.Text = "This will activate Steam Desktop Authenticator on your Steam account. This requir" + 98 | "es a phone number that can receive SMS."; 99 | // 100 | // LoginForm 101 | // 102 | this.AcceptButton = this.btnSteamLogin; 103 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 104 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 105 | this.ClientSize = new System.Drawing.Size(346, 193); 106 | this.Controls.Add(this.labelLoginExplanation); 107 | this.Controls.Add(this.btnSteamLogin); 108 | this.Controls.Add(this.txtPassword); 109 | this.Controls.Add(this.label2); 110 | this.Controls.Add(this.txtUsername); 111 | this.Controls.Add(this.label1); 112 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 113 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 114 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 115 | this.ImeMode = System.Windows.Forms.ImeMode.On; 116 | this.MaximizeBox = false; 117 | this.Name = "LoginForm"; 118 | this.ShowIcon = false; 119 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 120 | this.Text = "Steam Login"; 121 | this.Load += new System.EventHandler(this.LoginForm_Load); 122 | this.ResumeLayout(false); 123 | this.PerformLayout(); 124 | 125 | } 126 | 127 | #endregion 128 | 129 | private System.Windows.Forms.Label label1; 130 | private System.Windows.Forms.TextBox txtUsername; 131 | private System.Windows.Forms.TextBox txtPassword; 132 | private System.Windows.Forms.Label label2; 133 | private System.Windows.Forms.Button btnSteamLogin; 134 | private System.Windows.Forms.Label labelLoginExplanation; 135 | } 136 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/MaFileEncryptedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Steam_Desktop_Authenticator 8 | { 9 | class MaFileEncryptedException : Exception 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/ManifestParseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Steam_Desktop_Authenticator 8 | { 9 | class ManifestParseException : Exception 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Diagnostics; 4 | using CommandLine; 5 | 6 | namespace Steam_Desktop_Authenticator 7 | { 8 | static class Program 9 | { 10 | public static Process PriorProcess() 11 | // Returns a System.Diagnostics.Process pointing to 12 | // a pre-existing process with the same name as the 13 | // current one, if any; or null if the current process 14 | // is unique. 15 | { 16 | try 17 | { 18 | Process curr = Process.GetCurrentProcess(); 19 | Process[] procs = Process.GetProcessesByName(curr.ProcessName); 20 | foreach (Process p in procs) 21 | { 22 | if ((p.Id != curr.Id) && 23 | (p.MainModule.FileName == curr.MainModule.FileName)) 24 | return p; 25 | } 26 | return null; 27 | } 28 | catch (Exception) 29 | { 30 | return null; 31 | } 32 | } 33 | 34 | /// 35 | /// The main entry point for the application. 36 | /// 37 | [STAThread] 38 | static void Main(string[] args) 39 | { 40 | // run the program only once 41 | if (PriorProcess() != null) 42 | { 43 | MessageBox.Show("Another instance of the app is already running."); 44 | return; 45 | } 46 | 47 | // Parse command line arguments 48 | var options = new CommandLineOptions(); 49 | Parser.Default.ParseArguments(args, options); 50 | 51 | Application.EnableVisualStyles(); 52 | Application.SetCompatibleTextRenderingDefault(false); 53 | 54 | Manifest man; 55 | 56 | try 57 | { 58 | man = Manifest.GetManifest(); 59 | } 60 | catch (ManifestParseException) 61 | { 62 | // Manifest file was corrupted, generate a new one. 63 | try 64 | { 65 | MessageBox.Show("Your settings were unexpectedly corrupted and were reset to defaults.", "Steam Desktop Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 66 | man = Manifest.GenerateNewManifest(true); 67 | } 68 | catch (MaFileEncryptedException) 69 | { 70 | // An maFile was encrypted, we're fucked. 71 | MessageBox.Show("Sorry, but SDA was unable to recover your accounts since you used encryption.\nYou'll need to recover your Steam accounts by removing the authenticator.\nClick OK to view instructions.", "Steam Desktop Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Error); 72 | System.Diagnostics.Process.Start(@"https://github.com/Jessecar96/SteamDesktopAuthenticator/wiki/Help!-I'm-locked-out-of-my-account"); 73 | return; 74 | } 75 | } 76 | 77 | if (man.FirstRun) 78 | { 79 | // Install VC++ Redist and wait 80 | new InstallRedistribForm().ShowDialog(); 81 | 82 | if (man.Entries.Count > 0) 83 | { 84 | // Already has accounts, just run 85 | MainForm mf = new MainForm(); 86 | mf.SetEncryptionKey(options.EncryptionKey); 87 | mf.StartSilent(options.Silent); 88 | Application.Run(mf); 89 | } 90 | else 91 | { 92 | // No accounts, run welcome form 93 | Application.Run(new WelcomeForm()); 94 | } 95 | } 96 | else 97 | { 98 | MainForm mf = new MainForm(); 99 | mf.SetEncryptionKey(options.EncryptionKey); 100 | mf.StartSilent(options.Silent); 101 | Application.Run(mf); 102 | } 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Steam Desktop Authenticator")] 9 | [assembly: AssemblyDescription("Desktop implementation of Steam's mobile authenticator app")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Steam Desktop Authenticator")] 13 | [assembly: AssemblyCopyright("Copyright 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(true)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0f37c513-9af4-42c8-9ce9-f9b3bfa55e4e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.11")] 36 | [assembly: AssemblyFileVersion("1.0.11")] 37 | 38 | [assembly: AssemblyMetadata("SquirrelAwareVersion", "1")] -------------------------------------------------------------------------------- /Steam Desktop Authenticator/ResourceResponseFilter.cs: -------------------------------------------------------------------------------- 1 | using CefSharp; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.IO; 8 | 9 | namespace Steam_Desktop_Authenticator 10 | { 11 | class ResourceResponseFilter : IResponseFilter 12 | { 13 | public void Dispose() 14 | { 15 | 16 | } 17 | 18 | public FilterStatus Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten) 19 | { 20 | dataInRead = 0; 21 | dataOutWritten = 0; 22 | return FilterStatus.Error; 23 | } 24 | 25 | public bool InitFilter() 26 | { 27 | return false; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/SettingsForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class SettingsForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingsForm)); 32 | this.chkPeriodicChecking = new System.Windows.Forms.CheckBox(); 33 | this.btnSave = new System.Windows.Forms.Button(); 34 | this.numPeriodicInterval = new System.Windows.Forms.NumericUpDown(); 35 | this.label1 = new System.Windows.Forms.Label(); 36 | this.chkCheckAll = new System.Windows.Forms.CheckBox(); 37 | this.chkConfirmMarket = new System.Windows.Forms.CheckBox(); 38 | this.chkConfirmTrades = new System.Windows.Forms.CheckBox(); 39 | ((System.ComponentModel.ISupportInitialize)(this.numPeriodicInterval)).BeginInit(); 40 | this.SuspendLayout(); 41 | // 42 | // chkPeriodicChecking 43 | // 44 | this.chkPeriodicChecking.AutoSize = true; 45 | this.chkPeriodicChecking.Location = new System.Drawing.Point(12, 12); 46 | this.chkPeriodicChecking.Name = "chkPeriodicChecking"; 47 | this.chkPeriodicChecking.Size = new System.Drawing.Size(233, 30); 48 | this.chkPeriodicChecking.TabIndex = 0; 49 | this.chkPeriodicChecking.Text = "Periodically check for new confirmations\r\nand show a popup when they arrive"; 50 | this.chkPeriodicChecking.UseVisualStyleBackColor = true; 51 | this.chkPeriodicChecking.CheckedChanged += new System.EventHandler(this.chkPeriodicChecking_CheckedChanged); 52 | // 53 | // btnSave 54 | // 55 | this.btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 56 | | System.Windows.Forms.AnchorStyles.Right))); 57 | this.btnSave.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 58 | this.btnSave.Location = new System.Drawing.Point(12, 152); 59 | this.btnSave.Name = "btnSave"; 60 | this.btnSave.Size = new System.Drawing.Size(224, 38); 61 | this.btnSave.TabIndex = 1; 62 | this.btnSave.Text = "Save"; 63 | this.btnSave.UseVisualStyleBackColor = true; 64 | this.btnSave.Click += new System.EventHandler(this.btnSave_Click); 65 | // 66 | // numPeriodicInterval 67 | // 68 | this.numPeriodicInterval.Location = new System.Drawing.Point(12, 51); 69 | this.numPeriodicInterval.Minimum = new decimal(new int[] { 70 | 5, 71 | 0, 72 | 0, 73 | 0}); 74 | this.numPeriodicInterval.Name = "numPeriodicInterval"; 75 | this.numPeriodicInterval.Size = new System.Drawing.Size(41, 22); 76 | this.numPeriodicInterval.TabIndex = 2; 77 | this.numPeriodicInterval.Value = new decimal(new int[] { 78 | 5, 79 | 0, 80 | 0, 81 | 0}); 82 | // 83 | // label1 84 | // 85 | this.label1.AutoSize = true; 86 | this.label1.Location = new System.Drawing.Point(59, 49); 87 | this.label1.Name = "label1"; 88 | this.label1.Size = new System.Drawing.Size(150, 26); 89 | this.label1.TabIndex = 3; 90 | this.label1.Text = "Seconds between checking \r\nfor confirmations"; 91 | // 92 | // chkCheckAll 93 | // 94 | this.chkCheckAll.AutoSize = true; 95 | this.chkCheckAll.Location = new System.Drawing.Point(12, 81); 96 | this.chkCheckAll.Name = "chkCheckAll"; 97 | this.chkCheckAll.Size = new System.Drawing.Size(213, 17); 98 | this.chkCheckAll.TabIndex = 4; 99 | this.chkCheckAll.Text = "Check all accounts for confirmations"; 100 | this.chkCheckAll.UseVisualStyleBackColor = true; 101 | // 102 | // chkConfirmMarket 103 | // 104 | this.chkConfirmMarket.AutoSize = true; 105 | this.chkConfirmMarket.Location = new System.Drawing.Point(12, 104); 106 | this.chkConfirmMarket.Name = "chkConfirmMarket"; 107 | this.chkConfirmMarket.Size = new System.Drawing.Size(198, 17); 108 | this.chkConfirmMarket.TabIndex = 5; 109 | this.chkConfirmMarket.Text = "Auto-confirm market transactions"; 110 | this.chkConfirmMarket.UseVisualStyleBackColor = true; 111 | this.chkConfirmMarket.CheckedChanged += new System.EventHandler(this.chkConfirmMarket_CheckedChanged); 112 | // 113 | // chkConfirmTrades 114 | // 115 | this.chkConfirmTrades.AutoSize = true; 116 | this.chkConfirmTrades.Location = new System.Drawing.Point(12, 127); 117 | this.chkConfirmTrades.Name = "chkConfirmTrades"; 118 | this.chkConfirmTrades.Size = new System.Drawing.Size(129, 17); 119 | this.chkConfirmTrades.TabIndex = 6; 120 | this.chkConfirmTrades.Text = "Auto-confirm trades"; 121 | this.chkConfirmTrades.UseVisualStyleBackColor = true; 122 | this.chkConfirmTrades.CheckedChanged += new System.EventHandler(this.chkConfirmTrades_CheckedChanged); 123 | // 124 | // SettingsForm 125 | // 126 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 127 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 128 | this.ClientSize = new System.Drawing.Size(244, 202); 129 | this.Controls.Add(this.chkConfirmTrades); 130 | this.Controls.Add(this.chkConfirmMarket); 131 | this.Controls.Add(this.chkCheckAll); 132 | this.Controls.Add(this.label1); 133 | this.Controls.Add(this.numPeriodicInterval); 134 | this.Controls.Add(this.btnSave); 135 | this.Controls.Add(this.chkPeriodicChecking); 136 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 137 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 138 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 139 | this.MaximizeBox = false; 140 | this.Name = "SettingsForm"; 141 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 142 | this.Text = "Settings"; 143 | ((System.ComponentModel.ISupportInitialize)(this.numPeriodicInterval)).EndInit(); 144 | this.ResumeLayout(false); 145 | this.PerformLayout(); 146 | 147 | } 148 | 149 | #endregion 150 | 151 | private System.Windows.Forms.CheckBox chkPeriodicChecking; 152 | private System.Windows.Forms.Button btnSave; 153 | private System.Windows.Forms.NumericUpDown numPeriodicInterval; 154 | private System.Windows.Forms.Label label1; 155 | private System.Windows.Forms.CheckBox chkCheckAll; 156 | private System.Windows.Forms.CheckBox chkConfirmMarket; 157 | private System.Windows.Forms.CheckBox chkConfirmTrades; 158 | } 159 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/SettingsForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Steam_Desktop_Authenticator 5 | { 6 | public partial class SettingsForm : Form 7 | { 8 | Manifest manifest; 9 | bool fullyLoaded = false; 10 | 11 | public SettingsForm() 12 | { 13 | InitializeComponent(); 14 | 15 | // Get latest manifest 16 | manifest = Manifest.GetManifest(true); 17 | 18 | chkPeriodicChecking.Checked = manifest.PeriodicChecking; 19 | numPeriodicInterval.Value = manifest.PeriodicCheckingInterval; 20 | chkCheckAll.Checked = manifest.CheckAllAccounts; 21 | chkConfirmMarket.Checked = manifest.AutoConfirmMarketTransactions; 22 | chkConfirmTrades.Checked = manifest.AutoConfirmTrades; 23 | 24 | SetControlsEnabledState(chkPeriodicChecking.Checked); 25 | 26 | fullyLoaded = true; 27 | } 28 | 29 | private void SetControlsEnabledState(bool enabled) 30 | { 31 | numPeriodicInterval.Enabled = chkCheckAll.Enabled = chkConfirmMarket.Enabled = chkConfirmTrades.Enabled = enabled; 32 | } 33 | 34 | private void ShowWarning(CheckBox affectedBox) 35 | { 36 | if (!fullyLoaded) return; 37 | 38 | var result = MessageBox.Show("Warning: enabling this will severely reduce the security of your items! Use of this option is at your own risk. Would you like to continue?", "Warning!", MessageBoxButtons.YesNo); 39 | if (result == DialogResult.No) 40 | { 41 | affectedBox.Checked = false; 42 | } 43 | } 44 | 45 | private void btnSave_Click(object sender, EventArgs e) 46 | { 47 | manifest.PeriodicChecking = chkPeriodicChecking.Checked; 48 | manifest.PeriodicCheckingInterval = (int)numPeriodicInterval.Value; 49 | manifest.CheckAllAccounts = chkCheckAll.Checked; 50 | manifest.AutoConfirmMarketTransactions = chkConfirmMarket.Checked; 51 | manifest.AutoConfirmTrades = chkConfirmTrades.Checked; 52 | manifest.Save(); 53 | this.Close(); 54 | } 55 | 56 | private void chkPeriodicChecking_CheckedChanged(object sender, EventArgs e) 57 | { 58 | SetControlsEnabledState(chkPeriodicChecking.Checked); 59 | } 60 | 61 | private void chkConfirmMarket_CheckedChanged(object sender, EventArgs e) 62 | { 63 | if (chkConfirmMarket.Checked) 64 | ShowWarning(chkConfirmMarket); 65 | } 66 | 67 | private void chkConfirmTrades_CheckedChanged(object sender, EventArgs e) 68 | { 69 | if (chkConfirmTrades.Checked) 70 | ShowWarning(chkConfirmTrades); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/Steam Desktop Authenticator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Debug 10 | AnyCPU 11 | {0F37C513-9AF4-42C8-9CE9-F9B3BFA55E4E} 12 | WinExe 13 | Properties 14 | Steam_Desktop_Authenticator 15 | Steam Desktop Authenticator 16 | v4.7.2 17 | 512 18 | true 19 | false 20 | 21 | 22 | 23 | publish\ 24 | true 25 | Disk 26 | false 27 | Foreground 28 | 7 29 | Days 30 | false 31 | false 32 | true 33 | 0 34 | 0.2.2.%2a 35 | false 36 | true 37 | 38 | 39 | false 40 | 41 | 42 | 43 | 44 | 45 | 46 | true 47 | bin\x64\Debug\ 48 | DEBUG;TRACE 49 | full 50 | x64 51 | prompt 52 | MinimumRecommendedRules.ruleset 53 | true 54 | 55 | 56 | bin\x64\Release\ 57 | 58 | 59 | true 60 | none 61 | x64 62 | prompt 63 | MinimumRecommendedRules.ruleset 64 | true 65 | 66 | 67 | true 68 | bin\Debug\ 69 | 70 | 71 | full 72 | x86 73 | prompt 74 | MinimumRecommendedRules.ruleset 75 | true 76 | Auto 77 | 78 | 79 | bin\Release\ 80 | 81 | 82 | true 83 | pdbonly 84 | x86 85 | prompt 86 | MinimumRecommendedRules.ruleset 87 | true 88 | Auto 89 | true 90 | false 91 | 92 | 93 | icon.ico 94 | 95 | 96 | 97 | packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll 98 | 99 | 100 | packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | Form 118 | 119 | 120 | ConfirmationFormWeb.cs 121 | 122 | 123 | 124 | 125 | Form 126 | 127 | 128 | CaptchaForm.cs 129 | 130 | 131 | Form 132 | 133 | 134 | ImportAccountForm.cs 135 | 136 | 137 | Form 138 | 139 | 140 | InputForm.cs 141 | 142 | 143 | Form 144 | 145 | 146 | InstallRedistribForm.cs 147 | 148 | 149 | Form 150 | 151 | 152 | ListInputForm.cs 153 | 154 | 155 | Form 156 | 157 | 158 | LoginForm.cs 159 | 160 | 161 | 162 | Form 163 | 164 | 165 | MainForm.cs 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | Form 175 | 176 | 177 | SettingsForm.cs 178 | 179 | 180 | Form 181 | 182 | 183 | TradePopupForm.cs 184 | 185 | 186 | Form 187 | 188 | 189 | WelcomeForm.cs 190 | 191 | 192 | CaptchaForm.cs 193 | 194 | 195 | ConfirmationFormWeb.cs 196 | 197 | 198 | ImportAccountForm.cs 199 | 200 | 201 | InputForm.cs 202 | 203 | 204 | InstallRedistribForm.cs 205 | 206 | 207 | ListInputForm.cs 208 | 209 | 210 | LoginForm.cs 211 | 212 | 213 | MainForm.cs 214 | 215 | 216 | SettingsForm.cs 217 | 218 | 219 | TradePopupForm.cs 220 | 221 | 222 | WelcomeForm.cs 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | {5ad0934e-f6c4-4ae5-83af-c788313b2a87} 232 | SteamAuth 233 | 234 | 235 | 236 | 237 | False 238 | Microsoft .NET Framework 4.5.2 %28x86 and x64%29 239 | true 240 | 241 | 242 | False 243 | .NET Framework 3.5 SP1 244 | false 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 271 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/Steam Desktop Authenticator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Steam Desktop Authenticator", "Steam Desktop Authenticator.csproj", "{0F37C513-9AF4-42C8-9CE9-F9B3BFA55E4E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamAuth", "..\lib\SteamAuth\SteamAuth\SteamAuth.csproj", "{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x86 = Debug|x86 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {0F37C513-9AF4-42C8-9CE9-F9B3BFA55E4E}.Debug|x86.ActiveCfg = Debug|x86 17 | {0F37C513-9AF4-42C8-9CE9-F9B3BFA55E4E}.Debug|x86.Build.0 = Debug|x86 18 | {0F37C513-9AF4-42C8-9CE9-F9B3BFA55E4E}.Release|x86.ActiveCfg = Release|x86 19 | {0F37C513-9AF4-42C8-9CE9-F9B3BFA55E4E}.Release|x86.Build.0 = Release|x86 20 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Debug|x86.ActiveCfg = Debug|Any CPU 21 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Debug|x86.Build.0 = Debug|Any CPU 22 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|x86.ActiveCfg = Release|Any CPU 23 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|x86.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/TradePopupForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class TradePopupForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TradePopupForm)); 32 | this.lblDesc = new System.Windows.Forms.Label(); 33 | this.btnDeny = new System.Windows.Forms.Button(); 34 | this.btnAccept = new System.Windows.Forms.Button(); 35 | this.lblStatus = new System.Windows.Forms.Label(); 36 | this.lblAccount = new System.Windows.Forms.Label(); 37 | this.SuspendLayout(); 38 | // 39 | // lblDesc 40 | // 41 | this.lblDesc.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 42 | this.lblDesc.Location = new System.Drawing.Point(12, 23); 43 | this.lblDesc.Name = "lblDesc"; 44 | this.lblDesc.Size = new System.Drawing.Size(142, 38); 45 | this.lblDesc.TabIndex = 1; 46 | this.lblDesc.Text = "trade description"; 47 | this.lblDesc.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 48 | // 49 | // btnDeny 50 | // 51 | this.btnDeny.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); 52 | this.btnDeny.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 53 | this.btnDeny.Location = new System.Drawing.Point(12, 87); 54 | this.btnDeny.Name = "btnDeny"; 55 | this.btnDeny.Size = new System.Drawing.Size(69, 32); 56 | this.btnDeny.TabIndex = 2; 57 | this.btnDeny.Text = "Deny"; 58 | this.btnDeny.UseVisualStyleBackColor = false; 59 | this.btnDeny.Click += new System.EventHandler(this.btnDeny_Click); 60 | // 61 | // btnAccept 62 | // 63 | this.btnAccept.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192))))); 64 | this.btnAccept.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 65 | this.btnAccept.Location = new System.Drawing.Point(87, 87); 66 | this.btnAccept.Name = "btnAccept"; 67 | this.btnAccept.Size = new System.Drawing.Size(67, 32); 68 | this.btnAccept.TabIndex = 2; 69 | this.btnAccept.Text = "Accept"; 70 | this.btnAccept.UseVisualStyleBackColor = false; 71 | this.btnAccept.Click += new System.EventHandler(this.btnAccept_Click); 72 | // 73 | // lblStatus 74 | // 75 | this.lblStatus.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 76 | this.lblStatus.Location = new System.Drawing.Point(0, 61); 77 | this.lblStatus.Name = "lblStatus"; 78 | this.lblStatus.Size = new System.Drawing.Size(166, 19); 79 | this.lblStatus.TabIndex = 3; 80 | this.lblStatus.Text = "status"; 81 | this.lblStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 82 | // 83 | // lblAccount 84 | // 85 | this.lblAccount.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 86 | this.lblAccount.Location = new System.Drawing.Point(12, 0); 87 | this.lblAccount.Name = "lblAccount"; 88 | this.lblAccount.Size = new System.Drawing.Size(142, 23); 89 | this.lblAccount.TabIndex = 4; 90 | this.lblAccount.Text = "account name"; 91 | this.lblAccount.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 92 | // 93 | // TradePopupForm 94 | // 95 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 96 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 97 | this.ClientSize = new System.Drawing.Size(166, 131); 98 | this.Controls.Add(this.lblAccount); 99 | this.Controls.Add(this.lblStatus); 100 | this.Controls.Add(this.btnAccept); 101 | this.Controls.Add(this.btnDeny); 102 | this.Controls.Add(this.lblDesc); 103 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 104 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 105 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 106 | this.Name = "TradePopupForm"; 107 | this.Text = "New confirmation"; 108 | this.TopMost = true; 109 | this.Load += new System.EventHandler(this.TradePopupForm_Load); 110 | this.ResumeLayout(false); 111 | 112 | } 113 | 114 | #endregion 115 | private System.Windows.Forms.Label lblDesc; 116 | private System.Windows.Forms.Button btnDeny; 117 | private System.Windows.Forms.Button btnAccept; 118 | private System.Windows.Forms.Label lblStatus; 119 | private System.Windows.Forms.Label lblAccount; 120 | } 121 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/TradePopupForm.cs: -------------------------------------------------------------------------------- 1 | using SteamAuth; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | 12 | namespace Steam_Desktop_Authenticator 13 | { 14 | public partial class TradePopupForm : Form 15 | { 16 | private SteamGuardAccount acc; 17 | private List confirms = new List(); 18 | private bool deny2, accept2; 19 | 20 | public TradePopupForm() 21 | { 22 | InitializeComponent(); 23 | lblStatus.Text = ""; 24 | } 25 | 26 | public SteamGuardAccount Account 27 | { 28 | get { return acc; } 29 | set { acc = value; lblAccount.Text = acc.AccountName; } 30 | } 31 | 32 | public Confirmation[] Confirmations 33 | { 34 | get { return confirms.ToArray(); } 35 | set { confirms = new List(value); } 36 | } 37 | 38 | private void TradePopupForm_Load(object sender, EventArgs e) 39 | { 40 | this.Location = (Point)Size.Subtract(Screen.GetWorkingArea(this).Size, this.Size); 41 | } 42 | 43 | private void btnAccept_Click(object sender, EventArgs e) 44 | { 45 | if (!accept2) 46 | { 47 | // Allow user to confirm first 48 | lblStatus.Text = "Press Accept again to confirm"; 49 | btnAccept.BackColor = Color.FromArgb(128, 255, 128); 50 | accept2 = true; 51 | } 52 | else 53 | { 54 | lblStatus.Text = "Accepting..."; 55 | acc.AcceptConfirmation(confirms[0]); 56 | confirms.RemoveAt(0); 57 | Reset(); 58 | } 59 | } 60 | 61 | private void btnDeny_Click(object sender, EventArgs e) 62 | { 63 | if (!deny2) 64 | { 65 | lblStatus.Text = "Press Deny again to confirm"; 66 | btnDeny.BackColor = Color.FromArgb(255, 255, 128); 67 | deny2 = true; 68 | } 69 | else 70 | { 71 | lblStatus.Text = "Denying..."; 72 | acc.DenyConfirmation(confirms[0]); 73 | confirms.RemoveAt(0); 74 | Reset(); 75 | } 76 | } 77 | 78 | private void Reset() 79 | { 80 | deny2 = false; 81 | accept2 = false; 82 | btnAccept.BackColor = Color.FromArgb(192, 255, 192); 83 | btnDeny.BackColor = Color.FromArgb(255, 255, 192); 84 | 85 | btnAccept.Text = "Accept"; 86 | btnDeny.Text = "Deny"; 87 | lblAccount.Text = ""; 88 | lblStatus.Text = ""; 89 | 90 | if (confirms.Count == 0) 91 | { 92 | this.Hide(); 93 | } 94 | else 95 | { 96 | //TODO: Re-add confirmation description support to SteamAuth. 97 | lblDesc.Text = "Confirmation"; 98 | } 99 | } 100 | 101 | public void Popup() 102 | { 103 | Reset(); 104 | this.Show(); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/WelcomeForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Steam_Desktop_Authenticator 2 | { 3 | partial class WelcomeForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WelcomeForm)); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.btnImportConfig = new System.Windows.Forms.Button(); 34 | this.label2 = new System.Windows.Forms.Label(); 35 | this.btnJustStart = new System.Windows.Forms.Button(); 36 | this.SuspendLayout(); 37 | // 38 | // label1 39 | // 40 | this.label1.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 41 | this.label1.Location = new System.Drawing.Point(12, 9); 42 | this.label1.Name = "label1"; 43 | this.label1.Size = new System.Drawing.Size(366, 73); 44 | this.label1.TabIndex = 0; 45 | this.label1.Text = "Welcome to\r\nSteam Desktop Authenticator"; 46 | this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 47 | // 48 | // btnImportConfig 49 | // 50 | this.btnImportConfig.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 51 | this.btnImportConfig.Location = new System.Drawing.Point(12, 134); 52 | this.btnImportConfig.Name = "btnImportConfig"; 53 | this.btnImportConfig.Size = new System.Drawing.Size(366, 51); 54 | this.btnImportConfig.TabIndex = 1; 55 | this.btnImportConfig.Text = "I already setup Steam Desktop Authenticator in another location on this PC and I " + 56 | "want to import its account(s).\r\n"; 57 | this.btnImportConfig.UseVisualStyleBackColor = true; 58 | this.btnImportConfig.Click += new System.EventHandler(this.btnImportConfig_Click); 59 | // 60 | // label2 61 | // 62 | this.label2.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 63 | this.label2.Location = new System.Drawing.Point(12, 86); 64 | this.label2.Name = "label2"; 65 | this.label2.Size = new System.Drawing.Size(366, 37); 66 | this.label2.TabIndex = 2; 67 | this.label2.Text = "Select an item to get started:"; 68 | this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 69 | // 70 | // btnJustStart 71 | // 72 | this.btnJustStart.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 73 | this.btnJustStart.Location = new System.Drawing.Point(12, 191); 74 | this.btnJustStart.Name = "btnJustStart"; 75 | this.btnJustStart.Size = new System.Drawing.Size(366, 52); 76 | this.btnJustStart.TabIndex = 4; 77 | this.btnJustStart.Text = "This is my first time and \r\nI just want to sign into my Steam Account(s)."; 78 | this.btnJustStart.UseVisualStyleBackColor = true; 79 | this.btnJustStart.Click += new System.EventHandler(this.btnJustStart_Click); 80 | // 81 | // WelcomeForm 82 | // 83 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 84 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 85 | this.ClientSize = new System.Drawing.Size(390, 255); 86 | this.Controls.Add(this.btnJustStart); 87 | this.Controls.Add(this.label2); 88 | this.Controls.Add(this.btnImportConfig); 89 | this.Controls.Add(this.label1); 90 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 91 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 92 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 93 | this.MaximizeBox = false; 94 | this.Name = "WelcomeForm"; 95 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 96 | this.Text = "Steam Desktop Authenticator"; 97 | this.ResumeLayout(false); 98 | 99 | } 100 | 101 | #endregion 102 | 103 | private System.Windows.Forms.Label label1; 104 | private System.Windows.Forms.Button btnImportConfig; 105 | private System.Windows.Forms.Label label2; 106 | private System.Windows.Forms.Button btnJustStart; 107 | } 108 | } -------------------------------------------------------------------------------- /Steam Desktop Authenticator/WelcomeForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | 12 | namespace Steam_Desktop_Authenticator 13 | { 14 | public partial class WelcomeForm : Form 15 | { 16 | private Manifest man; 17 | 18 | public WelcomeForm() 19 | { 20 | InitializeComponent(); 21 | man = Manifest.GetManifest(); 22 | } 23 | 24 | private void btnJustStart_Click(object sender, EventArgs e) 25 | { 26 | // Mark as not first run anymore 27 | man.FirstRun = false; 28 | man.Save(); 29 | 30 | showMainForm(); 31 | } 32 | 33 | private void btnImportConfig_Click(object sender, EventArgs e) 34 | { 35 | // Let the user select the config dir 36 | FolderBrowserDialog folderBrowser = new FolderBrowserDialog(); 37 | folderBrowser.Description = "Select the folder of your old Steam Desktop Authenticator install"; 38 | DialogResult userClickedOK = folderBrowser.ShowDialog(); 39 | 40 | if (userClickedOK == DialogResult.OK) 41 | { 42 | string path = folderBrowser.SelectedPath; 43 | string pathToCopy = null; 44 | 45 | if (Directory.Exists(path + "/maFiles")) 46 | { 47 | // User selected the root install dir 48 | pathToCopy = path + "/maFiles"; 49 | } 50 | else if (File.Exists(path + "/manifest.json")) 51 | { 52 | // User selected the maFiles dir 53 | pathToCopy = path; 54 | } 55 | else 56 | { 57 | // Could not find either. 58 | MessageBox.Show("This folder does not contain either a manifest.json or an maFiles folder.\nPlease select the location where you had Steam Desktop Authenticator installed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 59 | return; 60 | } 61 | 62 | // Copy the contents of the config dir to the new config dir 63 | string currentPath = Manifest.GetExecutableDir(); 64 | 65 | // Create config dir if we don't have it 66 | if (!Directory.Exists(currentPath + "/maFiles")) 67 | { 68 | Directory.CreateDirectory(currentPath + "/maFiles"); 69 | } 70 | 71 | // Copy all files from the old dir to the new one 72 | foreach (string newPath in Directory.GetFiles(pathToCopy, "*.*", SearchOption.AllDirectories)) 73 | { 74 | File.Copy(newPath, newPath.Replace(pathToCopy, currentPath + "/maFiles"), true); 75 | } 76 | 77 | // Set first run in manifest 78 | try 79 | { 80 | man = Manifest.GetManifest(true); 81 | man.FirstRun = false; 82 | man.Save(); 83 | } 84 | catch (ManifestParseException) 85 | { 86 | // Manifest file was corrupted, generate a new one. 87 | try 88 | { 89 | MessageBox.Show("Your settings were unexpectedly corrupted and were reset to defaults.", "Steam Desktop Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 90 | man = Manifest.GenerateNewManifest(true); 91 | } 92 | catch (MaFileEncryptedException) 93 | { 94 | // An maFile was encrypted, we're fucked. 95 | MessageBox.Show("Sorry, but SDA was unable to recover your accounts since you used encryption.\nYou'll need to recover your Steam accounts by removing the authenticator.\nClick OK to view instructions.", "Steam Desktop Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Error); 96 | System.Diagnostics.Process.Start(@"https://github.com/Jessecar96/SteamDesktopAuthenticator/wiki/Help!-I'm-locked-out-of-my-account"); 97 | this.Close(); 98 | return; 99 | } 100 | } 101 | 102 | // All done! 103 | MessageBox.Show("All accounts and settings have been imported! Click OK to continue.", "Import accounts", MessageBoxButtons.OK, MessageBoxIcon.Information); 104 | showMainForm(); 105 | } 106 | 107 | } 108 | 109 | private void showMainForm() 110 | { 111 | this.Hide(); 112 | new MainForm().Show(); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Steam Desktop Authenticator/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/therepower/SteamDesktopAuthenticator-Temporary-Fix/5f2c7a25343e810508803ed0a032e099fc084f6c/Steam Desktop Authenticator/icon.ico -------------------------------------------------------------------------------- /Steam Desktop Authenticator/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/therepower/SteamDesktopAuthenticator-Temporary-Fix/5f2c7a25343e810508803ed0a032e099fc084f6c/icon.png -------------------------------------------------------------------------------- /lib/SteamAuth/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Joshua Coffey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /lib/SteamAuth/README.md: -------------------------------------------------------------------------------- 1 | # SteamAuth 2 | A C# library that provides vital Steam Mobile Authenticator functionality. **Looking for a desktop client to act as a Steam Mobile Authenticator? [Check out SteamDesktopAuthenticator](https://github.com/Jessecar96/SteamDesktopAuthenticator)** 3 | 4 | # Functionality 5 | Currently, this library can: 6 | 7 | * Generate login codes for a given Shared Secret 8 | * Login to a user account 9 | * Link and activate a new mobile authenticator to a user account after logging in 10 | * Remove itself from an account 11 | * Fetch, accept, and deny mobile confirmations 12 | 13 | # Requirements 14 | 15 | * [Newtonsoft.Json](http://www.newtonsoft.com/json) 16 | 17 | # Usage 18 | To generate login codes if you already have a Shared Secret, simply instantiate a `SteamGuardAccount` and set its `SharedSecret`. Then call `SteamGuardAccount.GenerateSteamGuardCode()`. 19 | 20 | To add a mobile authenticator to a user, instantiate a `UserLogin` instance which will allow you to login to the account. After logging in, instantiate an `AuthenticatorLinker` and use `AuthenticatorLinker.AddAuthenticator()` and `AuthenticatorLinker.FinalizeAddAuthenticator()` to link a new authenticator. **After calling AddAuthenticator(), and before calling FinalizeAddAuthenticator(), please save a JSON string of the `AuthenticatorLinker.LinkedAccount`. This will contain everything you need to generate subsequent codes. Failing to do this will lock you out of your account.** 21 | 22 | To fetch mobile confirmations, call `SteamGuardAccount.FetchConfirmations()`. You can then call `SteamGuardAccount.AcceptConfirmation` and `SteamGuardAccount.DenyConfirmation`. 23 | 24 | # Upcoming Features 25 | In order to be feature complete, this library will: 26 | 27 | * Be better documented (feature!!) 28 | 29 | 30 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/APIEndpoints.cs: -------------------------------------------------------------------------------- 1 | namespace SteamAuth 2 | { 3 | public static class APIEndpoints 4 | { 5 | public const string STEAMAPI_BASE = "https://api.steampowered.com"; 6 | public const string COMMUNITY_BASE = "https://steamcommunity.com"; 7 | public const string MOBILEAUTH_BASE = STEAMAPI_BASE + "/IMobileAuthService/%s/v0001"; 8 | public static string MOBILEAUTH_GETWGTOKEN = MOBILEAUTH_BASE.Replace("%s", "GetWGToken"); 9 | public const string TWO_FACTOR_BASE = STEAMAPI_BASE + "/ITwoFactorService/%s/v0001"; 10 | public static string TWO_FACTOR_TIME_QUERY = TWO_FACTOR_BASE.Replace("%s", "QueryTime"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/AuthenticatorLinker.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Specialized; 4 | using System.Net; 5 | using System.Security.Cryptography; 6 | using System.Threading; 7 | 8 | namespace SteamAuth 9 | { 10 | /// 11 | /// Handles the linking process for a new mobile authenticator. 12 | /// 13 | public class AuthenticatorLinker 14 | { 15 | /// 16 | /// Set to register a new phone number when linking. If a phone number is not set on the account, this must be set. If a phone number is set on the account, this must be null. 17 | /// 18 | public string PhoneNumber = null; 19 | 20 | /// 21 | /// Randomly-generated device ID. Should only be generated once per linker. 22 | /// 23 | public string DeviceID { get; private set; } 24 | 25 | /// 26 | /// After the initial link step, if successful, this will be the SteamGuard data for the account. PLEASE save this somewhere after generating it; it's vital data. 27 | /// 28 | public SteamGuardAccount LinkedAccount { get; private set; } 29 | 30 | /// 31 | /// True if the authenticator has been fully finalized. 32 | /// 33 | public bool Finalized = false; 34 | 35 | private SessionData _session; 36 | private CookieContainer _cookies; 37 | private bool confirmationEmailSent = false; 38 | 39 | public AuthenticatorLinker(SessionData session) 40 | { 41 | this._session = session; 42 | this.DeviceID = GenerateDeviceID(); 43 | 44 | this._cookies = new CookieContainer(); 45 | session.AddCookies(_cookies); 46 | } 47 | 48 | public LinkResult AddAuthenticator() 49 | { 50 | bool hasPhone = _hasPhoneAttached(); 51 | if (hasPhone && PhoneNumber != null) 52 | return LinkResult.MustRemovePhoneNumber; 53 | if (!hasPhone && PhoneNumber == null) 54 | return LinkResult.MustProvidePhoneNumber; 55 | 56 | if (!hasPhone) { 57 | if (confirmationEmailSent) { 58 | if (!_checkEmailConfirmation()) { 59 | return LinkResult.GeneralFailure; 60 | } 61 | } else if (!_addPhoneNumber()) { 62 | return LinkResult.GeneralFailure; 63 | } else { 64 | confirmationEmailSent = true; 65 | return LinkResult.MustConfirmEmail; 66 | } 67 | } 68 | 69 | var postData = new NameValueCollection(); 70 | postData.Add("access_token", _session.OAuthToken); 71 | postData.Add("steamid", _session.SteamID.ToString()); 72 | postData.Add("authenticator_type", "1"); 73 | postData.Add("device_identifier", this.DeviceID); 74 | postData.Add("sms_phone_id", "1"); 75 | 76 | string response = SteamWeb.MobileLoginRequest(APIEndpoints.STEAMAPI_BASE + "/ITwoFactorService/AddAuthenticator/v0001", "POST", postData); 77 | if (response == null) return LinkResult.GeneralFailure; 78 | 79 | var addAuthenticatorResponse = JsonConvert.DeserializeObject(response); 80 | if (addAuthenticatorResponse == null || addAuthenticatorResponse.Response == null) 81 | { 82 | return LinkResult.GeneralFailure; 83 | } 84 | 85 | if (addAuthenticatorResponse.Response.Status == 29) 86 | { 87 | return LinkResult.AuthenticatorPresent; 88 | } 89 | 90 | if (addAuthenticatorResponse.Response.Status != 1) 91 | { 92 | return LinkResult.GeneralFailure; 93 | } 94 | 95 | this.LinkedAccount = addAuthenticatorResponse.Response; 96 | LinkedAccount.Session = this._session; 97 | LinkedAccount.DeviceID = this.DeviceID; 98 | 99 | return LinkResult.AwaitingFinalization; 100 | } 101 | 102 | public FinalizeResult FinalizeAddAuthenticator(string smsCode) 103 | { 104 | //The act of checking the SMS code is necessary for Steam to finalize adding the phone number to the account. 105 | //Of course, we only want to check it if we're adding a phone number in the first place... 106 | 107 | if (!String.IsNullOrEmpty(this.PhoneNumber) && !this._checkSMSCode(smsCode)) 108 | { 109 | return FinalizeResult.BadSMSCode; 110 | } 111 | 112 | var postData = new NameValueCollection(); 113 | postData.Add("steamid", _session.SteamID.ToString()); 114 | postData.Add("access_token", _session.OAuthToken); 115 | postData.Add("activation_code", smsCode); 116 | int tries = 0; 117 | while (tries <= 30) 118 | { 119 | postData.Set("authenticator_code", LinkedAccount.GenerateSteamGuardCode()); 120 | postData.Set("authenticator_time", TimeAligner.GetSteamTime().ToString()); 121 | 122 | string response = SteamWeb.MobileLoginRequest(APIEndpoints.STEAMAPI_BASE + "/ITwoFactorService/FinalizeAddAuthenticator/v0001", "POST", postData); 123 | if (response == null) return FinalizeResult.GeneralFailure; 124 | 125 | var finalizeResponse = JsonConvert.DeserializeObject(response); 126 | 127 | if (finalizeResponse == null || finalizeResponse.Response == null) 128 | { 129 | return FinalizeResult.GeneralFailure; 130 | } 131 | 132 | if (finalizeResponse.Response.Status == 89) 133 | { 134 | return FinalizeResult.BadSMSCode; 135 | } 136 | 137 | if (finalizeResponse.Response.Status == 88) 138 | { 139 | if (tries >= 30) 140 | { 141 | return FinalizeResult.UnableToGenerateCorrectCodes; 142 | } 143 | } 144 | 145 | if (!finalizeResponse.Response.Success) 146 | { 147 | return FinalizeResult.GeneralFailure; 148 | } 149 | 150 | if (finalizeResponse.Response.WantMore) 151 | { 152 | tries++; 153 | continue; 154 | } 155 | 156 | this.LinkedAccount.FullyEnrolled = true; 157 | return FinalizeResult.Success; 158 | } 159 | 160 | return FinalizeResult.GeneralFailure; 161 | } 162 | 163 | private bool _checkSMSCode(string smsCode) 164 | { 165 | var postData = new NameValueCollection(); 166 | postData.Add("op", "check_sms_code"); 167 | postData.Add("arg", smsCode); 168 | postData.Add("checkfortos", "0"); 169 | postData.Add("skipvoip", "1"); 170 | postData.Add("sessionid", _session.SessionID); 171 | 172 | string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "POST", postData, _cookies); 173 | if (response == null) return false; 174 | 175 | var addPhoneNumberResponse = JsonConvert.DeserializeObject(response); 176 | 177 | if (!addPhoneNumberResponse.Success) 178 | { 179 | Thread.Sleep(3500); //It seems that Steam needs a few seconds to finalize the phone number on the account. 180 | return _hasPhoneAttached(); 181 | } 182 | 183 | return true; 184 | } 185 | 186 | private bool _addPhoneNumber() 187 | { 188 | var postData = new NameValueCollection(); 189 | postData.Add("op", "add_phone_number"); 190 | postData.Add("arg", PhoneNumber); 191 | postData.Add("sessionid", _session.SessionID); 192 | 193 | string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "POST", postData, _cookies); 194 | if (response == null) return false; 195 | 196 | var addPhoneNumberResponse = JsonConvert.DeserializeObject(response); 197 | return addPhoneNumberResponse.Success; 198 | } 199 | 200 | private bool _checkEmailConfirmation() { 201 | var postData = new NameValueCollection(); 202 | postData.Add("op", "email_confirmation"); 203 | postData.Add("arg", ""); 204 | postData.Add("sessionid", _session.SessionID); 205 | 206 | string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "POST", postData, _cookies); 207 | if (response == null) return false; 208 | 209 | var emailConfirmationResponse = JsonConvert.DeserializeObject(response); 210 | return emailConfirmationResponse.Success; 211 | } 212 | 213 | private bool _hasPhoneAttached() { 214 | var postData = new NameValueCollection(); 215 | postData.Add("op", "has_phone"); 216 | postData.Add("arg", "null"); 217 | postData.Add("sessionid", _session.SessionID); 218 | 219 | string response = SteamWeb.Request(APIEndpoints.COMMUNITY_BASE + "/steamguard/phoneajax", "POST", postData, _cookies); 220 | if (response == null) return false; 221 | 222 | var hasPhoneResponse = JsonConvert.DeserializeObject(response); 223 | return hasPhoneResponse.HasPhone; 224 | } 225 | 226 | public enum LinkResult 227 | { 228 | MustProvidePhoneNumber, //No phone number on the account 229 | MustRemovePhoneNumber, //A phone number is already on the account 230 | MustConfirmEmail, //User need to click link from confirmation email 231 | AwaitingFinalization, //Must provide an SMS code 232 | GeneralFailure, //General failure (really now!) 233 | AuthenticatorPresent 234 | } 235 | 236 | public enum FinalizeResult 237 | { 238 | BadSMSCode, 239 | UnableToGenerateCorrectCodes, 240 | Success, 241 | GeneralFailure 242 | } 243 | 244 | private class AddAuthenticatorResponse 245 | { 246 | [JsonProperty("response")] 247 | public SteamGuardAccount Response { get; set; } 248 | } 249 | 250 | private class FinalizeAuthenticatorResponse 251 | { 252 | [JsonProperty("response")] 253 | public FinalizeAuthenticatorInternalResponse Response { get; set; } 254 | 255 | internal class FinalizeAuthenticatorInternalResponse 256 | { 257 | [JsonProperty("status")] 258 | public int Status { get; set; } 259 | 260 | [JsonProperty("server_time")] 261 | public long ServerTime { get; set; } 262 | 263 | [JsonProperty("want_more")] 264 | public bool WantMore { get; set; } 265 | 266 | [JsonProperty("success")] 267 | public bool Success { get; set; } 268 | } 269 | } 270 | 271 | private class HasPhoneResponse 272 | { 273 | [JsonProperty("has_phone")] 274 | public bool HasPhone { get; set; } 275 | } 276 | 277 | private class AddPhoneResponse 278 | { 279 | [JsonProperty("success")] 280 | public bool Success { get; set; } 281 | } 282 | 283 | public static string GenerateDeviceID() 284 | { 285 | return "android:" + Guid.NewGuid().ToString(); 286 | } 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/Confirmation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SteamAuth 8 | { 9 | public class Confirmation 10 | { 11 | /// 12 | /// The ID of this confirmation 13 | /// 14 | public ulong ID; 15 | 16 | /// 17 | /// The unique key used to act upon this confirmation. 18 | /// 19 | public ulong Key; 20 | 21 | /// 22 | /// The value of the data-type HTML attribute returned for this contribution. 23 | /// 24 | public int IntType; 25 | 26 | /// 27 | /// Represents either the Trade Offer ID or market transaction ID that caused this confirmation to be created. 28 | /// 29 | public ulong Creator; 30 | 31 | /// 32 | /// The type of this confirmation. 33 | /// 34 | public ConfirmationType ConfType; 35 | 36 | public Confirmation(ulong id, ulong key, int type, ulong creator) 37 | { 38 | this.ID = id; 39 | this.Key = key; 40 | this.IntType = type; 41 | this.Creator = creator; 42 | 43 | //Do a switch simply because we're not 100% certain of all the possible types. 44 | switch (type) 45 | { 46 | case 1: 47 | this.ConfType = ConfirmationType.GenericConfirmation; 48 | break; 49 | case 2: 50 | this.ConfType = ConfirmationType.Trade; 51 | break; 52 | case 3: 53 | this.ConfType = ConfirmationType.MarketSellTransaction; 54 | break; 55 | default: 56 | this.ConfType = ConfirmationType.Unknown; 57 | break; 58 | } 59 | } 60 | 61 | public enum ConfirmationType 62 | { 63 | GenericConfirmation, 64 | Trade, 65 | MarketSellTransaction, 66 | Unknown 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Setting ComVisible to false makes the types in this assembly not visible 6 | // to COM components. If you need to access a type in this assembly from 7 | // COM, set the ComVisible attribute to true on that type. 8 | [assembly: ComVisible(false)] 9 | 10 | // The following GUID is for the ID of the typelib if this project is exposed to COM 11 | [assembly: Guid("5ad0934e-f6c4-4ae5-83af-c788313b2a87")] 12 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/SessionData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace SteamAuth 5 | { 6 | public class SessionData 7 | { 8 | public string SessionID { get; set; } 9 | 10 | [Obsolete("Steam no longer uses this cookie. Use SteamLoginSecure only")] 11 | public string SteamLogin { get; set; } 12 | 13 | public string SteamLoginSecure { get; set; } 14 | 15 | public string WebCookie { get; set; } 16 | 17 | public string OAuthToken { get; set; } 18 | 19 | public ulong SteamID { get; set; } 20 | 21 | public void AddCookies(CookieContainer cookies) 22 | { 23 | cookies.Add(new Cookie("mobileClientVersion", "0 (2.1.3)", "/", ".steamcommunity.com")); 24 | cookies.Add(new Cookie("mobileClient", "android", "/", ".steamcommunity.com")); 25 | cookies.Add(new Cookie("steamid", SteamID.ToString(), "/", ".steamcommunity.com")); 26 | cookies.Add(new Cookie("steamLoginSecure", SteamLoginSecure, "/", ".steamcommunity.com") 27 | { 28 | HttpOnly = true, 29 | Secure = true 30 | }); 31 | cookies.Add(new Cookie("Steam_Language", "english", "/", ".steamcommunity.com")); 32 | cookies.Add(new Cookie("dob", "", "/", ".steamcommunity.com")); 33 | cookies.Add(new Cookie("sessionid", this.SessionID, "/", ".steamcommunity.com")); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/SteamAuth.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87} 4 | netstandard2.0 5 | SteamAuth 6 | SteamAuth 7 | Copyright © 2015 8 | bin\$(Configuration)\ 9 | 10 | 11 | full 12 | 13 | 14 | pdbonly 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/SteamAuth.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamAuth", "SteamAuth.csproj", "{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBed", "..\TestBed\TestBed.csproj", "{8A732227-C090-4011-9F0A-51180CFE6271}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {8A732227-C090-4011-9F0A-51180CFE6271}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {8A732227-C090-4011-9F0A-51180CFE6271}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {8A732227-C090-4011-9F0A-51180CFE6271}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {8A732227-C090-4011-9F0A-51180CFE6271}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/SteamWeb.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Specialized; 3 | using System.IO; 4 | using System.Net; 5 | using System.Threading.Tasks; 6 | 7 | namespace SteamAuth 8 | { 9 | public class SteamWeb 10 | { 11 | /// 12 | /// Perform a mobile login request 13 | /// 14 | /// API url 15 | /// GET or POST 16 | /// Name-data pairs 17 | /// current cookie container 18 | /// response body 19 | public static string MobileLoginRequest(string url, string method, NameValueCollection data = null, CookieContainer cookies = null, NameValueCollection headers = null) 20 | { 21 | return Request(url, method, data, cookies, headers, APIEndpoints.COMMUNITY_BASE + "/mobilelogin?oauth_client_id=DE45CD61&oauth_scope=read_profile%20write_profile%20read_client%20write_client"); 22 | } 23 | 24 | public static string Request(string url, string method, NameValueCollection data = null, CookieContainer cookies = null, NameValueCollection headers = null, string referer = APIEndpoints.COMMUNITY_BASE) 25 | { 26 | string query = (data == null ? string.Empty : string.Join("&", Array.ConvertAll(data.AllKeys, key => String.Format("{0}={1}", WebUtility.UrlEncode(key), WebUtility.UrlEncode(data[key]))))); 27 | if (method == "GET") 28 | { 29 | url += (url.Contains("?") ? "&" : "?") + query; 30 | } 31 | 32 | return Request(url, method, query, cookies, headers, referer); 33 | } 34 | 35 | public static string Request(string url, string method, string dataString = null, CookieContainer cookies = null, NameValueCollection headers = null, string referer = APIEndpoints.COMMUNITY_BASE) 36 | { 37 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 38 | request.Method = method; 39 | request.Accept = "text/javascript, text/html, application/xml, text/xml, */*"; 40 | request.UserAgent = "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"; 41 | request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; 42 | request.Referer = referer; 43 | 44 | if (headers != null) 45 | { 46 | request.Headers.Add(headers); 47 | } 48 | 49 | if (cookies != null) 50 | { 51 | request.CookieContainer = cookies; 52 | } 53 | 54 | if (method == "POST") 55 | { 56 | request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"; 57 | request.ContentLength = dataString.Length; 58 | 59 | StreamWriter requestStream = new StreamWriter(request.GetRequestStream()); 60 | requestStream.Write(dataString); 61 | requestStream.Close(); 62 | } 63 | 64 | try 65 | { 66 | using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 67 | { 68 | if (response.StatusCode != HttpStatusCode.OK) 69 | { 70 | HandleFailedWebRequestResponse(response, url); 71 | return null; 72 | } 73 | 74 | using (StreamReader responseStream = new StreamReader(response.GetResponseStream())) 75 | { 76 | string responseData = responseStream.ReadToEnd(); 77 | return responseData; 78 | } 79 | } 80 | } 81 | catch (WebException e) 82 | { 83 | HandleFailedWebRequestResponse(e.Response as HttpWebResponse, url); 84 | return null; 85 | } 86 | } 87 | 88 | public static async Task RequestAsync(string url, string method, NameValueCollection data = null, CookieContainer cookies = null, NameValueCollection headers = null, string referer = APIEndpoints.COMMUNITY_BASE) 89 | { 90 | string query = (data == null ? string.Empty : string.Join("&", Array.ConvertAll(data.AllKeys, key => String.Format("{0}={1}", WebUtility.UrlEncode(key), WebUtility.UrlEncode(data[key]))))); 91 | if (method == "GET") 92 | { 93 | url += (url.Contains("?") ? "&" : "?") + query; 94 | } 95 | 96 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 97 | request.Method = method; 98 | request.Accept = "text/javascript, text/html, application/xml, text/xml, */*"; 99 | request.UserAgent = "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"; 100 | request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; 101 | request.Referer = referer; 102 | 103 | if (headers != null) 104 | { 105 | request.Headers.Add(headers); 106 | } 107 | 108 | if (cookies != null) 109 | { 110 | request.CookieContainer = cookies; 111 | } 112 | 113 | if (method == "POST") 114 | { 115 | request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"; 116 | request.ContentLength = query.Length; 117 | 118 | StreamWriter requestStream = new StreamWriter(request.GetRequestStream()); 119 | await requestStream.WriteAsync(query); 120 | requestStream.Close(); 121 | } 122 | 123 | try 124 | { 125 | HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); 126 | 127 | if (response.StatusCode != HttpStatusCode.OK) 128 | { 129 | HandleFailedWebRequestResponse(response, url); 130 | return null; 131 | } 132 | 133 | using (StreamReader responseStream = new StreamReader(response.GetResponseStream())) 134 | { 135 | string responseData = await responseStream.ReadToEndAsync(); 136 | return responseData; 137 | } 138 | } 139 | catch (WebException e) 140 | { 141 | HandleFailedWebRequestResponse(e.Response as HttpWebResponse, url); 142 | return null; 143 | } 144 | } 145 | 146 | /// 147 | /// Raise exceptions relevant to this HttpWebResponse -- EG, to signal that our oauth token has expired. 148 | /// 149 | private static void HandleFailedWebRequestResponse(HttpWebResponse response, string requestURL) 150 | { 151 | if (response == null) return; 152 | 153 | //Redirecting -- likely to a steammobile:// URI 154 | if (response.StatusCode == HttpStatusCode.Found) 155 | { 156 | var location = response.Headers.Get("Location"); 157 | if (!string.IsNullOrEmpty(location)) 158 | { 159 | //Our OAuth token has expired. This is given both when we must refresh our session, or the entire OAuth Token cannot be refreshed anymore. 160 | //Thus, we should only throw this exception when we're attempting to refresh our session. 161 | if (location == "steammobile://lostauth" && requestURL == APIEndpoints.MOBILEAUTH_GETWGTOKEN) 162 | { 163 | throw new SteamGuardAccount.WGTokenExpiredException(); 164 | } 165 | } 166 | } 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/TimeAligner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using System.Net; 4 | using Newtonsoft.Json; 5 | 6 | namespace SteamAuth 7 | { 8 | /// 9 | /// Class to help align system time with the Steam server time. Not super advanced; probably not taking some things into account that it should. 10 | /// Necessary to generate up-to-date codes. In general, this will have an error of less than a second, assuming Steam is operational. 11 | /// 12 | public class TimeAligner 13 | { 14 | private static bool _aligned = false; 15 | private static int _timeDifference = 0; 16 | 17 | public static long GetSteamTime() 18 | { 19 | if (!TimeAligner._aligned) 20 | { 21 | TimeAligner.AlignTime(); 22 | } 23 | return Util.GetSystemUnixTime() + _timeDifference; 24 | } 25 | 26 | public static async Task GetSteamTimeAsync() 27 | { 28 | if (!TimeAligner._aligned) 29 | { 30 | await TimeAligner.AlignTimeAsync(); 31 | } 32 | return Util.GetSystemUnixTime() + _timeDifference; 33 | } 34 | 35 | public static void AlignTime() 36 | { 37 | long currentTime = Util.GetSystemUnixTime(); 38 | using (WebClient client = new WebClient()) 39 | { 40 | try 41 | { 42 | string response = client.UploadString(APIEndpoints.TWO_FACTOR_TIME_QUERY, "steamid=0"); 43 | TimeQuery query = JsonConvert.DeserializeObject(response); 44 | TimeAligner._timeDifference = (int)(query.Response.ServerTime - currentTime); 45 | TimeAligner._aligned = true; 46 | } 47 | catch (WebException) 48 | { 49 | return; 50 | } 51 | } 52 | } 53 | 54 | public static async Task AlignTimeAsync() 55 | { 56 | long currentTime = Util.GetSystemUnixTime(); 57 | WebClient client = new WebClient(); 58 | try 59 | { 60 | string response = await client.UploadStringTaskAsync(new Uri(APIEndpoints.TWO_FACTOR_TIME_QUERY), "steamid=0"); 61 | TimeQuery query = JsonConvert.DeserializeObject(response); 62 | TimeAligner._timeDifference = (int)(query.Response.ServerTime - currentTime); 63 | TimeAligner._aligned = true; 64 | } 65 | catch (WebException) 66 | { 67 | return; 68 | } 69 | } 70 | 71 | internal class TimeQuery 72 | { 73 | [JsonProperty("response")] 74 | internal TimeQueryResponse Response { get; set; } 75 | 76 | internal class TimeQueryResponse 77 | { 78 | [JsonProperty("server_time")] 79 | public long ServerTime { get; set; } 80 | } 81 | 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/UserLogin.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Specialized; 4 | using System.Net; 5 | using System.Security.Cryptography; 6 | using System.Text; 7 | using System.Threading; 8 | 9 | namespace SteamAuth 10 | { 11 | /// 12 | /// Handles logging the user into the mobile Steam website. Necessary to generate OAuth token and session cookies. 13 | /// 14 | public class UserLogin 15 | { 16 | public string Username; 17 | public string Password; 18 | public ulong SteamID; 19 | 20 | public bool RequiresCaptcha; 21 | public string CaptchaGID = null; 22 | public string CaptchaText = null; 23 | 24 | public bool RequiresEmail; 25 | public string EmailDomain = null; 26 | public string EmailCode = null; 27 | 28 | public bool Requires2FA; 29 | public string TwoFactorCode = null; 30 | 31 | public SessionData Session = null; 32 | public bool LoggedIn = false; 33 | 34 | private CookieContainer _cookies = new CookieContainer(); 35 | 36 | public UserLogin(string username, string password) 37 | { 38 | this.Username = username; 39 | this.Password = password; 40 | } 41 | 42 | public LoginResult DoLogin() 43 | { 44 | var postData = new NameValueCollection(); 45 | var cookies = _cookies; 46 | string response = null; 47 | 48 | if (cookies.Count == 0) 49 | { 50 | //Generate a SessionID 51 | cookies.Add(new Cookie("mobileClientVersion", "0 (2.1.3)", "/", ".steamcommunity.com")); 52 | cookies.Add(new Cookie("mobileClient", "android", "/", ".steamcommunity.com")); 53 | cookies.Add(new Cookie("Steam_Language", "english", "/", ".steamcommunity.com")); 54 | 55 | NameValueCollection headers = new NameValueCollection(); 56 | headers.Add("X-Requested-With", "com.valvesoftware.android.steam.community"); 57 | 58 | SteamWeb.MobileLoginRequest("https://steamcommunity.com/login?oauth_client_id=DE45CD61&oauth_scope=read_profile%20write_profile%20read_client%20write_client", "GET", null, cookies, headers); 59 | } 60 | 61 | postData.Add("donotcache", (TimeAligner.GetSteamTime() * 1000).ToString()); 62 | postData.Add("username", this.Username); 63 | response = SteamWeb.MobileLoginRequest(APIEndpoints.COMMUNITY_BASE + "/login/getrsakey", "POST", postData, cookies); 64 | if (response == null || response.Contains("\nAn error occurred while processing your request.")) return LoginResult.GeneralFailure; 65 | 66 | var rsaResponse = JsonConvert.DeserializeObject(response); 67 | 68 | if (!rsaResponse.Success) 69 | { 70 | return LoginResult.BadRSA; 71 | } 72 | 73 | Thread.Sleep(350); //Sleep for a bit to give Steam a chance to catch up?? 74 | 75 | RNGCryptoServiceProvider secureRandom = new RNGCryptoServiceProvider(); 76 | byte[] encryptedPasswordBytes; 77 | using (var rsaEncryptor = new RSACryptoServiceProvider()) 78 | { 79 | var passwordBytes = Encoding.ASCII.GetBytes(this.Password); 80 | var rsaParameters = rsaEncryptor.ExportParameters(false); 81 | rsaParameters.Exponent = Util.HexStringToByteArray(rsaResponse.Exponent); 82 | rsaParameters.Modulus = Util.HexStringToByteArray(rsaResponse.Modulus); 83 | rsaEncryptor.ImportParameters(rsaParameters); 84 | encryptedPasswordBytes = rsaEncryptor.Encrypt(passwordBytes, false); 85 | } 86 | 87 | string encryptedPassword = Convert.ToBase64String(encryptedPasswordBytes); 88 | 89 | postData.Clear(); 90 | postData.Add("donotcache", (TimeAligner.GetSteamTime() * 1000).ToString()); 91 | 92 | postData.Add("password", encryptedPassword); 93 | postData.Add("username", this.Username); 94 | postData.Add("twofactorcode", this.TwoFactorCode ?? ""); 95 | 96 | postData.Add("emailauth", this.RequiresEmail ? this.EmailCode : ""); 97 | postData.Add("loginfriendlyname", ""); 98 | postData.Add("captchagid", this.RequiresCaptcha ? this.CaptchaGID : "-1"); 99 | postData.Add("captcha_text", this.RequiresCaptcha ? this.CaptchaText : ""); 100 | postData.Add("emailsteamid", (this.Requires2FA || this.RequiresEmail) ? this.SteamID.ToString() : ""); 101 | 102 | postData.Add("rsatimestamp", rsaResponse.Timestamp); 103 | postData.Add("remember_login", "true"); 104 | postData.Add("oauth_client_id", "DE45CD61"); 105 | postData.Add("oauth_scope", "read_profile write_profile read_client write_client"); 106 | 107 | response = SteamWeb.MobileLoginRequest(APIEndpoints.COMMUNITY_BASE + "/login/dologin", "POST", postData, cookies); 108 | if (response == null) return LoginResult.GeneralFailure; 109 | 110 | var loginResponse = JsonConvert.DeserializeObject(response); 111 | 112 | if (loginResponse.Message != null) 113 | { 114 | if (loginResponse.Message.Contains("There have been too many login failures")) 115 | return LoginResult.TooManyFailedLogins; 116 | 117 | if (loginResponse.Message.Contains("Incorrect login")) 118 | return LoginResult.BadCredentials; 119 | } 120 | 121 | if (loginResponse.CaptchaNeeded) 122 | { 123 | this.RequiresCaptcha = true; 124 | this.CaptchaGID = loginResponse.CaptchaGID; 125 | return LoginResult.NeedCaptcha; 126 | } 127 | 128 | if (loginResponse.EmailAuthNeeded) 129 | { 130 | this.RequiresEmail = true; 131 | this.SteamID = loginResponse.EmailSteamID; 132 | return LoginResult.NeedEmail; 133 | } 134 | 135 | if (loginResponse.TwoFactorNeeded && !loginResponse.Success) 136 | { 137 | this.Requires2FA = true; 138 | return LoginResult.Need2FA; 139 | } 140 | 141 | if (!loginResponse.LoginComplete) 142 | { 143 | return LoginResult.BadCredentials; 144 | } 145 | else 146 | { 147 | var readableCookies = cookies.GetCookies(new Uri("https://steamcommunity.com")); 148 | var oAuthData = loginResponse.TransferParameters; 149 | 150 | SessionData session = new SessionData(); 151 | session.SteamID = oAuthData.SteamID; 152 | session.SteamLogin = session.SteamID + "%7C%7C" + oAuthData.SteamLoginSecure; 153 | session.SteamLoginSecure = session.SteamID + "%7C%7C" + oAuthData.SteamLoginSecure; 154 | session.WebCookie = oAuthData.Webcookie; 155 | session.SessionID = readableCookies["sessionid"].Value; 156 | this.Session = session; 157 | this.LoggedIn = true; 158 | return LoginResult.LoginOkay; 159 | } 160 | } 161 | 162 | private class LoginResponse 163 | { 164 | [JsonProperty("success")] 165 | public bool Success { get; set; } 166 | 167 | [JsonProperty("login_complete")] 168 | public bool LoginComplete { get; set; } 169 | 170 | [JsonProperty("transfer_parameters")] 171 | public TransferParameters TransferParameters { get; set; } 172 | 173 | [JsonProperty("captcha_needed")] 174 | public bool CaptchaNeeded { get; set; } 175 | 176 | [JsonProperty("captcha_gid")] 177 | public string CaptchaGID { get; set; } 178 | 179 | [JsonProperty("emailsteamid")] 180 | public ulong EmailSteamID { get; set; } 181 | 182 | [JsonProperty("emailauth_needed")] 183 | public bool EmailAuthNeeded { get; set; } 184 | 185 | [JsonProperty("requires_twofactor")] 186 | public bool TwoFactorNeeded { get; set; } 187 | 188 | [JsonProperty("message")] 189 | public string Message { get; set; } 190 | } 191 | 192 | internal class TransferParameters 193 | { 194 | [JsonProperty("auth")] 195 | public string Auth { get; set; } 196 | 197 | [JsonProperty("remember_login")] 198 | public bool RememberLogin { get; set; } 199 | 200 | [JsonProperty("steamid")] 201 | public ulong SteamID { get; set; } 202 | 203 | [JsonProperty("token_secure")] 204 | public string SteamLoginSecure { get; set; } 205 | 206 | [JsonProperty("webcookie")] 207 | public string Webcookie { get; set; } 208 | } 209 | 210 | private class RSAResponse 211 | { 212 | [JsonProperty("success")] 213 | public bool Success { get; set; } 214 | 215 | [JsonProperty("publickey_exp")] 216 | public string Exponent { get; set; } 217 | 218 | [JsonProperty("publickey_mod")] 219 | public string Modulus { get; set; } 220 | 221 | [JsonProperty("timestamp")] 222 | public string Timestamp { get; set; } 223 | 224 | [JsonProperty("steamid")] 225 | public ulong SteamID { get; set; } 226 | } 227 | } 228 | 229 | public enum LoginResult 230 | { 231 | LoginOkay, 232 | GeneralFailure, 233 | BadRSA, 234 | BadCredentials, 235 | NeedCaptcha, 236 | Need2FA, 237 | NeedEmail, 238 | TooManyFailedLogins, 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/Util.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace SteamAuth 5 | { 6 | public class Util 7 | { 8 | public static long GetSystemUnixTime() 9 | { 10 | return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; 11 | } 12 | 13 | public static byte[] HexStringToByteArray(string hex) 14 | { 15 | int hexLen = hex.Length; 16 | byte[] ret = new byte[hexLen / 2]; 17 | for (int i = 0; i < hexLen; i += 2) 18 | { 19 | ret[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); 20 | } 21 | return ret; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/bin/Debug/netstandard2.0/SteamAuth.deps.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeTarget": { 3 | "name": ".NETStandard,Version=v2.0/", 4 | "signature": "" 5 | }, 6 | "compilationOptions": {}, 7 | "targets": { 8 | ".NETStandard,Version=v2.0": {}, 9 | ".NETStandard,Version=v2.0/": { 10 | "SteamAuth/1.0.0": { 11 | "dependencies": { 12 | "NETStandard.Library": "2.0.3", 13 | "Newtonsoft.Json": "13.0.3" 14 | }, 15 | "runtime": { 16 | "SteamAuth.dll": {} 17 | } 18 | }, 19 | "Microsoft.NETCore.Platforms/1.1.0": {}, 20 | "NETStandard.Library/2.0.3": { 21 | "dependencies": { 22 | "Microsoft.NETCore.Platforms": "1.1.0" 23 | } 24 | }, 25 | "Newtonsoft.Json/13.0.3": { 26 | "runtime": { 27 | "lib/netstandard2.0/Newtonsoft.Json.dll": { 28 | "assemblyVersion": "13.0.0.0", 29 | "fileVersion": "13.0.3.27908" 30 | } 31 | } 32 | } 33 | } 34 | }, 35 | "libraries": { 36 | "SteamAuth/1.0.0": { 37 | "type": "project", 38 | "serviceable": false, 39 | "sha512": "" 40 | }, 41 | "Microsoft.NETCore.Platforms/1.1.0": { 42 | "type": "package", 43 | "serviceable": true, 44 | "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", 45 | "path": "microsoft.netcore.platforms/1.1.0", 46 | "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" 47 | }, 48 | "NETStandard.Library/2.0.3": { 49 | "type": "package", 50 | "serviceable": true, 51 | "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", 52 | "path": "netstandard.library/2.0.3", 53 | "hashPath": "netstandard.library.2.0.3.nupkg.sha512" 54 | }, 55 | "Newtonsoft.Json/13.0.3": { 56 | "type": "package", 57 | "serviceable": true, 58 | "sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", 59 | "path": "newtonsoft.json/13.0.3", 60 | "hashPath": "newtonsoft.json.13.0.3.nupkg.sha512" 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/bin/Debug/netstandard2.0/SteamAuth.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/therepower/SteamDesktopAuthenticator-Temporary-Fix/5f2c7a25343e810508803ed0a032e099fc084f6c/lib/SteamAuth/SteamAuth/bin/Debug/netstandard2.0/SteamAuth.dll -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/bin/Debug/netstandard2.0/SteamAuth.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/therepower/SteamDesktopAuthenticator-Temporary-Fix/5f2c7a25343e810508803ed0a032e099fc084f6c/lib/SteamAuth/SteamAuth/bin/Debug/netstandard2.0/SteamAuth.pdb -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Bu kod araç tarafından oluşturuldu. 4 | // Çalışma Zamanı Sürümü:4.0.30319.42000 5 | // 6 | // Bu dosyada yapılacak değişiklikler yanlış davranışa neden olabilir ve 7 | // kod yeniden oluşturulursa kaybolur. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("SteamAuth")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyCopyrightAttribute("Copyright © 2015")] 17 | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] 18 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] 19 | [assembly: System.Reflection.AssemblyProductAttribute("SteamAuth")] 20 | [assembly: System.Reflection.AssemblyTitleAttribute("SteamAuth")] 21 | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] 22 | 23 | // MSBuild WriteCodeFragment sınıfı tarafından oluşturuldu. 24 | 25 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | f06bff79f2d7118e80595e4daa1797bcd4872c62 2 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.RootNamespace = SteamAuth 3 | build_property.ProjectDir = C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\ 4 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.assets.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/therepower/SteamDesktopAuthenticator-Temporary-Fix/5f2c7a25343e810508803ed0a032e099fc084f6c/lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.assets.cache -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.csproj.AssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/therepower/SteamDesktopAuthenticator-Temporary-Fix/5f2c7a25343e810508803ed0a032e099fc084f6c/lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.csproj.AssemblyReference.cache -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 538028333bdfa6f2cc2504091240ef8cdcfa6acc 2 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\bin\Debug\netstandard2.0\SteamAuth.deps.json 2 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\bin\Debug\netstandard2.0\SteamAuth.dll 3 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\bin\Debug\netstandard2.0\SteamAuth.pdb 4 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\obj\Debug\netstandard2.0\SteamAuth.csproj.AssemblyReference.cache 5 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\obj\Debug\netstandard2.0\SteamAuth.GeneratedMSBuildEditorConfig.editorconfig 6 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\obj\Debug\netstandard2.0\SteamAuth.AssemblyInfoInputs.cache 7 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\obj\Debug\netstandard2.0\SteamAuth.AssemblyInfo.cs 8 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\obj\Debug\netstandard2.0\SteamAuth.csproj.CoreCompileInputs.cache 9 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\obj\Debug\netstandard2.0\SteamAuth.dll 10 | C:\Users\test\Downloads\SteamDesktopAuthenticator-master\SteamDesktopAuthenticator-master\lib\SteamAuth\SteamAuth\obj\Debug\netstandard2.0\SteamAuth.pdb 11 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/therepower/SteamDesktopAuthenticator-Temporary-Fix/5f2c7a25343e810508803ed0a032e099fc084f6c/lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.dll -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/therepower/SteamDesktopAuthenticator-Temporary-Fix/5f2c7a25343e810508803ed0a032e099fc084f6c/lib/SteamAuth/SteamAuth/obj/Debug/netstandard2.0/SteamAuth.pdb -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/SteamAuth.csproj.nuget.dgspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 1, 3 | "restore": { 4 | "C:\\Users\\test\\Downloads\\SteamDesktopAuthenticator-master\\SteamDesktopAuthenticator-master\\lib\\SteamAuth\\SteamAuth\\SteamAuth.csproj": {} 5 | }, 6 | "projects": { 7 | "C:\\Users\\test\\Downloads\\SteamDesktopAuthenticator-master\\SteamDesktopAuthenticator-master\\lib\\SteamAuth\\SteamAuth\\SteamAuth.csproj": { 8 | "version": "1.0.0", 9 | "restore": { 10 | "projectUniqueName": "C:\\Users\\test\\Downloads\\SteamDesktopAuthenticator-master\\SteamDesktopAuthenticator-master\\lib\\SteamAuth\\SteamAuth\\SteamAuth.csproj", 11 | "projectName": "SteamAuth", 12 | "projectPath": "C:\\Users\\test\\Downloads\\SteamDesktopAuthenticator-master\\SteamDesktopAuthenticator-master\\lib\\SteamAuth\\SteamAuth\\SteamAuth.csproj", 13 | "packagesPath": "C:\\Users\\test\\.nuget\\packages\\", 14 | "outputPath": "C:\\Users\\test\\Downloads\\SteamDesktopAuthenticator-master\\SteamDesktopAuthenticator-master\\lib\\SteamAuth\\SteamAuth\\obj\\", 15 | "projectStyle": "PackageReference", 16 | "fallbackFolders": [ 17 | "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" 18 | ], 19 | "configFilePaths": [ 20 | "C:\\Users\\test\\AppData\\Roaming\\NuGet\\NuGet.Config", 21 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", 22 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 23 | ], 24 | "originalTargetFrameworks": [ 25 | "netstandard2.0" 26 | ], 27 | "sources": { 28 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 29 | "https://api.nuget.org/v3/index.json": {} 30 | }, 31 | "frameworks": { 32 | "netstandard2.0": { 33 | "targetAlias": "netstandard2.0", 34 | "projectReferences": {} 35 | } 36 | }, 37 | "warningProperties": { 38 | "warnAsError": [ 39 | "NU1605" 40 | ] 41 | } 42 | }, 43 | "frameworks": { 44 | "netstandard2.0": { 45 | "targetAlias": "netstandard2.0", 46 | "dependencies": { 47 | "NETStandard.Library": { 48 | "suppressParent": "All", 49 | "target": "Package", 50 | "version": "[2.0.3, )", 51 | "autoReferenced": true 52 | }, 53 | "Newtonsoft.Json": { 54 | "target": "Package", 55 | "version": "[13.0.3, )" 56 | } 57 | }, 58 | "imports": [ 59 | "net461", 60 | "net462", 61 | "net47", 62 | "net471", 63 | "net472", 64 | "net48", 65 | "net481" 66 | ], 67 | "assetTargetFallback": true, 68 | "warn": true, 69 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.100\\RuntimeIdentifierGraph.json" 70 | } 71 | } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/SteamAuth.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | NuGet 6 | $(MSBuildThisFileDirectory)project.assets.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\test\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages 9 | PackageReference 10 | 6.5.0 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/SteamAuth.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /lib/SteamAuth/SteamAuth/obj/project.nuget.cache: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "dgSpecHash": "uc0U/aIapL5fN5d5ms+ROSzKmL4NA+IRxT+ASeMBE/EmrLhkoSti+W1pBq3n9fnJnXgM3Wj7YM1D/KNU5otxPQ==", 4 | "success": true, 5 | "projectFilePath": "C:\\Users\\test\\Downloads\\SteamDesktopAuthenticator-master\\SteamDesktopAuthenticator-master\\lib\\SteamAuth\\SteamAuth\\SteamAuth.csproj", 6 | "expectedPackageFiles": [ 7 | "C:\\Users\\test\\.nuget\\packages\\microsoft.netcore.platforms\\1.1.0\\microsoft.netcore.platforms.1.1.0.nupkg.sha512", 8 | "C:\\Users\\test\\.nuget\\packages\\netstandard.library\\2.0.3\\netstandard.library.2.0.3.nupkg.sha512", 9 | "C:\\Users\\test\\.nuget\\packages\\newtonsoft.json\\13.0.3\\newtonsoft.json.13.0.3.nupkg.sha512" 10 | ], 11 | "logs": [] 12 | } -------------------------------------------------------------------------------- /lib/SteamAuth/TestBed/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /lib/SteamAuth/TestBed/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SteamAuth; 3 | using Newtonsoft.Json; 4 | using System.IO; 5 | 6 | namespace TestBed 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | //This basic loop will log into user accounts you specify, enable the mobile authenticator, and save a maFile (mobile authenticator file) 13 | while (true) 14 | { 15 | Console.WriteLine("Enter user/password: "); 16 | string username = Console.ReadLine(); 17 | string password = Console.ReadLine(); 18 | UserLogin login = new UserLogin(username, password); 19 | LoginResult response = LoginResult.BadCredentials; 20 | while ((response = login.DoLogin()) != LoginResult.LoginOkay) 21 | { 22 | switch (response) 23 | { 24 | case LoginResult.NeedEmail: 25 | Console.WriteLine("Please enter your email code: "); 26 | string code = Console.ReadLine(); 27 | login.EmailCode = code; 28 | break; 29 | 30 | case LoginResult.NeedCaptcha: 31 | System.Diagnostics.Process.Start(APIEndpoints.COMMUNITY_BASE + "/public/captcha.php?gid=" + login.CaptchaGID); //Open a web browser to the captcha image 32 | Console.WriteLine("Please enter captcha text: "); 33 | string captchaText = Console.ReadLine(); 34 | login.CaptchaText = captchaText; 35 | break; 36 | 37 | case LoginResult.Need2FA: 38 | Console.WriteLine("Please enter your mobile authenticator code: "); 39 | code = Console.ReadLine(); 40 | login.TwoFactorCode = code; 41 | break; 42 | } 43 | } 44 | 45 | AuthenticatorLinker linker = new AuthenticatorLinker(login.Session); 46 | linker.PhoneNumber = null; //Set this to non-null to add a new phone number to the account. 47 | var result = linker.AddAuthenticator(); 48 | 49 | if (result != AuthenticatorLinker.LinkResult.AwaitingFinalization) 50 | { 51 | Console.WriteLine("Failed to add authenticator: " + result); 52 | continue; 53 | } 54 | 55 | try 56 | { 57 | string sgFile = JsonConvert.SerializeObject(linker.LinkedAccount, Formatting.Indented); 58 | string fileName = linker.LinkedAccount.AccountName + ".maFile"; 59 | File.WriteAllText(fileName, sgFile); 60 | } 61 | catch (Exception e) 62 | { 63 | Console.WriteLine(e); 64 | Console.WriteLine("EXCEPTION saving maFile. For security, authenticator will not be finalized."); 65 | continue; 66 | } 67 | 68 | Console.WriteLine("Please enter SMS code: "); 69 | string smsCode = Console.ReadLine(); 70 | var linkResult = linker.FinalizeAddAuthenticator(smsCode); 71 | 72 | if (linkResult != AuthenticatorLinker.FinalizeResult.Success) 73 | { 74 | Console.WriteLine("Unable to finalize authenticator: " + linkResult); 75 | } 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/SteamAuth/TestBed/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TestBed")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TestBed")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8a732227-c090-4011-9f0a-51180cfe6271")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /lib/SteamAuth/TestBed/TestBed.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8A732227-C090-4011-9F0A-51180CFE6271} 8 | Exe 9 | Properties 10 | TestBed 11 | TestBed 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\SteamAuth\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {5ad0934e-f6c4-4ae5-83af-c788313b2a87} 59 | SteamAuth 60 | 61 | 62 | 63 | 70 | -------------------------------------------------------------------------------- /lib/SteamAuth/TestBed/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /prepare-release.bat: -------------------------------------------------------------------------------- 1 | REM Remove un-needed CEF files 2 | del /q "Steam Desktop Authenticator\bin\Release\devtools_resources.pak" 3 | del /q "Steam Desktop Authenticator\bin\Release\cef_extensions.pak" 4 | del /q "Steam Desktop Authenticator\bin\Release\pdf.dll" 5 | del /q "Steam Desktop Authenticator\bin\Release\ffmpegsumo.dll" 6 | del /q "Steam Desktop Authenticator\bin\Release\d3dcompiler_43.dll" 7 | del /q "Steam Desktop Authenticator\bin\Release\widevinecdmadapter.dll" 8 | 9 | REM Remove CEF directories 10 | RD /S /Q "Steam Desktop Authenticator\bin\Release\locales\" 11 | RD /S /Q "Steam Desktop Authenticator\bin\Release\swiftshader\" 12 | 13 | REM Remove CEF debug files 14 | del /q "Steam Desktop Authenticator\bin\Release\CefSharp.BrowserSubprocess.Core.pdb" 15 | del /q "Steam Desktop Authenticator\bin\Release\CefSharp.BrowserSubprocess.pdb" 16 | del /q "Steam Desktop Authenticator\bin\Release\CefSharp.Core.pdb" 17 | del /q "Steam Desktop Authenticator\bin\Release\CefSharp.pdb" 18 | del /q "Steam Desktop Authenticator\bin\Release\CefSharp.WinForms.pdb" 19 | 20 | REM Remove XML files 21 | del /q "Steam Desktop Authenticator\bin\Release\Newtonsoft.Json.xml" 22 | del /q "Steam Desktop Authenticator\bin\Release\CefSharp.xml" 23 | del /q "Steam Desktop Authenticator\bin\Release\CefSharp.WinForms.xml" 24 | del /q "Steam Desktop Authenticator\bin\Release\CefSharp.Core.xml" 25 | del /q "Steam Desktop Authenticator\bin\Release\CommandLine.xml" 26 | 27 | REM Remove ClickOnce app 28 | del /q "Steam Desktop Authenticator\bin\Release\Steam Desktop Authenticator.application" 29 | RD /S /Q "Steam Desktop Authenticator\bin\Release\app.publish\" --------------------------------------------------------------------------------