URL encoded passwords

Advertisement

Anony Mouse
Guest

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;
}
//---------------------------------------------------------------------

Reply with quote

Advertisement

Anony Mouse
Guest

Working patch

--- SessionData.cpp.orig        2004-10-14 10:57:23.117376113 -0600
+++ SessionData.cpp     2004-10-14 14:17:21.329551988 -0600
@@ -638,6 +638,65 @@
   }
 }
 //---------------------------------------------------------------------
+static void __fastcall UrlDecode(AnsiString * param)
+{
+  if (param == NULL) return;
+
+  const char * buff = param->c_str();
+  char * buff2 = new char[strlen(buff)];
+  char hexstr[3];
+  int x, y;
+
+  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 +787,14 @@
       *Password = UserInfo;
     }
   }
+
+  UrlDecode(ConnectInfo);
+  UrlDecode(HostName);
+  UrlDecode(UserName);
+  UrlDecode(Password);
+  UrlDecode(Path);
+  UrlDecode(FileName);
+
   return Result;
 }
 //---------------------------------------------------------------------

Reply with quote

martin
Site Admin
martin avatar

Re: URL encoded passwords

With what browser have you tested your patch? I have found that IE replaces the %XX patterns with appropriate character before passing the URL to WinSCP. So your fix will not works with IE, because it will not be able to distinguish @ to %40 anyway.

Mozilla does not perform the replacement.

Reply with quote

Guest

Re: URL encoded passwords

I was able to compile with the trial version, but I got some Invalid Pointer errors every now and again. Don't know what it was all about.

I'm not using a browser with WinSCP, just calling it from a batch file in console mode.

I see that you've put a fix into 3.7.1. Thanks! Now I don't have to worry about patching it and dealing with Borland's compiler.

Reply with quote

Advertisement

You can post new topics in this forum