Here is the guts of a rinky dink program that uploads a file
static void GetMsg(std::string &msg,const char *password);
static void TopMsg(std::string &msg,const char *target,const char
*contentlength,const char *password);
static void MidMsg(std::string &msg,const char *fname);
static void BotMsg(std::string &msg,const char *password);
static int DumpFile(const char *fname,BYTE *buf,int maxlen);
static void Base64Encode(const char *s,char *d);
int DetermineFileSize(const char *fname);
HRESULT DoUpgrade(const char *target,const char *target_password,const
char *fname,const char *fname_password)
{
std::string topmsg="",midmsg="",botmsg="";
char contentlength[16];
int origsize=0,totalsize=0;
unsigned int nsize=0;
unsigned int fsize=0;
BYTE *bigbuf=NULL;
SSLSocket myssl;
int RC=0;
char hash[128];
char foo[128];
sprintf(foo,"%s:%s","admin",target_password);
Base64Encode(foo,(char *)&hash);
// Generate Messages
MidMsg(midmsg,fname);
BotMsg(botmsg,fname_password);
// Calculate Content-length
origsize = DetermineFileSize(fname);
if (origsize == ERROR_FILE_NOT_FOUND )
{
fprintf(stderr,"TRY AGAIN \n" );
return ERROR_FILE_NOT_FOUND;
}
fsize = (int) midmsg.size();
fsize+= origsize;
fsize+= (int) botmsg.size();
sprintf(contentlength,"%d",fsize);
//#if defined (DEBUG)
// fprintf(stderr,"line 44 \n");
//#endif
// Write out top
TopMsg(topmsg,target,contentlength,hash);
// Write out Middle
bigbuf=new BYTE[origsize+1];
memset(bigbuf,0,origsize+1);
fsize = DumpFile(fname,(BYTE *) bigbuf,origsize+1);
if (fsize < 0)
return NO_ERROR;
// Open SSL connection
RC = myssl.Setup(target);
if ( RC != 0)
{
fprintf(stderr,"SSL FAILED with error %d\n", RC );
fprintf(stderr,"Unable to make SSL connection application is
aborted \n");
return ERR_SSL_CONNECTION_FAILED;
}
else
{
fprintf(stdout,"+++++++++ SSL Connection Succeeded
+++++++++++++\n");
}
// #ifdef _DEBUG
fprintf(stderr,"About to write to SSLsocket\n");
// #endif
// Write out messages
nsize =myssl.writeToSSLSocket( topmsg.c_str(), topmsg.size() );
if (nsize != topmsg.size() )
fprintf(stderr,"TOP FAILED\n");
#ifdef _DEBUG
fprintf(stdout,"%s\n",topmsg.c_str());
#endif
totalsize += nsize;
nsize =myssl.writeToSSLSocket( midmsg.c_str());
if (nsize != midmsg.size() )
fprintf(stderr,"MID FAILED\n");
totalsize += nsize;
nsize=myssl.writeToSSLSocket((char *) bigbuf,fsize);
if ( nsize != fsize)
fprintf(stderr,"FILE FAILED\n");
totalsize += nsize;
nsize =myssl.writeToSSLSocket(botmsg.c_str());
if (nsize != botmsg.size() )
fprintf(stderr,"BOT FAILED\n");
totalsize += nsize;
// Get Response
char rec_buff[4096];
memset(rec_buff, 0, sizeof(rec_buff));
int bytesRead = myssl.readFromSSLSocket(rec_buff, 4096 -1);
if (bytesRead <= 0)
fprintf(stderr,"formatdata.cpp: SSLSocket first read failed
\n");
#ifdef _DEBUG
else
fprintf(stdout,"%s\n",rec_buff);
#endif
// Shutdown
myssl.Shutdown();
// Prepare Nex message
GetMsg(topmsg,hash);
// Open SSL connection
if (myssl.Setup(target) != 0)
{
fprintf(stderr,"formatdata.cpp: SSL FAILED\n");
}
else
{
fprintf(stdout,"SSL Succeeded\n");
}
// Write out DoUpgrade message
nsize =myssl.writeToSSLSocket( topmsg.c_str(), topmsg.size() );
if (nsize != topmsg.size() )
fprintf(stderr,"TOP FAILED\n");
#ifdef _DEBUG
fprintf(stdout,"nsize = %d\n", nsize );
fprintf(stdout,"topmsg.size = %d\n", topmsg.size() );
#endif
totalsize += nsize;
//#ifdef _DEBUG
fprintf(stdout,"++++ Here's the html string we're sending over ++++
\n");
fprintf(stdout,"%s\n",topmsg.c_str());
//#endif
bytesRead = myssl.readFromSSLSocket(rec_buff, 4096 -1);
if (bytesRead <= 0)
{
fprintf(stderr,"formatdata.cpp: SSLSocket second read failed
\n");
}
//#ifdef _DEBUG
else
{
fprintf(stdout,"Successfully read %d bytes from ssl socket \n",
bytesRead );
fprintf(stdout,"..... and here's what we gotback \n" );
fprintf(stdout,"%s\n",rec_buff);
}
//#endif
// Shutdown
myssl.Shutdown();
return NO_ERROR;
}
void TopMsg(std::string &msg,const char *target,const char
*contentlength,const char *password)
{
msg ="POST /sys_opts.html?frame=upgd_frms HTTP/1.1\r\n";
msg +="Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, */*\r\n";
msg +="Referer: http://";
msg +=target ; msg +=
"/sys_opts.html?frame=upgd_frms\r\n";
msg +="Accept-Language: en-us\r\n";
msg +="Content-Type: multipart/form-data;
boundary=---------------------------7d2deb2062e\r\n";
msg +="User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT
5.1; .NET CLR 1.0.3705)\r\n";
msg +="Host: "; msg += target; msg +="\r\n";
msg +="Content-Length: "; msg += contentlength ; msg +="\r\n";
msg +="Pragma: no-cache\r\n";
msg +="Authorization: Basic "; msg += password ; msg +="\r\n";
msg +="Connection: keep-alive\r\n";
msg +="Accept-encoding: deflate, gzip\r\n";
msg +="\r\n";
}
void MidMsg(std::string &msg,const char *fname)
{
msg +="-----------------------------7d2deb2062e\r\n";
msg +="Content-Disposition: form-data; name=\"file\"; filename=\"";
msg += fname ; msg +="\"\r\n";
msg +="Content-Type: application/octet-stream\r\n";
msg +="\r\n";
}
void BotMsg(std::string &msg,const char *password)
{
msg +="\r\n";
msg +="-----------------------------7d2deb2062e\r\n";
msg +="Content-Disposition: form-data; name=\"password\"\r\n";
msg +="\r\n";
msg +=password ; msg +="\r\n";
msg +="-----------------------------7d2deb2062e\r\n";
msg +="Content-Disposition: form-data; name=\"UPFRM\"\r\n";
msg +="\r\n";
msg +=" OK \r\n";
msg +="-----------------------------7d2deb2062e--\r\n";
}
int DumpFile(const char *fname,BYTE *buf,int maxlen)
{
int z=0,ch=0;
FILE *fh=fopen(fname,"rb");
while (( ch=getc(fh) ) != EOF)
{
buf[z]=ch;
z++;
if (z >= maxlen)
return -1;
}
fclose(fh);
return z;
}
void GetMsg(std::string &msg,const char *password)
{
msg ="GET /sys_opts.html?frame=doupgrade HTTP/1.1\r\n";
msg +="Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, */*\r\n";
// msg +="Referer: http://";
msg +=target ; msg +=
"/sys_opts.html?frame=upgd_frms\r\n";
// msg +="Accept-Language: en-us\r\n";
// msg +="Content-Type: multipart/form-data;
boundary=---------------------------7d2deb2062e\r\n";
// msg +="User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT
5.1; .NET CLR 1.0.3705)\r\n";
// msg +="Host: "; msg += target; msg +="\r\n";
// msg +="Content-Length: "; msg += contentlength ; msg +="\r\n";
msg +="Pragma: no-cache\r\n";
msg +="Authorization: Basic "; msg += password; msg +="\r\n";
msg +="Connection: keep-alive\r\n";
msg +="Accept-encoding: deflate, gzip\r\n";
msg +="\r\n";
}
void Base64Encode(const char *s,char *d)
{
/* Conversion table. */
static char tbl[64] = {
'A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X',
'Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3',
'4','5','6','7','8','9','+','/'
};
UINT32 i,length=strlen(s);
char *p=d;
char *ps=(char *) s;
/* Transform the 3x8 bits to 4x6 bits, as required by base64. */
for (i = 0; i < length; i += 3)
{
*p++ = tbl[ps[0] >> 2];
*p++ = tbl[((ps[0] & 3) << 4) + (ps[1] >> 4)];
*p++ = tbl[((ps[1] & 0xf) << 2) + (ps[2] >> 6)];
*p++ = tbl[ps[2] & 0x3f];
ps += 3;
}
/* Pad the result if necessary... */
if (i == length + 1)
*(p - 1) = '=';
else if (i == length + 2)
*(p - 1) = *(p - 2) = '=';
/* ...and zero-terminate it. */
*p = '\0';
}
Mark Thomas wrote:
Hi,
I was wondering if anybody has any pointers on what actually is happening
under the hood in HTTP POST land, Are just the contents just sent ?, or
encoded in some fashion. Or is just a
HTTP POST Header stuff
And then
Filename=<filename>&sendfile=<contents-of-file>
Just got my WWDC ticket so see you all there.
Thanks for any pointers
Mark.
|