C:/fscan/HTTPCore/HTTP.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * TODO:
00007  * Revisar el soporte de proxy HTTP con autenticacion ("Proxy-Authorization" + "Proxy-Authenticate")
00008  * Implementation of the AutoRedirect303 feature (y mirar que hacer con 302 y 301 )
00009  * Segregar SendHTTPRequest() en BuildHTTPRequest() y despues una llamada a DispatchHTTPRequest(). 
00010    Esto permitiría definir un SendAsyncHTTPRequest() y definir un Callback para la petición.
00011 */
00012 
00013 #include "HTTPCore.h"
00014 #include "CallBack.h"
00015 #include "Threading.h"
00016 
00017 
00018 
00019 /*******************************************************************************
00020  ************************** Functions not exported *****************************
00021  *******************************************************************************/
00022 
00023 static char*            GetServerVersion(HTTP_DATA *response);
00024 static unsigned int     IschallengeSupported(char *headers);
00025 static PREQUEST         ParseReturnedBuffer(HTTPHANDLE HTTPHandle, PHTTP_DATA request, PHTTP_DATA response, char *url);
00026 
00027 /*******************************************************************************
00028  *************************** Local definitions to this module ******************
00029  *******************************************************************************/
00030 unsigned int AutoRedirect303             = 1;
00031 const char       UserAgent[]                     = "User-Agent: Mozilla/5.0 (FHScan Core 1.1)\r\n";
00032 PHHANDLE         GlobalHTTPCoreApiOptions = NULL;
00033 
00034 /*******************************************************************************/
00035 /************************** GLOBAL HTTP CORE FUNCTIONS *************************/
00036 /*******************************************************************************/
00038 
00041 /*******************************************************************************/
00042 int             InitHTTPApi(void)
00043 {
00044         int ret = InitHTTPApiCore();
00045         if ( ret == 1 )
00046         {
00047                 GlobalHTTPCoreApiOptions = (PHHANDLE)malloc(sizeof(struct _hhandle));
00048                 memset((void*)GlobalHTTPCoreApiOptions,0,sizeof(struct _hhandle));
00049         }
00050         return (ret);
00051 }
00052 /*******************************************************************************/
00054 /*******************************************************************************/
00055 void    CloseHTTPApi(void)
00056 {
00057         CloseHTTPApiCore();
00058         if (GlobalHTTPCoreApiOptions)
00059         {
00060                 free(GlobalHTTPCoreApiOptions);
00061                 GlobalHTTPCoreApiOptions = NULL;
00062         }
00063         CloseHTTPConnectionHandle((HTTPHANDLE)GlobalHTTPCoreApiOptions);
00064         GlobalHTTPCoreApiOptions = NULL;
00065 }
00066 /*******************************************************************************/
00068 
00073 /*******************************************************************************/
00074 int SetHTTPAPIConfig(int opt, char *parameter)
00075 {
00076         return(SetHTTPConfig(GlobalHTTPCoreApiOptions,opt,parameter));
00077 }
00078 /*******************************************************************************/
00080 
00085 /*******************************************************************************/
00086 char *GetHTTPAPIConfig( int opt)
00087 {
00088         return(GetHTTPConfig(GlobalHTTPCoreApiOptions,opt));
00089 }
00090 /*******************************************************************************/
00092 
00107  /*******************************************************************************/
00108 HTTPHANDLE InitHTTPConnectionHandle(char *hostname, int port, int ssl)
00109 {
00110         PHHANDLE HTTPHandle=NULL;
00111         struct sockaddr_in remote;
00112 
00113         remote.sin_addr.s_addr = inet_addr(GlobalHTTPCoreApiOptions->ProxyHost ? GlobalHTTPCoreApiOptions->ProxyHost : hostname);
00114         if (remote.sin_addr.s_addr == INADDR_NONE)
00115         {
00116                 struct hostent *hostend=gethostbyname(GlobalHTTPCoreApiOptions->ProxyHost ? GlobalHTTPCoreApiOptions->ProxyHost : hostname);
00117                 if (!hostend)
00118                 {
00119                         return((HTTPHANDLE)NULL);
00120                 }
00121                 memcpy(&remote.sin_addr.s_addr, hostend->h_addr, 4);
00122         }
00123         HTTPHandle=(PHHANDLE)malloc(sizeof(struct _hhandle));
00124         memset(HTTPHandle,0,sizeof(struct _hhandle));
00125         HTTPHandle->target=remote.sin_addr.s_addr;
00126         strncpy(HTTPHandle->targetDNS, hostname ,sizeof(HTTPHandle->targetDNS));
00127         //printf("resuelto %s como %s\n",hostname,inet_ntoa(remote.sin_addr));
00128         HTTPHandle->port                        = port;
00129         HTTPHandle->NeedSSL                     = ssl;
00130         HTTPHandle->version                     = 1;
00131         HTTPHandle->AdditionalHeader= GlobalHTTPCoreApiOptions->AdditionalHeader ? _strdup(GlobalHTTPCoreApiOptions->AdditionalHeader) : NULL;
00132         HTTPHandle->UserAgent           = GlobalHTTPCoreApiOptions->UserAgent ? _strdup(GlobalHTTPCoreApiOptions->UserAgent) : NULL;
00133         HTTPHandle->ProxyHost           = GlobalHTTPCoreApiOptions->ProxyHost ? _strdup(GlobalHTTPCoreApiOptions->ProxyHost): NULL;
00134         HTTPHandle->ProxyPort           = GlobalHTTPCoreApiOptions->ProxyPort ? _strdup(GlobalHTTPCoreApiOptions->ProxyPort): NULL;
00135         HTTPHandle->lpProxyUserName = GlobalHTTPCoreApiOptions->lpProxyUserName ? _strdup(GlobalHTTPCoreApiOptions->lpProxyUserName): NULL;
00136         HTTPHandle->lpProxyPassword = GlobalHTTPCoreApiOptions->lpProxyPassword ? _strdup(GlobalHTTPCoreApiOptions->lpProxyPassword): NULL;
00137         HTTPHandle->DownloadBwLimit = GlobalHTTPCoreApiOptions->DownloadBwLimit ? _strdup(GlobalHTTPCoreApiOptions->DownloadBwLimit): NULL; 
00138         HTTPHandle->Cookie                      = NULL;
00139         HTTPHandle->conexion            = NULL;
00140         HTTPHandle->LastAuthenticationString=NULL;
00141         memset(HTTPHandle->LastRequestedUri,'\0',sizeof(HTTPHandle->LastRequestedUri));
00142         #ifdef _DBG_
00143         printf("resuelto %s como %s\n",hostname,inet_ntoa(remote.sin_addr));
00144         #endif
00145         
00146 #ifdef __WIN32__RELEASE__
00147         HTTPHandle->ThreadID = GetCurrentThreadId();
00148 #else
00149         HTTPHandle->ThreadID = pthread_self();
00150 #endif
00151 
00152         return((HTTPHANDLE)HTTPHandle);
00153 
00154 }
00155 /*******************************************************************************/
00157 
00163 /*******************************************************************************/
00164 
00165 char *GetHTTPConfig(HTTPHANDLE HTTPHandle,int opt)
00166 {
00167         PHHANDLE phandle=(PHHANDLE)HTTPHandle;
00168         switch(opt)
00169         {
00170                 case OPT_HTTP_MAXSPEED_DOWNLOAD:
00171                         return(NULL);
00172                         break;
00173                 case OPT_HTTP_COOKIE:
00174                         return ( phandle->Cookie );
00175                         break;
00176                 case OPT_HTTP_HEADER:
00177                         return ( phandle->AdditionalHeader );
00178                         break;
00179                 case OPT_HTTP_USERAGENT:
00180                         return ( phandle->UserAgent);
00181                         break;
00182                 case OPT_HTTP_PROXY_HOST:
00183                         return ( phandle->ProxyHost);
00184                         break;
00185                 case OPT_HTTP_PROXY_PORT:
00186                         return(phandle->ProxyPort);
00187                         break;
00188                 case OPT_HTTP_PROXY_USER:
00189                         return ( phandle->lpProxyUserName );
00190                         break;
00191                 case OPT_HTTP_PROXY_PASS:
00192                         return ( phandle->lpProxyPassword );
00193                         break;
00194                 case OPT_HTTP_PROTOCOL:
00195                         return(NULL);
00196                         break;
00197         }
00198         return(NULL);
00199 }
00200 /*******************************************************************************/
00202 
00228 /*******************************************************************************/
00229 
00230 int SetHTTPConfig(HTTPHANDLE HTTPHandle,int opt, char *parameter)
00231 {
00232         PHHANDLE phandle=(PHHANDLE)HTTPHandle;
00233         if (!HTTPHandle) return(-1);
00234 
00235         switch (opt)
00236         {
00237 
00238          case OPT_HTTP_MAXSPEED_DOWNLOAD:
00239                  if (phandle->DownloadBwLimit) free(phandle->DownloadBwLimit);
00240                  if (parameter)
00241                  {                       
00242                          phandle->DownloadBwLimit = _strdup(parameter);
00243                  } else {
00244                          phandle->DownloadBwLimit = NULL;
00245                  }
00246 
00247                 break;
00248          case OPT_HTTP_COOKIE:
00249                  if ( (parameter) && (*parameter) ){
00250                         if (phandle->Cookie)
00251                         {
00252                                 free(phandle->Cookie);
00253                                 phandle->Cookie= NULL;
00254                         }
00255                         if (strnicmp(parameter,"Cookie: ",8)==0) //Validate the cookie parameter
00256                         {
00257                                 phandle->Cookie=_strdup(parameter);
00258                         } else //Add Cookie Header..
00259                         {
00260                                 phandle->Cookie=(char*)malloc( 8 + strlen(parameter) +1 );
00261                                 strcpy(phandle->Cookie,"Cookie: ");
00262                                 strcpy(phandle->Cookie+8,parameter);
00263                         }
00264                  } else {
00265                          if (phandle->Cookie)
00266                          {
00267                                 free(phandle->Cookie);
00268                                 phandle->Cookie = NULL;
00269                          }
00270                  }
00271                 break;
00272 
00273          case OPT_HTTP_HEADER:
00274                  if (phandle->AdditionalHeader) 
00275                  {
00276                          free(phandle->AdditionalHeader);                       
00277                  }
00278                  if ( (parameter) && (*parameter) && (strchr(parameter,':')) ) 
00279                  {
00280                          int len2 = (int) strlen(parameter);
00281                          if (memcmp(parameter+len2 -2,"\r\n",2)!=0) {
00282                                  phandle->AdditionalHeader = (char*)malloc(len2 +2 +1 );
00283                                  memcpy(phandle->AdditionalHeader,parameter,len2);
00284                                  memcpy(phandle->AdditionalHeader +len2,"\r\n\x00",3);
00285                          } else {
00286                                 phandle->AdditionalHeader = _strdup(parameter);
00287                         }
00288                  }  else {
00289                          phandle->AdditionalHeader=NULL;
00290                  }
00291                 break;
00292 
00293          case OPT_HTTP_USERAGENT:
00294                  if (phandle->UserAgent) {
00295                         free(phandle->UserAgent);
00296                  }
00297                  if (parameter) {                       
00298                         phandle->UserAgent= _strdup(parameter);
00299                 } else {
00300                                 phandle->UserAgent=NULL;
00301                 }
00302                 break;
00303          case OPT_HTTP_PROXY_HOST:
00304                 if (phandle->ProxyHost) {
00305                         free(phandle->ProxyHost);
00306                         phandle->ProxyHost=NULL;
00307                 }
00308                 phandle->NeedSSL=0;
00309                 if (parameter) {
00310                         struct sockaddr_in remote;
00311                         phandle->ProxyHost=_strdup(parameter);
00312                         remote.sin_addr.s_addr = inet_addr(phandle->ProxyHost);
00313                         if (remote.sin_addr.s_addr == INADDR_NONE)
00314                         {
00315                                 struct hostent *hostend=gethostbyname(phandle->ProxyHost);
00316                                 if (!hostend) return(-1);
00317                                 memcpy(&remote.sin_addr.s_addr, hostend->h_addr, 4);
00318                         }
00319                         phandle->target=remote.sin_addr.s_addr;
00320                 } else  {
00321                         struct sockaddr_in remote;
00322                         phandle->ProxyHost = NULL;
00323                         remote.sin_addr.s_addr = inet_addr(phandle->targetDNS);
00324                         if (remote.sin_addr.s_addr == INADDR_NONE)
00325                         {
00326                                 struct hostent *hostend=gethostbyname(phandle->targetDNS);
00327                                 if (!hostend) return(-1);
00328                                 memcpy(&remote.sin_addr.s_addr, hostend->h_addr, 4);
00329                         }
00330                         phandle->target=remote.sin_addr.s_addr;
00331                 }
00332                 phandle->conexion=NULL;
00333                 if (!phandle->ProxyPort) phandle->ProxyPort=_strdup("8080");
00334                 break;
00335 
00336          case OPT_HTTP_PROXY_PORT:
00337                 if (parameter) {
00338                         if (phandle->ProxyPort) free(phandle->ProxyPort);
00339                         phandle->ProxyPort=_strdup(parameter);
00340                 } else {
00341                         free(phandle->ProxyPort);
00342                         phandle->ProxyPort=NULL;
00343                 }
00344                 break;
00345 
00346          case OPT_HTTP_PROXY_USER:
00347         if (phandle->lpProxyUserName) {
00348                         free(phandle->lpProxyUserName);
00349                 }
00350                 if (parameter) {
00351                         phandle->lpProxyUserName=_strdup(parameter);
00352                 } else phandle->lpProxyUserName=NULL;
00353                 break;
00354 
00355          case OPT_HTTP_PROXY_PASS:
00356                 if (phandle->lpProxyPassword) {
00357                         free(phandle->lpProxyPassword);
00358                 }
00359                 if (parameter) {
00360                         phandle->lpProxyPassword=_strdup(parameter);
00361                 } else phandle->lpProxyPassword=NULL;
00362                 break;
00363 
00364          case OPT_HTTP_PROTOCOL:
00365                 if (parameter) {
00366                         phandle->version=atoi(parameter);
00367                 } else phandle->version=1;
00368         break;
00369          default:
00370         return(-1);
00371 
00372         }
00373     return(1);
00374 
00375 }
00376 /*******************************************************************************/
00378 
00382 /*******************************************************************************/
00383 void CloseHTTPConnectionHandle(HTTPHANDLE HTTPHandle){
00384         if (HTTPHandle) {
00385                 if ((((PHHANDLE)HTTPHandle)->DownloadBwLimit)) free((((PHHANDLE)HTTPHandle)->DownloadBwLimit));
00386                 if ((((PHHANDLE)HTTPHandle)->ProxyHost)) free((((PHHANDLE)HTTPHandle)->ProxyHost));
00387                 if ((((PHHANDLE)HTTPHandle)->ProxyPort)) free((((PHHANDLE)HTTPHandle)->ProxyPort));
00388                 if ((((PHHANDLE)HTTPHandle)->AdditionalHeader)) free((((PHHANDLE)HTTPHandle)->AdditionalHeader));
00389                 if ((((PHHANDLE)HTTPHandle)->UserAgent)) free((((PHHANDLE)HTTPHandle)->UserAgent));
00390                 if ((((PHHANDLE)HTTPHandle)->lpProxyUserName)) free((((PHHANDLE)HTTPHandle)->lpProxyUserName));
00391                 if ((((PHHANDLE)HTTPHandle)->lpProxyPassword)) free((((PHHANDLE)HTTPHandle)->lpProxyPassword));
00392                 if ((((PHHANDLE)HTTPHandle)->LastAuthenticationString)) free((((PHHANDLE)HTTPHandle)->LastAuthenticationString));
00393                 free(HTTPHandle);
00394         }
00395 }
00396 
00397 /*******************************************************************************/
00399 
00403 /*******************************************************************************/
00404 static char *GetServerVersion(HTTP_DATA *response){
00405         char *server=NULL;
00406         if (response)
00407         {
00408                 if (response->Header)
00409                 {
00410                         if (response->HeaderSize)
00411                         {
00412                                 server = GetHeaderValue(response->Header,"Server: ",0);
00413                                 if ((!server) && (response->HeaderSize>=12) )
00414                                 {
00415                                         //server=(char*)malloc(9);
00416                                         //sprintf(server,"HTTP/1.%c",response->Header[7]);
00417                                         //TODO: IMPLEMENT THIS IN NEXT RELEASE
00418                                 }
00419                         }
00420 
00421                 }
00422         }
00423         return( server ? server :_strdup("HTTP/1.0") );
00424 }
00425 /*****************************************************************************/
00427 
00432 /*****************************************************************************/
00433 static unsigned int IschallengeSupported(char *headers)
00434 {
00435   char *AuthNeeded="WWW-Authenticate:";
00436   unsigned int ret=0;
00437   int i=0;
00438   char *auth;
00439 
00440   do {
00441     auth=GetHeaderValue(headers,AuthNeeded,i++);
00442         if (auth) {
00443                 if (strnicmp (auth, "basic",  5) == 0) {
00444                    if (!(ret & BASIC_AUTH)) ret+=BASIC_AUTH;
00445                 }  else
00446                 if (strnicmp (auth, "digest", 6) == 0) {
00447                    if (!(ret & DIGEST_AUTH)) ret+=DIGEST_AUTH;
00448                 } else
00449                 if (strnicmp (auth, "ntlm",   4) == 0) {
00450                    if (!(ret & NTLM_AUTH)) ret+=NTLM_AUTH;
00451                 } else
00452                 if (strnicmp (auth, "Negotiate",   9) == 0) {
00453                    if (!(ret & NTLM_AUTH)) ret+=NEGOTIATE_AUTH;
00454         } else {
00455                if (!(ret & UNKNOWN_AUTH)) ret+=UNKNOWN_AUTH;
00456                 }
00457                 free(auth);
00458         }
00459   } while (auth) ;
00460 
00461   if (ret & BASIC_AUTH)         return(BASIC_AUTH);
00462   if (ret & DIGEST_AUTH)        return(DIGEST_AUTH);
00463   if (ret & NTLM_AUTH)          return(NTLM_AUTH);
00464   if (ret & NEGOTIATE_AUTH) return(NEGOTIATE_AUTH);
00465 
00466   return(ret);
00467 }
00468 
00469 
00470 /*******************************************************************************/
00472 
00480 /*******************************************************************************/
00481 static PREQUEST ParseReturnedBuffer(HTTPHANDLE HTTPHandle, PHTTP_DATA request, PHTTP_DATA response, char *url)
00482 {
00483         PHHANDLE RealHTTPHandle=(PHHANDLE)HTTPHandle;
00484         struct _request *data;
00485         char version[4];
00486         if (!response)
00487         {
00488                 FreeHTTPData(request);
00489                 return(NULL);
00490         }
00491         data=(struct _request*)malloc(sizeof(struct _request));
00492         memset((void*)data,'\0',sizeof(struct _request));
00493         strncpy(data->hostname,RealHTTPHandle->targetDNS,sizeof(data->hostname)-1);
00494         data->ip=RealHTTPHandle->target;
00495         data->port=RealHTTPHandle->port;
00496         data->NeedSSL = RealHTTPHandle->NeedSSL;
00497         data->request=request;
00498         data->response=response;
00499         data->server=GetServerVersion(response);
00500         if (response->HeaderSize>=12)
00501         {
00502                 memcpy(version,response->Header+9,3);
00503                 version[3]='\0';
00504                 data->status=atoi(version);
00505         }
00506         data->challenge=IschallengeSupported(response->Header);
00507 
00508     if (data->challenge & DIGEST_AUTH)
00509     {
00510                 if (RealHTTPHandle->LastAuthenticationString){
00511                         free(RealHTTPHandle->LastAuthenticationString);
00512                         RealHTTPHandle->LastAuthenticationString=NULL;
00513                 }
00514                 RealHTTPHandle->LastAuthenticationString=GetHeaderValue(response->Header,"WWW-Authenticate: Digest ",0);
00515         }
00516 
00517         strncpy(data->url,url,sizeof(data->url)-1);
00518         strncpy(((PHHANDLE)HTTPHandle)->LastRequestedUri,url,sizeof(((PHHANDLE)HTTPHandle)->LastRequestedUri));
00519 
00520         return(data);
00521 }
00522 /*******************************************************************************/
00524 /*******************************************************************************/
00525 static __inline void AddLine(char *lpBuffer, char *source, unsigned int *Buffersize)
00526 {
00527     strncat(lpBuffer,source,*Buffersize);
00528         *Buffersize-=(unsigned int)strlen(source);
00529 }
00530 /*******************************************************************************/
00532 
00551 /*******************************************************************************/
00552 char *GetHeaderValue(char *headers,char *value,int n)
00553 {
00554     char *base,*end;
00555     end=base=headers;
00556     if ( (headers) && (value) )
00557         {
00558         unsigned int valuelen= (unsigned int) strlen(value);
00559         while (*end) {
00560             if (*end=='\n')
00561                         {
00562                                 if (strnicmp(base,value,valuelen)==0)
00563                 {
00564                                         if (n==0)
00565                     {
00566                         base  = base + valuelen;
00567                         while  (*base==' ') { base++; }
00568                                                 int len = end-base;
00569                                                 //assert(end-base < 1024 );
00570                                                 char *header=(char*)malloc(len+1);
00571                                                 memcpy(header,base,len);
00572                                                 if (header[len-1]=='\r')
00573                                                 {
00574                                                         header[len-1]='\0';
00575                                                 } else {
00576                                                         header[len]='\0';
00577                                                 }
00578                                                 return (header);
00579                     } else
00580                     {
00581                         n--;
00582                     }
00583                 }
00584                                 base=end+1;
00585             }
00586                         end++;
00587         }
00588     }
00589     return(NULL);
00590 }
00591 /*******************************************************************************/
00593 
00617 /*******************************************************************************/
00618 char *GetHeaderValueByID(char *headers, unsigned int id)
00619 {
00620         char *base, *end;
00621         base = end=headers;
00622 
00623         #define HEADER_ID_NOT_FOUND NULL
00624 
00625    if (headers)
00626         {
00627                 while (*end)
00628                 {
00629                         if  (*end=='\n')
00630                         {
00631                                 if (id==0)
00632                                 {
00633                                         if ( (end - base)==1) {
00634                         return(HEADER_ID_NOT_FOUND);
00635                                         }
00636                                         char *p=(char *) malloc(end - base +1);
00637                                         memcpy(p,base,end-base);
00638                                         p[end-base]='\0';
00639                                         if (p[end-base-1]=='\r')
00640                                                 p[end-base-1]='\0';
00641                                         return(p);
00642                                 }
00643                                 id--;
00644                                 base=end+1;
00645                         }
00646                         end++;
00647                 }
00648         }
00649         return (HEADER_ID_NOT_FOUND);
00650 }
00651 /*******************************************************************************/
00653 
00658 /*******************************************************************************/
00659 PHTTP_DATA AddHeader(PHTTP_DATA request,char *Header)
00660 {
00661         int NewSize= (int) strlen(Header);
00662 
00663         request->Header=(char*)realloc(request->Header, request->HeaderSize + NewSize +1);
00664         memcpy(request->Header + request->HeaderSize -2, Header,NewSize);
00665         memcpy(request->Header + request->HeaderSize -2 + NewSize,"\r\n",2);
00666         request->HeaderSize+=NewSize;
00667         request->Header[request->HeaderSize]='\0';
00668 
00669     return(request);
00670 
00671 }
00672 
00673 /*******************************************************************************/
00675 
00679 /*******************************************************************************/
00680 PHTTP_DATA RemoveHeader(PHTTP_DATA request, char *Header)
00681 {
00682         char *base,*end;
00683         base = end=request->Header;
00684 
00685         if ( (request) && (request->Header) && (Header) )
00686         {
00687         int HeaderLen= (int) strlen(Header);
00688                 while (*end) {
00689                         if (*end=='\n')
00690                         {
00691                                 if (strnicmp(base,Header,HeaderLen)==0)
00692                                 {
00693                                         end=strchr(base,'\n');
00694                                         memcpy(request->Header + (base - request->Header),end+1,strlen(end+1)+1);
00695                                         request->Header=(char *)realloc(request->Header,request->HeaderSize - (end - base +1) +1 );
00696                                         request->HeaderSize = (int) strlen(request->Header);//request->HeaderSize - (end - base -1) ;
00697                                         break;
00698                                 }
00699                                 base=end+1;
00700                         }
00701                         end++;
00702                 }
00703         }
00704         return(request);
00705 
00706 }
00707 /*******************************************************************************/
00709 
00714 /*******************************************************************************/
00715 void *FreeRequest(PREQUEST data) {
00716    if (data)
00717    {
00718        FreeHTTPData(data->request);
00719        FreeHTTPData(data->response);
00720           if (data->server) free(data->server);
00721       free(data);
00722    }
00723    return(NULL);
00724 }
00725 /*******************************************************************************/
00727 
00735 PREQUEST SendRawHttpRequest(HTTPHANDLE HTTPHandle,char *headers, char *postdata)
00736 {
00737         PREQUEST                DATA;
00738         PHTTP_DATA              request,response;
00739 
00740         request=InitHTTPData(headers,postdata);
00741         response=DispatchHTTPRequest((PHHANDLE)HTTPHandle,request);
00742         DATA=ParseReturnedBuffer( HTTPHandle, request,response,"/TODO"); //manually parse the request buffer to extract URI
00743 
00744         return(DATA);
00745 }
00746 /*******************************************************************************/
00748 
00812 /*******************************************************************************/
00813 PREQUEST SendHttpRequest(
00814         HTTPHANDLE HTTPHandle,
00815         char *VHost,
00816         char *HTTPMethod,
00817         char *url,
00818         char *Postdata,
00819         char *lpUsername,
00820         char *lpPassword,
00821         int AuthMethod)
00822 {
00823         char                    tmp[MAX_POST_LENGHT+1]="";
00824         char                    lpBuffer[MAX_POST_LENGHT+1]="";
00825         unsigned int    lpSize=MAX_POST_LENGHT;
00826         PREQUEST                DATA;
00827         PHHANDLE                RealHTTPHandle=(PHHANDLE)HTTPHandle;
00828         PHTTP_DATA              request=NULL, response=NULL;// = InitHTTPData();
00829 
00830         if ( (!url) || (*url=='\0') ){ //Bad url
00831                 return ( NULL);
00832         }
00833 
00834         if ( (RealHTTPHandle->ProxyHost) && (!RealHTTPHandle->NeedSSL) )
00835         {
00836         snprintf(lpBuffer,lpSize-1,"%s http://%s:%i%s HTTP/1.%i\r\n",HTTPMethod,RealHTTPHandle->targetDNS,RealHTTPHandle->port,url,((PHHANDLE)HTTPHandle)->version);
00837         } else
00838         {
00839                 if ( (strncmp(HTTPMethod,"GET",3)!=0) || (!Postdata) || (!*Postdata) ) {
00840                         snprintf(lpBuffer,lpSize-1,"%s %s HTTP/1.%i\r\n",HTTPMethod,url,((PHHANDLE)HTTPHandle)->version);
00841                 } else {
00842                         snprintf(lpBuffer,lpSize-1,"GET %s?%s HTTP/1.%i\r\n",url,Postdata,((PHHANDLE)HTTPHandle)->version);
00843                 }
00844         }
00845         lpSize-=(unsigned int)strlen(lpBuffer);
00846 
00847         if (VHost)      {
00848                 snprintf(tmp,sizeof(tmp)-1,"Host: %s\r\n",VHost);
00849         } else {
00850                 snprintf(tmp,sizeof(tmp)-1,"Host: %s\r\n",((PHHANDLE)HTTPHandle)->targetDNS);
00851         }
00852         AddLine(lpBuffer,tmp,&lpSize);
00853 
00854         if (RealHTTPHandle->UserAgent) {
00855                 AddLine(lpBuffer,RealHTTPHandle->UserAgent,&lpSize);
00856         } else {
00857                 AddLine(lpBuffer,(char*)UserAgent,&lpSize);
00858         }
00859 
00860         if (RealHTTPHandle->AdditionalHeader) {
00861                 AddLine(lpBuffer,RealHTTPHandle->AdditionalHeader,&lpSize);
00862         }
00863         if (RealHTTPHandle->Cookie) {
00864                 sprintf(tmp,"%s\r\n",RealHTTPHandle->Cookie);
00865                 AddLine(lpBuffer,tmp,&lpSize);
00866         }
00867 
00868         if (RealHTTPHandle->ProxyHost) {
00869                 AddLine(lpBuffer,"Proxy-Connection: keep-alive\r\n",&lpSize);
00870         } else {
00871                 AddLine(lpBuffer,"Connection: keep-alive\r\n",&lpSize);
00872         }
00873 
00874 
00875         if  (  (strncmp(HTTPMethod,"GET",3)!=0) && (Postdata) && (*Postdata) )
00876         {
00877                 snprintf(tmp,sizeof(tmp)-1,"Content-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n",strlen(Postdata));
00878                 AddLine(lpBuffer,tmp,&lpSize);
00879         }
00880 
00881 
00882         if ( (AuthMethod) && (lpUsername) && (lpPassword) )
00883         {
00884                 struct _request *tmpdata=NULL;
00885 //        char *tmpdataBuffer;
00886         switch (AuthMethod)
00887         {
00888             case BASIC_AUTH:
00889                             char RawUserPass[750];
00890                             char EncodedUserPass[1000];
00891                             snprintf(RawUserPass,sizeof(RawUserPass),"%s:%s",lpUsername,lpPassword);
00892                             memset(EncodedUserPass,'\0',sizeof(EncodedUserPass));
00893                             Base64Encode((unsigned char *)EncodedUserPass,(unsigned char*)RawUserPass,(int)strlen(RawUserPass));
00894                             snprintf(tmp,sizeof(tmp)-1,"Authorization: Basic %s\r\n",EncodedUserPass);
00895                 AddLine(lpBuffer,tmp,&lpSize);
00896                 break;
00897             case DIGEST_AUTH:
00898                             //Search for cached nonce in memory.
00899                             char *AuthenticationHeader;
00900                             if ( (*RealHTTPHandle->LastRequestedUri) && (strcmp(RealHTTPHandle->LastRequestedUri,url)==0) && (RealHTTPHandle->LastAuthenticationString!=NULL) )
00901                             {
00902                                     //printf("Reusing realm: %s\n",RealHTTPHandle->LastAuthenticationString );
00903                             } else
00904                                 {
00905                                         //Send another request to check if authentication is required and get www-authenticate header
00906                                         char     tmplpBuffer[MAX_POST_LENGHT+1];
00907                                         unsigned int    tmplpSize=lpSize;
00908                                         strncpy(tmplpBuffer,lpBuffer,sizeof(tmplpBuffer)-1);
00909 
00910                                         //Append end of request CLRF
00911                                         strncat(tmplpBuffer,"\r\n",tmplpSize);tmplpSize-=2;
00912 
00913                                         if  (  (strncmp(HTTPMethod,"GET",3)!=0) && (Postdata) )//Add optional POST HEADER
00914                                         {
00915                                                 AddLine(tmplpBuffer,Postdata,&lpSize);
00916                                                 //strncat(tmplpBuffer,Postdata,lpSize);
00917                                         }
00918                                         request=InitHTTPData(tmplpBuffer,NULL);
00919                                         response=DispatchHTTPRequest((PHHANDLE)HTTPHandle,request);
00920                                         tmpdata=ParseReturnedBuffer( HTTPHandle, request,response,url);//, tmpdataBuffer,ReturnedDataSize);
00921                                         if (!tmpdata) return(NULL);
00922 
00923                                         if (tmpdata->status!=401) {
00924                                                 return(tmpdata);
00925                                         }
00926                                         if (RealHTTPHandle->LastAuthenticationString) free(RealHTTPHandle->LastAuthenticationString);
00927                                         RealHTTPHandle->LastAuthenticationString=GetHeaderValue(tmpdata->response->Header,"WWW-Authenticate: Digest ",0);
00928                                 }
00929 
00930                             AuthenticationHeader=CreateDigestAuth(RealHTTPHandle->LastAuthenticationString,lpUsername,lpPassword,HTTPMethod,url,0);
00931                                 if (AuthenticationHeader)
00932                                 {
00933 
00934                                         FreeRequest(tmpdata);
00935                                         tmpdata=NULL;
00936                                         memset(tmp,'\0',sizeof(tmp));
00937                                         strncpy(tmp,AuthenticationHeader,sizeof(tmp)-1); free(AuthenticationHeader);
00938                                         AddLine(lpBuffer,tmp,&lpSize);
00939                                 } else
00940                                 {
00941 #ifdef _DBG_
00942                                         sprintf(tmp,"AUTH DIGEST FAILED Host %s - path: %s, DATA:%s\n",RealHTTPHandle->targetDNS,url,RealHTTPHandle->LastAuthenticationString);
00943                                         printf("%s\n",tmp);
00944 #endif
00945                     if (RealHTTPHandle->LastAuthenticationString) {
00946                         free(RealHTTPHandle->LastAuthenticationString);
00947                         RealHTTPHandle->LastAuthenticationString=NULL;
00948                     }
00949                                         //return(tmpdata);
00950                             }
00951 
00952                 break;
00953             case NTLM_AUTH:
00954             case NEGOTIATE_AUTH:
00955                             unsigned char buf2[4096];
00956                             unsigned char buf1[4096];
00957                             char     tmplpBuffer[MAX_POST_LENGHT+1];
00958                             unsigned int tmplpSize=lpSize;
00959                             strncpy(tmplpBuffer,lpBuffer,sizeof(tmplpBuffer)-1);
00960                 #ifdef _DBG_
00961                                 sprintf(tmp,"path: %s - host: %s\n",url,RealHTTPHandle->targetDNS);
00962                                         printf("DBG: %s\n",tmp);
00963                 #endif
00964                             memset(buf1,'\0',sizeof(buf1));
00965                             memset(buf2,'\0',sizeof(buf2));
00966 
00967                 //NTLM message type 1
00968                             BuildAuthRequest((tSmbNtlmAuthRequest*)buf2,0,NULL,NULL);
00969 
00970                 #ifdef _DBG_
00971                     printf("CLIENT MSG1\n");
00972 //                    DumpMem(buf2,SmbLength((tSmbNtlmAuthResponse*)buf2));
00973                 #endif
00974                             to64frombits(buf1, buf2, SmbLength((tSmbNtlmAuthResponse*)buf2));
00975                             snprintf(tmp,sizeof(tmp)-1,"Authorization: NTLM %s\r\n",buf1);
00976 
00977                             //Append authorization header
00978                             strncat(tmplpBuffer,tmp,tmplpSize);
00979                             tmplpSize-=(unsigned int)strlen(tmp);
00980 
00981                             //Append end of request CLRF
00982                             AddLine(tmplpBuffer,"\r\n",&tmplpSize);
00983 
00984                                 //Add optional POST HEADER
00985                             if  (  (strncmp(HTTPMethod,"GET",3)!=0) && (Postdata) )
00986                             {
00987                                     strncat(tmplpBuffer,Postdata,lpSize);
00988                             }
00989                             //Send Initial Request
00990                 #ifdef _DBG_
00991                                         printf("ENVIANDO: %s\n",tmplpBuffer);
00992                 #endif
00993                                 request=InitHTTPData(tmplpBuffer,NULL);
00994                                 response=DispatchHTTPRequest((PHHANDLE)HTTPHandle,request);
00995                             tmpdata=ParseReturnedBuffer( HTTPHandle, request,response,url);
00996 
00997                             if (!tmpdata)  return(NULL);
00998 
00999                                 if (tmpdata->status==401)
01000                             {
01001                                     //Parse NTLM Message Type 2
01002         //                tmpdata->response
01003                                         char *response=GetHeaderValue(tmpdata->response->Header,"WWW-Authenticate: NTLM ",0);
01004                                         if (!response) {
01005                     #ifdef _DBG_
01006                                                 printf("WWW-Authenticate: NTLM Header not Found\n");
01007                                         #endif
01008                                             strncpy(tmpdata->url,url,sizeof(tmpdata->url)-1);
01009                         //tmpdata->url=_strdup(url);
01010                                             return(tmpdata);
01011                                     }
01012                                     //Build NTLM Message Type 3
01013                     #ifdef _DBG_
01014                                                     printf("Obtenido: !%s!\n",response);
01015                     #endif
01016                                     from64tobits((char *)&buf1[0], response);
01017 
01018                     #ifdef _DBG_
01019                         printf("SERVER MSG2\n");
01020 //                        DumpMem(buf1,0x100);
01021                         dumpAuthChallenge(0,(tSmbNtlmAuthChallenge*)buf1);
01022                     #endif
01023                                     buildAuthResponse((tSmbNtlmAuthChallenge*)buf1,(tSmbNtlmAuthResponse*)buf2,0,lpUsername,lpPassword,NULL,NULL);
01024                     #ifdef _DBG_
01025                         printf("CLIENT MSG3\n");
01026 //                        DumpMem(buf2,SmbLength((tSmbNtlmAuthResponse*)buf2));
01027                     #endif
01028 
01029                                     to64frombits(buf1, buf2, SmbLength((tSmbNtlmAuthResponse*)buf2));
01030                                     snprintf(tmp,sizeof(tmp)-1,"Authorization: NTLM %s\r\n",buf1);
01031                     #ifdef _DBG_
01032                         printf("Enviando: !%s!",tmp);
01033                     #endif
01034                                     free(response);
01035                                         //tmpdata=
01036                                         FreeRequest(tmpdata);
01037                             } else {
01038                                     //strcpy(tmpdata->hostname,((PHHANDLE)HTTPHandle)->hostname);
01039                                         //strncpy(tmpdata->url,url,sizeof(tmpdata->url));
01040                                     return(tmpdata);
01041                                 }
01042                 AddLine(lpBuffer,tmp,&lpSize);
01043                                 break;
01044                         }
01045         }
01046 
01047 
01048 
01049         strncat(lpBuffer,"\r\n",lpSize);
01050         lpSize-=2;
01051 
01052         request=InitHTTPData(lpBuffer,NULL);
01053         //Optional Post Data
01054         if  (  (strncmp(HTTPMethod,"GET",3)!=0) && (Postdata) ) {
01055         free(request->Data);
01056                 request->Data=_strdup(Postdata);
01057                 request->DataSize= (unsigned int) strlen(Postdata);
01058         }
01059 
01060         response=DispatchHTTPRequest(RealHTTPHandle,request);
01061 
01062         DATA=ParseReturnedBuffer(RealHTTPHandle, request, response, url);
01063 
01064 
01065         if ( (!AuthMethod) && (lpUsername) && (lpPassword) && (DATA) && (DATA->challenge))
01066         {
01067                 #ifdef _DBG_
01068                 printf("**********REAUTH**********\n");
01069                 #endif
01070                 struct _request *AUTHDATA=SendHttpRequest(
01071                         HTTPHandle,
01072                         VHost,
01073                         HTTPMethod,
01074                         url,
01075                         Postdata,
01076                         lpUsername,
01077                         lpPassword,
01078                         DATA->challenge);
01079                 if (AUTHDATA)
01080                 {
01081                         FreeRequest(DATA);
01082                         return(AUTHDATA);
01083                 }
01084         }
01085 
01086         /*
01087         if (DATA) {
01088                 if ( (DATA->status==303) && (AutoRedirect303) && (DATA->response) && (DATA->response->HeaderSize) )  {
01089             char *location= GetHeaderValue(DATA->response->Header,"Location: ",1);
01090                         if (location) {
01091                                 if (*location) {
01092                                         char Redirecthost[1000];
01093                                         unsigned int Redirectport;
01094                                         char RedirectURL[1000];
01095                                         int ssl;
01096                                         if ( (Redirectport == RealHTTPHandle->port) && (RealHTTPHandle->NeedSSL == ssl) ) {
01097 
01098                                         }
01099 
01100                                         FreeRequest(DATA);
01101                                         DATA =SendHttpRequest(
01102                                                 HTTPHandle,
01103                                                 Redirecthost,
01104                                                 "GET",
01105                                                 RedirectURL,
01106                                                 NULL,
01107                                                 lpUsername,
01108                                                 lpPassword,
01109                                                 DATA->challenge);
01110                                 }
01111 
01112                                 free(location);
01113                         }
01114 
01115                 }
01116         }
01117 
01118         */
01119  /*
01120         if (DATA->challenge)
01121         {
01122                 if (lpUsername) strncpy(DATA->lpUserName,lpUsername,sizeof(DATA->UserName)-1);
01123                 if (lpPassword) strncpy(DATA->lpPassword,lpPassword,sizeof(DATA->Password)-1);
01124         }
01125 */
01126     return(DATA);
01127 }
01128 /*******************************************************************************************/
01130 
01136 /*******************************************************************************************/
01137 int CancelHttpRequest(HTTPHANDLE HTTPHandle, int what)
01138 {
01139         return ( HTTPCoreCancelHTTPRequest(HTTPHandle, what));
01140 }
01141 /*******************************************************************************************/

Generated on Sun Jan 18 00:32:04 2009 for Fast HTTP Vulnerability Scanner by  doxygen 1.5.4