Skip to content

Commit 9f075cc

Browse files
fix(installer): strip internal whitespace from pasted enrollment JWT
1 parent dcff01c commit 9f075cc

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

package/AgentWindowsManaged/Dialogs/AgentTunnelDialog.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,31 @@ public override bool ToProperties()
2525
// is now the single source of truth for the agent-facing URL. Overriding it
2626
// server-side would defeat the whole point of validating that the agent reached
2727
// the gateway through one of `AgentTunnel.AdvertisedNames`.
28-
Runtime.Session[AgentProperties.AgentTunnelEnrollmentString] = enrollmentString.Text.Trim();
28+
//
29+
// Important: the enrollment string is persisted with ALL internal whitespace
30+
// removed — not just edge `.Trim()`. The validation in `DoValidate` already
31+
// works on the whitespace-stripped form (browsers and password managers
32+
// routinely wrap long JWTs across lines on paste), so the value handed off
33+
// to `agent.exe up --enrollment-string` must match what was validated.
34+
// Otherwise a multiline pasted JWT passes validation here and then fails at
35+
// enrollment with an opaque error from the agent's JWT parser.
36+
Runtime.Session[AgentProperties.AgentTunnelEnrollmentString] = StripAllWhitespace(enrollmentString.Text);
2937
Runtime.Session[AgentProperties.AgentTunnelAgentName] = agentName.Text.Trim();
3038
Runtime.Session[AgentProperties.AgentTunnelAdvertiseSubnets] = advertiseSubnets.Text.Trim();
3139
Runtime.Session[AgentProperties.AgentTunnelAdvertiseDomains] = advertiseDomains.Text.Trim();
3240

3341
return true;
3442
}
3543

44+
/// <summary>
45+
/// Strip every whitespace character from <paramref name="value"/>. Used to
46+
/// canonicalize pasted JWTs (which often arrive wrapped onto multiple lines)
47+
/// so that validation and the value persisted into the MSI session refer to
48+
/// the exact same string.
49+
/// </summary>
50+
private static string StripAllWhitespace(string value) =>
51+
value is null ? string.Empty : Regex.Replace(value, @"\s+", "");
52+
3653
public override void OnLoad(object sender, EventArgs e)
3754
{
3855
banner.Image = Runtime.Session.GetResourceBitmap("WixUI_Bmp_Banner");
@@ -58,7 +75,10 @@ public override bool DoValidate()
5875
// JWT shape: three base64url segments separated by dots. The agent's `up --enrollment-string`
5976
// parses the JWT claims for jet_gw_url / jet_agent_name, so the dialog only sanity-checks
6077
// shape and base64url decodability here; signature verification happens at the gateway.
61-
string text = Regex.Replace(enrollmentString.Text, @"\s+", "");
78+
//
79+
// Use the same whitespace-stripping helper as `ToProperties` so validation and
80+
// persistence operate on byte-identical input.
81+
string text = StripAllWhitespace(enrollmentString.Text);
6282
string[] parts = text.Split('.');
6383
if (parts.Length != 3 || parts.Any(string.IsNullOrEmpty))
6484
{

0 commit comments

Comments
 (0)