-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
107 lines (84 loc) · 3 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System.Text.Json.Nodes;
using SteamGuardTotp = SteamGuard.TOTP.SteamGuard;
using SteamAuth.Utils;
using System.Security.Cryptography;
using TextCopy;
using Ookii.CommandLine;
using Ookii.CommandLine.Terminal;
namespace SteamAuth;
internal static class Program
{
private const string SteamGuardFile = "steamauth.json";
private static readonly SteamGuardTotp SteamGuard = new();
private static readonly string SteamGuardPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, SteamGuardFile);
private static readonly ConsoleWriter Console = new();
private static int Main()
{
var args = CommandLineParser.Parse<Arguments>() ?? new(isInvalid: true);
if (args.IsInvalid)
{
return (int)Status.InvalidArguments;
}
var result = string.IsNullOrWhiteSpace(args.Secret) ? ProcessFile() : ProcessArgs(args);
if (result != Status.Success)
{
Console.WriteLine(result.GetMessage(), TextFormat.ForegroundRed, TextFormat.BoldBright);
}
return (int)result;
}
private static Status ProcessArgs(Arguments args)
{
var secret = args.Secret ?? string.Empty;
var code = SteamGuard.GenerateAuthenticationCode(secret);
if (code is null)
{
return Status.TotpGenerationFailure;
}
OutputTotpCode(code);
return args.Save ? SaveSecret(secret) : Status.Success;
}
private static Status ProcessFile()
{
if (!File.Exists(SteamGuardPath))
{
return Status.ConfigFileNotFound;
}
var json = JsonNode.Parse(File.ReadAllText(SteamGuardPath));
if (json is null or not JsonObject)
{
return Status.ConfigFileNotFound;
}
var entropy = json["entropy"]!.GetValue<string>();
var encryptedSecret = json["encryptedSecret"]!.GetValue<string>();
var secret = encryptedSecret.FromBase64().Unprotect(entropy.FromBase64())?.ToStringUtf();
if (secret is null)
{
return Status.DecryptionFailure;
}
var code = SteamGuard.GenerateAuthenticationCode(secret);
if (code is null) return Status.TotpGenerationFailure;
OutputTotpCode(code);
return Status.Success;
}
private static Status SaveSecret(string secret)
{
var entropy = new byte[20];
RandomNumberGenerator.Fill(entropy);
var json = new JsonObject
{
["encryptedSecret"] = secret.ToBytes().Protect(entropy)?.ToBase64(),
["entropy"] = entropy.ToBase64()
};
if (json["encryptedSecret"] is null || json["entropy"] is null)
{
return Status.EncryptionFailure;
}
File.WriteAllText(SteamGuardPath, json.ToString());
return Status.Success;
}
private static void OutputTotpCode(string code)
{
Console.WriteLine(code, TextFormat.ForegroundGreen, TextFormat.BoldBright);
ClipboardService.SetText(code);
}
}