URL encoded passwords
Here's a not-so-hypothetical situation:
Let's say my password is ": @am a My P@ssw0rd"
It should be clear that this password could cause serious problems for the scp://user:pasword@host/path URL syntax. Clearly the ':', '@', and space characters should be escaped with URL encoding (%3A, %40, and +, respectively). It looks like WinSCP doesn't support URL encoding, though. I've tried to hack it in, but I don't have Borland C++ (I'm downloading the trial now). Anyway, here's a patch, but note that I haven't tried to compile it yet, so expect it to not work:
--- SessionData.cpp.orig 2004-10-14 10:57:23.117376113 -0600
+++ SessionData.cpp 2004-10-14 10:32:13.185073804 -0600
@@ -638,6 +638,61 @@
}
}
//---------------------------------------------------------------------
+static void __fastcall UrlDecode(AnsiString * param)
+{
+ const char * buff = param->c_str();
+ char * buff2 = new char[strlen(buff)];
+
+ try
+ {
+ for (x = 0, y = 0; x < strlen(buff); x++, y++)
+ {
+ switch (buff[x])
+ {
+ /* Convert all + chars to space chars */
+ case '+':
+ buff2[y] = ' ';
+ break;
+
+ /* Convert all %xy hex codes into ASCII chars */
+ case '%':
+
+ /* Copy the two bytes following the % */
+ strncpy(hexstr, &buff[x + 1], 2);
+
+ /* Skip over the hex */
+ x = x + 2;
+
+ /* Convert the hex to ASCII */
+ /* Prevent user from altering URL delimiter sequence */
+ if( ((strcmp(hexstr,"26")==0)) || ((strcmp(hexstr,"3D")==0)) )
+ {
+ buff2[y]='%';
+ y++;
+ strcpy(buff2,hexstr);
+ y=y+2;
+ break;
+ }
+
+ buff2[y] = (char)strtol(hexstr, NULL, 16);
+ break;
+
+ /* Make an exact copy of anything else */
+ default:
+ buff2[y] = buff[x];
+ break;
+ }
+ }
+ buff2[y] = '\0';
+ param->SetLength(y+1);
+ memcpy(param->c_str(), buff2, y+1);
+ }
+ __finally
+ {
+ delete[] buff2;
+ }
+}
+//---------------------------------------------------------------------
bool __fastcall TSessionData::ParseUrl(AnsiString Url, int Params,
AnsiString * ConnectInfo, AnsiString * HostName, int * PortNumber,
AnsiString * UserName, AnsiString * Password, AnsiString * Path,
@@ -728,6 +783,14 @@
*Password = UserInfo;
}
}
+
+ UrlDecode(ConnectInfo);
+ UrlDecode(HostName);
+ UrlDecode(UserName);
+ UrlDecode(Password);
+ UrlDecode(Path);
+ UrlDecode(FileName);
+
return Result;
}
//---------------------------------------------------------------------
Let's say my password is ": @am a My P@ssw0rd"
It should be clear that this password could cause serious problems for the scp://user:pasword@host/path URL syntax. Clearly the ':', '@', and space characters should be escaped with URL encoding (%3A, %40, and +, respectively). It looks like WinSCP doesn't support URL encoding, though. I've tried to hack it in, but I don't have Borland C++ (I'm downloading the trial now). Anyway, here's a patch, but note that I haven't tried to compile it yet, so expect it to not work:
--- SessionData.cpp.orig 2004-10-14 10:57:23.117376113 -0600
+++ SessionData.cpp 2004-10-14 10:32:13.185073804 -0600
@@ -638,6 +638,61 @@
}
}
//---------------------------------------------------------------------
+static void __fastcall UrlDecode(AnsiString * param)
+{
+ const char * buff = param->c_str();
+ char * buff2 = new char[strlen(buff)];
+
+ try
+ {
+ for (x = 0, y = 0; x < strlen(buff); x++, y++)
+ {
+ switch (buff[x])
+ {
+ /* Convert all + chars to space chars */
+ case '+':
+ buff2[y] = ' ';
+ break;
+
+ /* Convert all %xy hex codes into ASCII chars */
+ case '%':
+
+ /* Copy the two bytes following the % */
+ strncpy(hexstr, &buff[x + 1], 2);
+
+ /* Skip over the hex */
+ x = x + 2;
+
+ /* Convert the hex to ASCII */
+ /* Prevent user from altering URL delimiter sequence */
+ if( ((strcmp(hexstr,"26")==0)) || ((strcmp(hexstr,"3D")==0)) )
+ {
+ buff2[y]='%';
+ y++;
+ strcpy(buff2,hexstr);
+ y=y+2;
+ break;
+ }
+
+ buff2[y] = (char)strtol(hexstr, NULL, 16);
+ break;
+
+ /* Make an exact copy of anything else */
+ default:
+ buff2[y] = buff[x];
+ break;
+ }
+ }
+ buff2[y] = '\0';
+ param->SetLength(y+1);
+ memcpy(param->c_str(), buff2, y+1);
+ }
+ __finally
+ {
+ delete[] buff2;
+ }
+}
+//---------------------------------------------------------------------
bool __fastcall TSessionData::ParseUrl(AnsiString Url, int Params,
AnsiString * ConnectInfo, AnsiString * HostName, int * PortNumber,
AnsiString * UserName, AnsiString * Password, AnsiString * Path,
@@ -728,6 +783,14 @@
*Password = UserInfo;
}
}
+
+ UrlDecode(ConnectInfo);
+ UrlDecode(HostName);
+ UrlDecode(UserName);
+ UrlDecode(Password);
+ UrlDecode(Path);
+ UrlDecode(FileName);
+
return Result;
}
//---------------------------------------------------------------------