* configure.ac: Add --disable-endian-check for building fat binaries
[gnupg.git] / util / http.c
index 125f68c..b5dc682 100644 (file)
@@ -1,5 +1,6 @@
 /* http.c  -  HTTP protocol handler
- * Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 1999, 2001, 2002, 2003, 2004,
+ *               2005 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -69,7 +70,7 @@ static int remove_escapes( byte *string );
 static int insert_escapes( byte *buffer, const byte *string,
                                         const byte *special );
 static URI_TUPLE parse_tuple( byte *string );
-static int send_request( HTTP_HD hd, const char *proxy );
+static int send_request( HTTP_HD hd, const char *auth, const char *proxy );
 static byte *build_rel_path( PARSED_URI uri );
 static int parse_response( HTTP_HD hd );
 
@@ -117,14 +118,14 @@ static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  * create a radix64 encoded string.
  */
 
-/* TODO: This is a duplicate of code in g10/armor.c.  Better to use a
-   single copy in strgutil.c */
+/* TODO: This is a duplicate of code in g10/armor.c modified to do the
+   "=" padding.  Better to use a single copy in strgutil.c ? */
 static char *
 make_radix64_string( const byte *data, size_t len )
 {
     char *buffer, *p;
 
-    buffer = p = m_alloc( (len+2)/3*4 + 1 );
+    buffer = p = xmalloc( (len+2)/3*4 + 1 );
     for( ; len >= 3 ; len -= 3, data += 3 ) {
        *p++ = bintoasc[(data[0] >> 2) & 077];
        *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
@@ -135,10 +136,13 @@ make_radix64_string( const byte *data, size_t len )
        *p++ = bintoasc[(data[0] >> 2) & 077];
        *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
        *p++ = bintoasc[((data[1]<<2)&074)];
+       *p++ = '=';
     }
     else if( len == 1 ) {
        *p++ = bintoasc[(data[0] >> 2) & 077];
        *p++ = bintoasc[(data[0] <<4)&060];
+       *p++ = '=';
+       *p++ = '=';
     }
     *p = 0;
     return buffer;
@@ -146,7 +150,7 @@ make_radix64_string( const byte *data, size_t len )
 
 int
 http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
-          unsigned int flags, const char *proxy )
+          char *auth, unsigned int flags, const char *proxy )
 {
     int rc;
 
@@ -162,7 +166,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
 
     rc = parse_uri( &hd->uri, url );
     if( !rc ) {
-       rc = send_request( hd, proxy );
+       rc = send_request( hd, auth, proxy );
        if( !rc ) {
            hd->fp_write = iobuf_sockopen( hd->sock , "w" );
            if( hd->fp_write )
@@ -225,12 +229,12 @@ http_wait_response( HTTP_HD hd, unsigned int *ret_status )
 
 
 int
-http_open_document( HTTP_HD hd, const char *document,
+http_open_document( HTTP_HD hd, const char *document, char *auth,
                    unsigned int flags, const char *proxy )
 {
     int rc;
 
-    rc = http_open( hd, HTTP_REQ_GET, document, flags, proxy );
+    rc = http_open(hd, HTTP_REQ_GET, document, auth, flags, proxy );
     if( rc )
        return rc;
 
@@ -252,7 +256,7 @@ http_close( HTTP_HD hd )
     iobuf_close( hd->fp_read );
     iobuf_close( hd->fp_write );
     release_parsed_uri( hd->uri );
-    m_free( hd->buffer );
+    xfree( hd->buffer );
     hd->initialized = 0;
 }
 
@@ -266,7 +270,7 @@ http_close( HTTP_HD hd )
 static int
 parse_uri( PARSED_URI *ret_uri, const char *uri )
 {
-   *ret_uri = m_alloc_clear( sizeof(**ret_uri) + strlen(uri) );
+   *ret_uri = xmalloc_clear( sizeof(**ret_uri) + strlen(uri) );
    strcpy( (*ret_uri)->buffer, uri );
    return do_parse_uri( *ret_uri, 0 );
 }
@@ -280,9 +284,9 @@ release_parsed_uri( PARSED_URI uri )
 
        for( r = uri->query; r; r = r2 ) {
            r2 = r->next;
-           m_free( r );
+           xfree( r );
        }
-       m_free( uri );
+       xfree( uri );
     }
 }
 
@@ -479,7 +483,7 @@ parse_tuple( byte *string )
        return NULL; /* bad URI */
     if( n != strlen( p ) )
        return NULL; /* name with a Nul in it */
-    tuple = m_alloc_clear( sizeof *tuple );
+    tuple = xmalloc_clear( sizeof *tuple );
     tuple->name = p;
     if( !p2 )  {
        /* we have only the name, so we assume an empty value string */
@@ -488,7 +492,7 @@ parse_tuple( byte *string )
     }
     else { /* name and value */
        if( (n = remove_escapes( p2 )) < 0 ) {
-           m_free( tuple );
+           xfree( tuple );
            return NULL; /* bad URI */
        }
        tuple->value = p2;
@@ -503,18 +507,18 @@ parse_tuple( byte *string )
  * Returns 0 if the request was successful
  */
 static int
-send_request( HTTP_HD hd, const char *proxy )
+send_request( HTTP_HD hd, const char *auth, const char *proxy )
 {
     const byte *server;
     byte *request, *p;
     ushort port;
     int rc;
-    char *auth=NULL;
+    char *proxy_authstr=NULL,*authstr=NULL;
 
     server = *hd->uri->host? hd->uri->host : "localhost";
     port   = hd->uri->port?  hd->uri->port : 80;
 
-    if(proxy)
+    if(proxy && *proxy)
       {
        PARSED_URI uri;
 
@@ -529,24 +533,37 @@ send_request( HTTP_HD hd, const char *proxy )
                                   uri->port? uri->port : 80, 0, NULL );
        if(uri->auth)
          {
-           char *x=make_radix64_string(uri->auth,strlen(uri->auth));
-           auth=m_alloc(52+strlen(x));
-           sprintf(auth,"Proxy-Authorization: Basic %s==\r\n",x);
-           m_free(x);
+           char *x;
+           remove_escapes(uri->auth);
+           x=make_radix64_string(uri->auth,strlen(uri->auth));
+           proxy_authstr=xmalloc(52+strlen(x));
+           sprintf(proxy_authstr,"Proxy-Authorization: Basic %s\r\n",x);
+           xfree(x);
          }
 
        release_parsed_uri( uri );
       }
     else
+      hd->sock = connect_server( server, port, hd->flags, hd->uri->scheme );
+
+    if(auth || hd->uri->auth)
       {
-       hd->sock = connect_server( server, port, hd->flags, hd->uri->scheme );
-       if(hd->uri->auth)
+       char *x,*tempauth=NULL;
+
+       if(auth)
          {
-           char *x=make_radix64_string(hd->uri->auth,strlen(hd->uri->auth));
-           auth=m_alloc(52+strlen(x));
-           sprintf(auth,"Authorization: Basic %s==\r\n",x);
-           m_free(x);
+           tempauth=xstrdup(auth);
+           remove_escapes(tempauth);
          }
+       else if(hd->uri->auth)
+         remove_escapes(hd->uri->auth);
+
+       x=make_radix64_string(tempauth?tempauth:hd->uri->auth,
+                             strlen(tempauth?tempauth:hd->uri->auth));
+       authstr=xmalloc(52+strlen(x));
+       sprintf(authstr,"Authorization: Basic %s\r\n",x);
+       xfree(x);
+       xfree(tempauth);
       }
 
     if( hd->sock == -1 )
@@ -554,13 +571,16 @@ send_request( HTTP_HD hd, const char *proxy )
 
     p = build_rel_path( hd->uri );
 
-    request=m_alloc(strlen(server)*2 + strlen(p) + (auth?strlen(auth):0) + 65);
+    request=xmalloc(strlen(server)*2 + strlen(p)
+                   + (authstr?strlen(authstr):0)
+                   + (proxy_authstr?strlen(proxy_authstr):0) + 65);
     if( proxy )
-      sprintf( request, "%s http://%s:%hu%s%s HTTP/1.0\r\n%s",
+      sprintf( request, "%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s",
               hd->req_type == HTTP_REQ_GET ? "GET" :
               hd->req_type == HTTP_REQ_HEAD? "HEAD":
               hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
-              server, port,  *p == '/'? "":"/", p, auth?auth:"" );
+              server, port,  *p == '/'? "":"/", p,
+              authstr?authstr:"",proxy_authstr?proxy_authstr:"" );
     else
       {
        char portstr[15];
@@ -573,14 +593,15 @@ send_request( HTTP_HD hd, const char *proxy )
                 hd->req_type == HTTP_REQ_HEAD? "HEAD":
                 hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
                 *p == '/'? "":"/", p, server, (port!=80)?portstr:"",
-                auth?auth:"");
+                authstr?authstr:"");
       }
 
-    m_free(p);
+    xfree(p);
 
     rc = write_server( hd->sock, request, strlen(request) );
-    m_free( request );
-    m_free(auth);
+    xfree( request );
+    xfree(proxy_authstr);
+    xfree(authstr);
 
     return rc;
 }
@@ -609,7 +630,7 @@ build_rel_path( PARSED_URI uri )
     n++;
 
     /* now  allocate and copy */
-    p = rel_path = m_alloc( n );
+    p = rel_path = xmalloc( n );
     n = insert_escapes( p, uri->path, "%;?&" );
     p += n;
     /* todo: add params */
@@ -824,7 +845,7 @@ connect_server( const char *server, ushort port, unsigned int flags,
     {
       /* Either we're not using SRV, or the SRV lookup failed.  Make
         up a fake SRV record. */
-      srvlist=m_alloc_clear(sizeof(struct srventry));
+      srvlist=xmalloc_clear(sizeof(struct srventry));
       srvlist->port=port;
       strncpy(srvlist->target,server,MAXDNAME);
       srvlist->target[MAXDNAME-1]='\0';
@@ -927,7 +948,7 @@ connect_server( const char *server, ushort port, unsigned int flags,
     }
 #endif /* !HAVE_GETADDRINFO */
 
-  m_free(srvlist);
+  xfree(srvlist);
 
   if(!connected)
     {