Skip to content

Commit b01b310

Browse files
author
Miriam McMahon
authored
Merge pull request #57 from MiriamMcMahon/spaceIssue
Issue #56: allow for spaces in the user account name when parsing the URL
2 parents 670a9da + a4f3c32 commit b01b310

6 files changed

Lines changed: 132 additions & 110 deletions

File tree

scripts/Win/scalus.json

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,12 @@
6868
"ParserId": "ssh",
6969
"Options": []
7070
},
71-
"Exec": "C:\\windows\\system32\\cmd.exe",
72-
"Args": [ "/c", "C:\\Windows\\System32\\OpenSSH\\ssh.exe -l %User% %Host%" ]
71+
"Exec": "C:\\Windows\\System32\\OpenSSH\\ssh.exe",
72+
"Args": [
73+
"-l",
74+
"%User%",
75+
"%Host%"
76+
]
7377
},
7478

7579
{
@@ -128,8 +132,11 @@
128132
"ParserId": "ssh",
129133
"Options": []
130134
},
131-
"Exec": "C:\\windows\\system32\\cmd.exe",
132-
"Args": [ "/c", "C:\\Program Files\\PuTTY\\putty.exe", "-ssh", "%user%@%host%" ]
135+
"Exec": "C:\\Program Files\\PuTTY\\putty.exe",
136+
"Args": [
137+
"-ssh",
138+
"%user%@%host%"
139+
]
133140
},
134141
{
135142
"Id": "putty-telnet",
@@ -141,8 +148,11 @@
141148
"ParserId": "telnet",
142149
"Options": []
143150
},
144-
"Exec": "C:\\windows\\system32\\cmd.exe",
145-
"Args": [ "/c", "C:\\Program Files\\PuTTY\\putty.exe", "-telnet", "%user%@%host%" ]
151+
"Exec": "C:\\Program Files\\PuTTY\\putty.exe",
152+
"Args": [
153+
"-telnet",
154+
"%user%@%host%"
155+
]
146156
},
147157
{
148158
"Id": "remmina-rdp",

src/UrlParser/BaseParser.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ protected void SetValue(Match match, int index, Token property, bool decode, str
145145
}
146146
Dictionary[property] = val;
147147
}
148-
148+
149149
protected void GetSafeguardUserValue()
150150
{
151151
var match = SafeguardUserPattern.Match(Dictionary[Token.User]);
@@ -174,7 +174,7 @@ private void WriteTempFile(IEnumerable<string> lines, string ext)
174174
var user = Dictionary[Token.TargetUser];
175175
user = user.Replace('\\', '~');
176176
tempFile = Path.Combine(Path.GetTempPath(),
177-
$"SG-{host}_{user}_{guid}.{ext}");
177+
$"SG-{host}_{user}_{guid}{ext}");
178178
}
179179
else
180180
{
@@ -343,15 +343,15 @@ protected void Parse(Uri url)
343343
{
344344
Dictionary = new Dictionary<Token, string>();
345345
try {
346-
Dictionary[Token.OriginalUrl]=url.GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
346+
Dictionary[Token.OriginalUrl]=url.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped);
347347
Dictionary[Token.RelativeUrl] = StripProtocol(Dictionary[Token.OriginalUrl]);
348-
Dictionary[Token.Protocol] = url.GetComponents(UriComponents.Scheme, UriFormat.SafeUnescaped);
349-
Dictionary[Token.Host] = url.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped);
350-
Dictionary[Token.Port] = url.GetComponents(UriComponents.Port, UriFormat.SafeUnescaped);
351-
Dictionary[Token.Path] = url.GetComponents(UriComponents.Path, UriFormat.SafeUnescaped);
352-
Dictionary[Token.User] = url.GetComponents(UriComponents.UserInfo, UriFormat.SafeUnescaped);
353-
Dictionary[Token.Query] = url.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);
354-
Dictionary[Token.Fragment] = url.GetComponents(UriComponents.Fragment, UriFormat.SafeUnescaped);
348+
Dictionary[Token.Protocol] = url.GetComponents(UriComponents.Scheme, UriFormat.Unescaped);
349+
Dictionary[Token.Host] = url.GetComponents(UriComponents.Host, UriFormat.Unescaped);
350+
Dictionary[Token.Port] = url.GetComponents(UriComponents.Port, UriFormat.Unescaped);
351+
Dictionary[Token.Path] = url.GetComponents(UriComponents.Path, UriFormat.Unescaped);
352+
Dictionary[Token.User] = url.GetComponents(UriComponents.UserInfo, UriFormat.Unescaped);
353+
Dictionary[Token.Query] = url.GetComponents(UriComponents.Query, UriFormat.Unescaped);
354+
Dictionary[Token.Fragment] = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
355355
ParseConfig();
356356
}
357357
catch

src/UrlParser/DefaultRdpUrlParser.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ public override IDictionary<Token,string> Parse(string url)
7171
{
7272
if (key.Equals(FulladdressKey))
7373
{
74-
_msArgList.Add($"{key}:s:{result.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped)}");
74+
_msArgList.Add($"{key}:s:{result.GetComponents(UriComponents.Host, UriFormat.Unescaped)}");
7575
}
7676
else if (key.Equals(UsernameKey))
7777
{
78-
_msArgList.Add($"{key}:s:{result.GetComponents(UriComponents.UserInfo, UriFormat.SafeUnescaped)}");
78+
_msArgList.Add($"{key}:s:{result.GetComponents(UriComponents.UserInfo, UriFormat.Unescaped)}");
7979

8080
}
8181
else {
@@ -188,7 +188,7 @@ protected override IEnumerable<string> GetDefaultTemplate()
188188
private void ParseArgs(string clArgs)
189189
{
190190
var usedNames = new HashSet<string>();
191-
var re = new Regex("([^=]+)=(\\S+)");
191+
var re = new Regex("([^=]+)=(.+)");
192192
var args = clArgs.Split('&');
193193
foreach (var arg in args)
194194
{
@@ -201,7 +201,9 @@ private void ParseArgs(string clArgs)
201201
var value = m.Groups[2].Value;
202202
if (name.Equals(UsernameKey))
203203
{
204-
if (value.IndexOf("%25", StringComparison.Ordinal) >= 0 || value.IndexOf("%5c", StringComparison.Ordinal)>= 0)
204+
if ((value.IndexOf("%25", StringComparison.Ordinal) >= 0) ||
205+
(value.IndexOf("%5c", StringComparison.Ordinal)>= 0) ||
206+
(value.IndexOf("%20", StringComparison.Ordinal) >=0))
205207
{
206208
value = HttpUtility.UrlDecode(value);
207209
}

src/UrlParser/DefaultSshUrlParser.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public DefaultSshUrlParser(ParserConfig config, IDictionary<Token, string> dicti
2525
Dictionary = dictionary;
2626
}
2727

28-
public Regex ScpPattern = new Regex("(([^:]+)://)?((\\S+)@([^:]+)(:(\\d+))?)", RegexOptions.IgnoreCase);
28+
public Regex ScpPattern = new Regex("(([^:]+)://)?((.+)@([^:]+)(:(\\d+))?)", RegexOptions.IgnoreCase);
2929

3030
public override IDictionary<Token, string> Parse(string url)
3131
{
@@ -54,7 +54,6 @@ public override IDictionary<Token, string> Parse(string url)
5454
else
5555
{
5656
SetValue(match, 2, Token.Protocol, false, "ssh");
57-
SetValue(match, 3, Token.RelativeUrl, false);
5857
SetValue(match, 4, Token.User, true);
5958
SetValue(match, 5, Token.Host, false);
6059
SetValue(match, 7, Token.Port, false, "22");

test/TestDefaultRdpUrlParser.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ public void Test1()
2424
var port="3389";
2525
var vault="10.5.33.238";
2626
var token="epdFwRQSofwL6xJV4Ud32g4TXKM7XgXkYU8ks4i5GQHURRoBiFq5Rjr4dT";
27-
var targetuser="win10-acct1";
27+
var targetuser="win10-acct1%20with%20Space";
28+
var decodedTargetUser = "win10-acct1 with Space";
2829
var targethost="10.5.60.94";
2930
var targetport="3389";
3031
var user = $"username=s:localhost%5cvaultaddress%7e{vault}%25token%7e{token}%25{targetuser}%25{targethost}:{targetport}";
31-
var decodedUser = $"localhost\\vaultaddress~{vault}%token~{token}%{targetuser}%{targethost}:{targetport}";
32+
var decodedUser = $"localhost\\vaultaddress~{vault}%token~{token}%{decodedTargetUser}%{targethost}:{targetport}";
3233

3334
var str = $"full+address=s:{host}:{port}&{user}";
3435
var dictionary =sut.Parse($"{str}/");
@@ -40,7 +41,7 @@ public void Test1()
4041
Assert.Equal(decodedUser, dictionary[Token.User]);
4142
Assert.Equal(vault, dictionary[Token.Vault]);
4243
Assert.Equal(token, dictionary[Token.Token]);
43-
Assert.Equal(targetuser, dictionary[Token.TargetUser]);
44+
Assert.Equal(decodedTargetUser, dictionary[Token.TargetUser]);
4445
Assert.Equal(targethost, dictionary[Token.TargetHost]);
4546
Assert.Equal(targetport, dictionary[Token.TargetPort]);
4647
Assert.Equal(string.Empty, dictionary[Token.GeneratedFile]);
@@ -62,13 +63,13 @@ public void Test2()
6263
//rdp://username=s:encodeduser&full+address=s:hostname:port&screen%20mode%20id=i:3&shell working directory=s:C:/dir1 dir2
6364
using (var sut = new DefaultRdpUrlParser(new Dto.ParserConfig{ UseDefaultTemplate = true }))
6465
{
65-
var url = "rdp://username=s:myuser%5cishere&full%20address=s:myhostname:3333&screen%20mode%20id=i:3&shell+working+directory=s:C%3a%2Fdir1+dir2/";
66+
var url = "rdp://username=s:my%20test%20user%5cishere&full%20address=s:myhostname:3333&screen%20mode%20id=i:3&shell+working+directory=s:C%3a%2Fdir1+dir2/";
6667
var dictionary = sut.Parse($"{url}");
6768
Assert.Equal(url, dictionary[Token.OriginalUrl]);
6869
Assert.Equal("rdp", dictionary[Token.Protocol]);
6970
Assert.Equal("myhostname", dictionary[Token.Host]);
7071
Assert.Equal("3333", dictionary[Token.Port]);
71-
Assert.Equal("myuser\\ishere", dictionary[Token.User]);
72+
Assert.Equal("my test user\\ishere", dictionary[Token.User]);
7273
var tempfile = dictionary[Token.GeneratedFile ];
7374
var lines = File.ReadAllLines(tempfile);
7475
var count = 0;
@@ -92,7 +93,7 @@ public void Test2()
9293
if (Regex.IsMatch(one,"^username" ))
9394
{
9495
count++;
95-
Assert.Equal("username:s:myuser\\ishere", one);
96+
Assert.Equal("username:s:my test user\\ishere", one);
9697
}
9798
}
9899
Assert.Equal(4, count);
@@ -116,13 +117,13 @@ public void Test3()
116117

117118
using (var sut = new DefaultRdpUrlParser(new Dto.ParserConfig{ UseTemplateFile = template }))
118119
{
119-
var url = "rdp://username=s:myuser%5cishere&full%20address=s:myhostname:3333&screen%20mode%20id=i:3&shell+working+directory=s:C%3a%2Fdir1+dir2/";
120+
var url = "rdp://username=s:my test user%5cishere&full%20address=s:myhostname:3333&screen%20mode%20id=i:3&shell+working+directory=s:C%3a%2Fdir1+dir2/";
120121
var dictionary = sut.Parse($"{url}");
121122
Assert.Equal(url, dictionary[Token.OriginalUrl]);
122123
Assert.Equal("rdp", dictionary[Token.Protocol]);
123124
Assert.Equal("myhostname", dictionary[Token.Host]);
124125
Assert.Equal("3333", dictionary[Token.Port]);
125-
Assert.Equal("myuser\\ishere", dictionary[Token.User]);
126+
Assert.Equal("my test user\\ishere", dictionary[Token.User]);
126127
var tempfile = dictionary[Token.GeneratedFile ];
127128
var fileLines = File.ReadAllLines(tempfile);
128129
var count = 0;
@@ -146,7 +147,7 @@ public void Test3()
146147
else if (Regex.IsMatch(one,"^username" ))
147148
{
148149
count++;
149-
Assert.Equal("username:s:myuser\\ishere", one);
150+
Assert.Equal("username:s:my test user\\ishere", one);
150151
}
151152
}
152153
Assert.Equal(4, count);
@@ -167,17 +168,18 @@ public void Test4()
167168

168169

169170
//standard URI
170-
//myprot://myuser:mypass@myhost:2222/thisisapath?queryit#fragment
171+
//myprot://my test user:mypass@myhost:2222/thisisapath?queryit#fragment
171172
using (sut = new DefaultRdpUrlParser(new Dto.ParserConfig())) {
172173

173-
str="myuser%5c:mypass@myhost:3456/thisisapath?queryit#fragment";
174+
str="my%20test%20user%5c:mypass@myhost:3456/thisisapath?queryit#fragment";
175+
var decodedStr = "my test user\\:mypass@myhost:3456/thisisapath?queryit#fragment";
174176
var uri=$"myprot://{str}";
175177

176178
var dictionary = sut.Parse(uri);
177179
Assert.Equal("myprot", dictionary[Token.Protocol]);
178180
Assert.Equal(uri, dictionary[Token.OriginalUrl]);
179181
Assert.Equal(str, dictionary[Token.RelativeUrl]);
180-
Assert.Equal("myuser%5c:mypass", dictionary[Token.User]);
182+
Assert.Equal("my test user\\:mypass", dictionary[Token.User]);
181183
Assert.Equal("myhost", dictionary[Token.Host]);
182184
Assert.Equal("3456", dictionary[Token.Port]);
183185
Assert.Equal("thisisapath", dictionary[Token.Path]);

0 commit comments

Comments
 (0)