Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SteamAuthentication to handle new Steam login flow sessions #1129

Merged
merged 29 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0084f8e
Create SteamAuthentication
xPaw Aug 29, 2022
3c8472d
Add some polling support
xPaw Aug 29, 2022
cf5635a
Add AccessToken to LogOnDetails
xPaw Aug 29, 2022
a127e68
Return tokens when poll returns data
xPaw Aug 29, 2022
b617056
Put send/poll methods on the session object
xPaw Aug 30, 2022
d373630
Add authenticator object and implement 2FA auth
xPaw Aug 30, 2022
a8add89
Sort by preferred auth confirmation
xPaw Aug 30, 2022
7603aa8
Add AuthenticationException
xPaw Aug 31, 2022
6322eb3
Add guard_data; add some comments
xPaw Mar 3, 2023
8c7b10f
Add authentication sample
xPaw Mar 11, 2023
f92bac3
Change enum to IsPersistentSession bool
xPaw Mar 12, 2023
b7d393f
Add cancellation token to polling
xPaw Mar 13, 2023
ec96a73
Make `AuthenticationException` public
JustArchi Mar 15, 2023
3687218
Allow consumers to decide whether they want to poll for device confir…
xPaw Mar 15, 2023
5767a15
Add a sample for authenticating using qr codes
xPaw Mar 15, 2023
1c2cc7a
Add more comments
xPaw Mar 15, 2023
8d10d5a
Cleanup, add qr challenge url change callback, add os type
xPaw Mar 17, 2023
43b634a
Use default WebsiteID in sample
xPaw Mar 17, 2023
f8ec8a9
Add a sample parsing jwt payload
xPaw Mar 17, 2023
44cf6b4
Deprecate login keys
xPaw Mar 17, 2023
b006cd2
Document more website ids
xPaw Mar 17, 2023
2fc013e
Handle incorrect 2FA codes and call the authenticator again
xPaw Mar 17, 2023
20c0b84
Update guard data comment
xPaw Mar 22, 2023
7b266f3
Review
xPaw Mar 22, 2023
2cb4a75
Move authentication stuff to its own namespace
xPaw Mar 22, 2023
2496b06
Suppress LoginKey obsolete warnings in SK codebase
xPaw Mar 22, 2023
9aa61d0
Review
xPaw Mar 23, 2023
79931d7
Change visibility
xPaw Mar 23, 2023
1d41f5f
Added `SteamClient.Authentication`
xPaw Mar 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Create SteamAuthentication
  • Loading branch information
xPaw committed Mar 3, 2023
commit 0084f8e2e21952627ab12be16d3659378b287220
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* This file is subject to the terms and conditions defined in
* file 'license.txt', which is part of this source code package.
*/

using System;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using SteamKit2.Internal;

namespace SteamKit2
{
/// <summary>
/// This handler is used for authenticating on Steam.
/// </summary>
public sealed class SteamAuthentication : ClientMsgHandler
{
/// <summary>
/// Represents the details required to authenticate on Steam.
/// </summary>
public sealed class AuthSessionDetails
{
/// <summary>
/// Gets or sets the username.
/// </summary>
/// <value>The username.</value>
public string? Username { get; set; }

/// <summary>
/// Gets or sets the password.
/// </summary>
/// <value>The password.</value>
public string? Password { get; set; }

/// <summary>
/// Gets or sets the device name (or user agent).
/// </summary>
/// <value>The device name.</value>
public string? DeviceFriendlyName { get; set; }

/// <summary>
/// Gets or sets the platform type that the login will be performed for.
/// </summary>
public EAuthTokenPlatformType PlatformType { get; set; } = EAuthTokenPlatformType.k_EAuthTokenPlatformType_SteamClient;

/// <summary>
/// Gets or sets the session persistence.
/// </summary>
/// <value>The persistence.</value>
public ESessionPersistence Persistence { get; set; } = ESessionPersistence.k_ESessionPersistence_Persistent;

/// <summary>
/// Gets or sets the website id that the login will be performed for. (EMachineAuthWebDomain)
xPaw marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <value>The website id.</value>
public string? WebsiteID { get; set; }
}

/// <summary>
/// Gets public key for the provided account name which can be used to encrypt the account password.
/// </summary>
/// <param name="accountName">The account name to get RSA public key for.</param>
public async Task<CAuthentication_GetPasswordRSAPublicKey_Response> GetPasswordRSAPublicKey( string accountName )
{
var request = new CAuthentication_GetPasswordRSAPublicKey_Request
{
account_name = accountName
};

var unifiedMessages = Client.GetHandler<SteamUnifiedMessages>()!;
var contentService = unifiedMessages.CreateService<IAuthentication>();
var message = await contentService.SendMessage( api => api.GetPasswordRSAPublicKey( request ) );
var response = message.GetDeserializedResponse<CAuthentication_GetPasswordRSAPublicKey_Response>();

return response;
}

/// <summary>
///
/// </summary>
/// <param name="details">The details to use for logging on.</param>
public async Task BeginAuthSessionViaQR( AuthSessionDetails details )
{
var request = new CAuthentication_BeginAuthSessionViaQR_Request
{
platform_type = details.PlatformType,
device_friendly_name = details.DeviceFriendlyName,
};

var unifiedMessages = Client.GetHandler<SteamUnifiedMessages>()!;
var contentService = unifiedMessages.CreateService<IAuthentication>();
var message = await contentService.SendMessage( api => api.BeginAuthSessionViaQR( request ) );
var response = message.GetDeserializedResponse<CAuthentication_BeginAuthSessionViaQR_Response>();
}

/// <summary>
///
/// </summary>
/// <param name="details">The details to use for logging on.</param>
/// <exception cref="ArgumentNullException">No auth details were provided.</exception>
/// <exception cref="ArgumentException">Username or password are not set within <paramref name="details"/>.</exception>
public async Task BeginAuthSessionViaCredentials( AuthSessionDetails details )
{
if ( details == null )
{
throw new ArgumentNullException( nameof( details ) );
}

if ( string.IsNullOrEmpty( details.Username ) || string.IsNullOrEmpty( details.Password ) )
{
throw new ArgumentException( "BeginAuthSessionViaCredentials requires a username and password to be set in 'details'." );
}

// Encrypt the password
var publicKey = await GetPasswordRSAPublicKey( details.Username! );
var rsaParameters = new RSAParameters
{
Modulus = Utils.DecodeHexString( publicKey.publickey_mod ),
Exponent = Utils.DecodeHexString( publicKey.publickey_exp ),
};

using var rsa = RSA.Create();
rsa.ImportParameters( rsaParameters );
var encryptedPassword = rsa.Encrypt( Encoding.UTF8.GetBytes( details.Password ), RSAEncryptionPadding.Pkcs1 );
xPaw marked this conversation as resolved.
Show resolved Hide resolved

// Create request
var request = new CAuthentication_BeginAuthSessionViaCredentials_Request
{
platform_type = details.PlatformType,
device_friendly_name = details.DeviceFriendlyName,
account_name = details.Username,
persistence = details.Persistence,
website_id = details.WebsiteID,
encrypted_password = Convert.ToBase64String( encryptedPassword ),
encryption_timestamp = publicKey.timestamp,
};

var unifiedMessages = Client.GetHandler<SteamUnifiedMessages>()!;
var contentService = unifiedMessages.CreateService<IAuthentication>();
var message = await contentService.SendMessage( api => api.BeginAuthSessionViaCredentials( request ) );
var response = message.GetDeserializedResponse<CAuthentication_BeginAuthSessionViaCredentials_Response>();

var t = 1;
}

/// <summary>
/// Handles a client message. This should not be called directly.
/// </summary>
/// <param name="packetMsg">The packet message that contains the data.</param>
public override void HandleMsg( IPacketMsg packetMsg )
{
// not used
xPaw marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
1 change: 1 addition & 0 deletions SteamKit2/SteamKit2/Steam/SteamClient/SteamClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public SteamClient( SteamConfiguration configuration, string identifier )
// notice: SteamFriends should be added before SteamUser due to AccountInfoCallback
this.AddHandler( new SteamFriends() );
this.AddHandler( new SteamUser() );
this.AddHandler( new SteamAuthentication() );
this.AddHandler( new SteamApps() );
this.AddHandler( new SteamGameCoordinator() );
this.AddHandler( new SteamGameServer() );
Expand Down