Ejemplo n.º 1
0
/*
 * Build the dpip command tag, according to URL and server.
 */
static char *Capi_dpi_build_cmd(DilloWeb *web, char *server)
{
   char *cmd;

   if (strcmp(server, "proto.https") == 0) {
      /* Let's be kind and make the HTTP query string for the dpi */
      char *proxy_connect = a_Http_make_connect_str(web->url);
      Dstr *http_query = a_Http_make_query_str(web->url, FALSE);
      /* BUG: embedded NULLs in query data will truncate message */
      if (proxy_connect) {
         const char *proxy_urlstr = a_Http_get_proxy_urlstr();
         cmd = a_Dpip_build_cmd("cmd=%s proxy_url=%s proxy_connect=%s "
                                "url=%s query=%s", "open_url", proxy_urlstr,
                                proxy_connect, URL_STR(web->url),
                                http_query->str);
      } else {
         cmd = a_Dpip_build_cmd("cmd=%s url=%s query=%s",
                                "open_url", URL_STR(web->url),http_query->str);
      }
      dFree(proxy_connect);
      dStr_free(http_query, 1);

   } else if (strcmp(server, "downloads") == 0) {
      /* let the downloads server get it */
      cmd = a_Dpip_build_cmd("cmd=%s url=%s destination=%s",
                             "download", URL_STR(web->url), web->filename);

   } else {
      /* For everyone else, the url string is enough... */
      cmd = a_Dpip_build_cmd("cmd=%s url=%s", "open_url", URL_STR(web->url));
   }
   return cmd;
}
Ejemplo n.º 2
0
/*
 * Test proxy settings and check the no_proxy domains list
 * Return value: whether to use proxy or not.
 */
static int Http_must_use_proxy(const DilloUrl *url)
{
   char *np, *p, *tok;
   int ret = 0;

   if (HTTP_Proxy) {
      ret = 1;
      if (prefs.no_proxy) {
         const char *host = URL_HOST(url);
         size_t host_len = strlen(host);

         np = dStrdup(prefs.no_proxy);
         for (p = np; (tok = dStrsep(&p, " "));  ) {
            int start = host_len - strlen(tok);

            if (start >= 0 && dStrAsciiCasecmp(host + start, tok) == 0) {
               /* no_proxy token is suffix of host string */
               ret = 0;
               break;
            }
         }
         dFree(np);
      }
   }
   _MSG("Http_must_use_proxy: %s\n  %s\n", URL_STR(url), ret ? "YES":"NO");
   return ret;
}
Ejemplo n.º 3
0
/*
 * If the url belongs to a dpi server, return its name.
 */
static int Capi_url_uses_dpi(DilloUrl *url, char **server_ptr)
{
   char *p, *server = NULL, *url_str = URL_STR(url);
   Dstr *tmp;

   if ((dStrncasecmp(url_str, "http:", 5) == 0) ||
       (dStrncasecmp(url_str, "about:", 6) == 0)) {
      /* URL doesn't use dpi (server = NULL) */
   } else if (dStrncasecmp(url_str, "dpi:/", 5) == 0) {
      /* dpi prefix, get this server's name */
      if ((p = strchr(url_str + 5, '/')) != NULL) {
         server = dStrndup(url_str + 5, (uint_t)(p - url_str - 5));
      } else {
         server = dStrdup("?");
      }
      if (strcmp(server, "bm") == 0) {
         dFree(server);
         server = dStrdup("bookmarks");
      }
   } else if ((p = strchr(url_str, ':')) != NULL) {
      tmp = dStr_new("proto.");
      dStr_append_l(tmp, url_str, p - url_str);
      server = tmp->str;
      dStr_free(tmp, 0);
   }

   return ((*server_ptr = server) ? 1 : 0);
}
Ejemplo n.º 4
0
/*
 * Safety test: only allow GET|POST dpi-urls from dpi-generated pages.
 */
int a_Capi_dpi_verify_request(BrowserWindow *bw, DilloUrl *url)
{
   DilloUrl *referer;
   int allow = FALSE;

   /* test POST and GET */
   if (dStrcasecmp(URL_SCHEME(url), "dpi") == 0 &&
       URL_FLAGS(url) & (URL_Post + URL_Get)) {
      /* only allow dpi requests from dpi-generated urls */
      if (a_Nav_stack_size(bw)) {
         referer = a_History_get_url(NAV_TOP_UIDX(bw));
         if (dStrcasecmp(URL_SCHEME(referer), "dpi") == 0) {
            allow = TRUE;
         }
      }
   } else {
      allow = TRUE;
   }

   if (!allow) {
      MSG("a_Capi_dpi_verify_request: Permission Denied!\n");
      MSG("  URL_STR : %s\n", URL_STR(url));
      if (URL_FLAGS(url) & URL_Post) {
         MSG("  URL_DATA: %s\n", dStr_printable(URL_DATA(url), 1024));
      }
   }
   return allow;
}
Ejemplo n.º 5
0
/*
 * Let the client know that we're not following a redirection.
 */
static void Cache_provide_redirection_blocked_page(CacheEntry_t *entry,
                                                   CacheClient_t *client)
{
   DilloWeb *clientWeb = client->Web;

   a_Web_dispatch_by_type("text/html", clientWeb, &client->Callback,
                          &client->CbData);
   client->Buf = dStrconcat("<!doctype html><html><body>"
                    "Dillo blocked a redirection from <a href=\"",
                    URL_STR(entry->Url), "\">", URL_STR(entry->Url),
                    "</a> to <a href=\"", URL_STR(entry->Location), "\">",
                    URL_STR(entry->Location), "</a> based on your domainrc "
                    "settings.</body></html>", NULL);
   client->BufSize = strlen(client->Buf);
   (client->Callback)(CA_Send, client);
   dFree(client->Buf);
}
Ejemplo n.º 6
0
/* this is the routine called by libjpeg when it detects an error. */
METHODDEF(void) Jpeg_errorexit (j_common_ptr cinfo)
{
   /* display message and return to setjmp buffer */
   my_error_ptr myerr = (my_error_ptr) cinfo->err;
   if (prefs.show_msg) {
      DilloJpeg *jpeg =
                     ((my_source_mgr *) ((j_decompress_ptr) cinfo)->src)->jpeg;
      MSG_WARN("\"%s\": ", URL_STR(jpeg->url));
      (*cinfo->err->output_message) (cinfo);
   }
   longjmp(myerr->setjmp_buffer, 1);
}
Ejemplo n.º 7
0
Archivo: auth.c Proyecto: epitron/dillo
/*
 * Determine whether the user needs to authenticate.
 */
static int Auth_do_auth_required(const AuthParse_t *auth_parse,
                                 const DilloUrl *url)
{
   /*
    * TO DO: I dislike the way that this code must decide whether we
    * sent authentication during the request and trust us to resend it
    * after the reload.  Could it be more robust if every DilloUrl
    * recorded its authentication, and whether it was accepted?  (JCH)
    */

   AuthHost_t *host;
   AuthRealm_t *realm;

   /*
    * The size of the following comments reflects the concerns in the
    * TO DO at the top of this function.  It should not be so hard to
    * explain why code is correct! (JCH)
    */

   /*
    * If we have authentication but did not send it (because we did
    * not know this path was in the realm) then we update the realm.
    * We do not re-authenticate because our authentication is probably
    * OK.  Thanks to the updated realm the forthcoming reload will
    * make us send the authentication.  If our authentication is not
    * OK the server will challenge us again after the reload and then
    * we will re-authenticate.
    */
   if ((host = Auth_host_by_url(url)) &&
       (realm = Auth_realm_by_name(host, auth_parse->realm))) {
      if (!Auth_realm_includes_path(realm, URL_PATH(url))) {
         _MSG("Auth_do_auth_required: updating realm '%s' with URL '%s'\n",
              auth_parse->realm, URL_STR(url));
         Auth_realm_add_path(realm, URL_PATH(url));
         return 0;
      }

      if (auth_parse->type == DIGEST && auth_parse->stale) {
         /* we do have valid credentials but our nonce is old */
         dFree((void *)realm->nonce);
         realm->nonce = dStrdup(auth_parse->nonce);
         return 0;
      }
   }

   /*
    * Either we had no authentication or we sent it and the server
    * rejected it, so we must re-authenticate.
    */
   return 1;
}
Ejemplo n.º 8
0
/*
 * Change Content-Type for cache entry found by url.
 * from = { "http" | "meta" }
 * Return new content type.
 */
const char *a_Cache_set_content_type(const DilloUrl *url, const char *ctype,
                                     const char *from)
{
   const char *curr;
   char *major, *minor, *charset;
   CacheEntry_t *entry = Cache_entry_search(url);

   dReturn_val_if_fail (entry != NULL, NULL);

   _MSG("a_Cache_set_content_type {%s} {%s}\n", ctype, URL_STR(url));

   curr = Cache_current_content_type(entry);
   if  (entry->TypeMeta || (*from == 'h' && entry->TypeHdr) ) {
      /* Type is already been set. Do nothing.
       * BTW, META overrides TypeHdr */
   } else {
      if (*from == 'h') {
         /* Content-Type from HTTP header */
         entry->TypeHdr = dStrdup(ctype);
      } else {
         /* Content-Type from META */
         entry->TypeMeta = dStrdup(ctype);
      }
      if (a_Misc_content_type_cmp(curr, ctype)) {
         /* ctype gives one different from current */
         a_Misc_parse_content_type(ctype, &major, &minor, &charset);
         if (*from == 'm' && charset &&
             ((!major || !*major) && (!minor || !*minor))) {
            /* META only gives charset; use detected MIME type too */
            entry->TypeNorm = dStrconcat(entry->TypeDet, ctype, NULL);
         } else if (*from == 'm' &&
                    !dStrnAsciiCasecmp(ctype, "text/xhtml", 10)) {
            /* WORKAROUND: doxygen uses "text/xhtml" in META */
            entry->TypeNorm = dStrdup(entry->TypeDet);
         }
         if (charset) {
            if (entry->CharsetDecoder)
               a_Decode_free(entry->CharsetDecoder);
            entry->CharsetDecoder = a_Decode_charset_init(charset);
            curr = Cache_current_content_type(entry);

            /* Invalidate UTF8Data */
            dStr_free(entry->UTF8Data, 1);
            entry->UTF8Data = NULL;
         }
         dFree(major); dFree(minor); dFree(charset);
      }
   }
   return curr;
}
Ejemplo n.º 9
0
Archivo: web.c Proyecto: dimkr/dillo
/*
 * Given the MIME content type, and a fd to read it from,
 * this function connects the proper MIME viewer to it.
 * Return value: 1 on success, -1 for unhandled MIME types
 */
gint a_Web_dispatch_by_type (const char *Type, DilloWeb *Web,
                             CA_Callback_t *Call, void **Data)
{
   DwWidget *dw = NULL;
   DwStyle style_attrs, *style;
   DwStyleFont font;

   DEBUG_MSG(1, "a_Web_dispatch_by_type\n");

   g_return_val_if_fail(Web->bw != NULL, -1);

   if (Web->flags & WEB_RootUrl) {
      /* We have RootUrl! */
      dw = a_Mime_set_viewer(Type, Web, Call, Data);
      if (dw == NULL)
         return -1;

      /* Set a style for the widget */
      font.name = prefs.vw_fontname; /* must be defined */
      font.size = rint(12.0 * prefs.font_factor);
      font.weight = 400;
      font.style = DW_STYLE_FONT_STYLE_NORMAL;

      a_Dw_style_init_values (&style_attrs, Web->bw->main_window->window);
      a_Dw_style_box_set_val (&style_attrs.margin, 5);
      style_attrs.font = a_Dw_style_font_new (&font);
      style_attrs.color =
         a_Dw_style_color_new (prefs.text_color, Web->bw->main_window->window);
      style_attrs.background_color =
         a_Dw_style_color_new (prefs.bg_color, Web->bw->main_window->window);
      style = a_Dw_style_new (&style_attrs, Web->bw->main_window->window);
      a_Dw_widget_set_style (dw, style);
      a_Dw_style_unref (style);

      a_Dw_gtk_scrolled_window_set_dw(
         GTK_DW_SCROLLED_WINDOW(Web->bw->docwin), dw);

      if (URL_POSX(Web->url) || URL_POSY(Web->url)) {
        a_Dw_gtk_scrolled_window_set_scrolling_position(
           GTK_DW_SCROLLED_WINDOW(Web->bw->docwin),
           URL_POSX(Web->url), URL_POSY(Web->url));
      } else {
        gchar *pf = a_Url_decode_hex_str(URL_FRAGMENT_(Web->url));
        a_Dw_gtk_scrolled_window_set_anchor(
           GTK_DW_SCROLLED_WINDOW(Web->bw->docwin), pf);
        g_free(pf);
      }

      /* Clear the title bar for pages without a <TITLE> tag */
      a_Interface_set_page_title(Web->bw, "");
      a_Interface_set_location_text(Web->bw, URL_STR(Web->url));
      a_Interface_reset_progress_bars(Web->bw);
      /* Reset the bug meter */
      a_Interface_bug_meter_update(Web->bw, 0);

      /* Let the Nav module know... */
      a_Nav_expect_done(Web->bw);

   } else {
      /* A non-RootUrl. At this moment we only handle image-children */
      if (!g_strncasecmp(Type, "image/", 6))
         dw = a_Mime_set_viewer(Type, Web, Call, Data);
   }

   if (!dw) {
      MSG_HTTP("unhandled MIME type: \"%s\"\n", Type);
   }
   return (dw ? 1 : -1);
}
Ejemplo n.º 10
0
/*
 * Return URL string of HTTP proxy, if any
 */
const char *a_Http_get_proxy_urlstr()
{
   return HTTP_Proxy ? URL_STR(HTTP_Proxy) : NULL;
}
Ejemplo n.º 11
0
/*
 * Make the http query string
 */
Dstr *a_Http_make_query_str(const DilloUrl *url, const DilloUrl *requester,
                            bool_t use_proxy)
{
   char *ptr, *cookies, *referer, *auth;
   Dstr *query      = dStr_new(""),
        *request_uri = dStr_new(""),
        *proxy_auth = dStr_new("");

   if (use_proxy) {
      dStr_sprintfa(request_uri, "%s%s",
                    URL_STR(url),
                    (URL_PATH_(url) || URL_QUERY_(url)) ? "" : "/");
      if ((ptr = strrchr(request_uri->str, '#')))
         dStr_truncate(request_uri, ptr - request_uri->str);
      if (HTTP_Proxy_Auth_base64)
         dStr_sprintf(proxy_auth, "Proxy-Authorization: Basic %s\r\n",
                      HTTP_Proxy_Auth_base64);
   } else {
      dStr_sprintfa(request_uri, "%s%s%s%s",
                    URL_PATH(url),
                    URL_QUERY_(url) ? "?" : "",
                    URL_QUERY(url),
                    (URL_PATH_(url) || URL_QUERY_(url)) ? "" : "/");
   }

   cookies = a_Cookies_get_query(url, requester);
   auth = a_Auth_get_auth_str(url, request_uri->str);
   referer = Http_get_referer(url);
   if (URL_FLAGS(url) & URL_Post) {
      Dstr *content_type = Http_make_content_type(url);
      dStr_sprintfa(
         query,
         "POST %s HTTP/1.1\r\n"
         "Connection: close\r\n"
         "Accept: text/*,image/*,*/*;q=0.2\r\n"
         "Accept-Charset: utf-8,*;q=0.8\r\n"
         "Accept-Encoding: gzip\r\n"
         "%s" /* language */
         "%s" /* auth */
         "Host: %s\r\n"
         "%s"
         "%s"
         "User-Agent: %s\r\n"
         "Content-Length: %ld\r\n"
         "Content-Type: %s\r\n"
         "%s" /* cookies */
         "\r\n",
         request_uri->str, HTTP_Language_hdr, auth ? auth : "",
         URL_AUTHORITY(url), proxy_auth->str, referer, prefs.http_user_agent,
         (long)URL_DATA(url)->len, content_type->str,
         cookies);
      dStr_append_l(query, URL_DATA(url)->str, URL_DATA(url)->len);
      dStr_free(content_type, TRUE);
   } else {
      dStr_sprintfa(
         query,
         "GET %s HTTP/1.1\r\n"
         "%s"
         "Connection: close\r\n"
         "Accept: text/*,image/*,*/*;q=0.2\r\n"
         "Accept-Charset: utf-8,*;q=0.8\r\n"
         "Accept-Encoding: gzip\r\n"
         "%s" /* language */
         "%s" /* auth */
         "Host: %s\r\n"
         "%s"
         "%s"
         "User-Agent: %s\r\n"
         "%s" /* cookies */
         "\r\n",
         request_uri->str,
         (URL_FLAGS(url) & URL_E2EQuery) ?
            "Cache-Control: no-cache\r\nPragma: no-cache\r\n" : "",
         HTTP_Language_hdr, auth ? auth : "", URL_AUTHORITY(url),
         proxy_auth->str, referer, prefs.http_user_agent, cookies);
   }
   dFree(referer);
   dFree(cookies);
   dFree(auth);

   dStr_free(request_uri, TRUE);
   dStr_free(proxy_auth, TRUE);
   _MSG("Query: {%s}\n", dStr_printable(query, 8192));
   return query;
}
Ejemplo n.º 12
0
/*
 * Scan, allocate, and set things according to header info.
 * (This function needs the whole header to work)
 */
static void Cache_parse_header(CacheEntry_t *entry)
{
   char *header = entry->Header->str;
   char *Length, *Type, *location_str, *encoding;
#ifndef DISABLE_COOKIES
   Dlist *Cookies;
#endif
   Dlist *warnings;
   void *data;
   int i;

   _MSG("Cache_parse_header\n");

   if (entry->Header->len > 12) {
      if (header[9] == '1' && header[10] == '0' && header[11] == '0') {
         /* 100: Continue. The "real" header has not come yet. */
         MSG("An actual 100 Continue header!\n");
         entry->Flags &= ~CA_GotHeader;
         dStr_free(entry->Header, 1);
         entry->Header = dStr_new("");
         return;
      }
      if (header[9] == '3' && header[10] == '0' &&
          (location_str = Cache_parse_field(header, "Location"))) {
         /* 30x: URL redirection */
         DilloUrl *location_url = a_Url_new(location_str,URL_STR_(entry->Url));

         if (prefs.filter_auto_requests == PREFS_FILTER_SAME_DOMAIN &&
             !a_Url_same_organization(entry->Url, location_url)) {
            /* don't redirect; just show body like usual (if any) */
            MSG("Redirection not followed from %s to %s\n",
                URL_HOST(entry->Url), URL_STR(location_url));
            a_Url_free(location_url);
         } else {
            entry->Flags |= CA_Redirect;
            if (header[11] == '1')
               entry->Flags |= CA_ForceRedirect;  /* 301 Moved Permanently */
            else if (header[11] == '2')
               entry->Flags |= CA_TempRedirect;   /* 302 Temporary Redirect */

            if (URL_FLAGS(location_url) & (URL_Post + URL_Get) &&
                dStrAsciiCasecmp(URL_SCHEME(location_url), "dpi") == 0 &&
                dStrAsciiCasecmp(URL_SCHEME(entry->Url), "dpi") != 0) {
               /* Forbid dpi GET and POST from non dpi-generated urls */
               MSG("Redirection Denied! '%s' -> '%s'\n",
                   URL_STR(entry->Url), URL_STR(location_url));
               a_Url_free(location_url);
            } else {
               entry->Location = location_url;
            }
         }
         dFree(location_str);
      } else if (strncmp(header + 9, "401", 3) == 0) {
         entry->Auth =
            Cache_parse_multiple_fields(header, "WWW-Authenticate");
      } else if (strncmp(header + 9, "404", 3) == 0) {
         entry->Flags |= CA_NotFound;
      }
   }

   if ((warnings = Cache_parse_multiple_fields(header, "Warning"))) {
      for (i = 0; (data = dList_nth_data(warnings, i)); ++i) {
         MSG_HTTP("%s\n", (char *)data);
         dFree(data);
      }
      dList_free(warnings);
   }

   /*
    * Get Transfer-Encoding and initialize decoder
    */
   encoding = Cache_parse_field(header, "Transfer-Encoding");
   entry->TransferDecoder = a_Decode_transfer_init(encoding);


   if ((Length = Cache_parse_field(header, "Content-Length")) != NULL) {
      if (encoding) {
         /*
          * If Transfer-Encoding is present, Content-Length must be ignored.
          * If the Transfer-Encoding is non-identity, it is an error.
          */
         if (dStrAsciiCasecmp(encoding, "identity"))
            MSG_HTTP("Content-Length and non-identity Transfer-Encoding "
                     "headers both present.\n");
      } else {
         entry->Flags |= CA_GotLength;
         entry->ExpectedSize = MAX(strtol(Length, NULL, 10), 0);
      }
      dFree(Length);
   }

   dFree(encoding); /* free Transfer-Encoding */

#ifndef DISABLE_COOKIES
   if ((Cookies = Cache_parse_multiple_fields(header, "Set-Cookie"))) {
      CacheClient_t *client;

      for (i = 0; (client = dList_nth_data(ClientQueue, i)); ++i) {
         if (client->Url == entry->Url) {
            DilloWeb *web = client->Web;

            if (!web->requester ||
                a_Url_same_organization(entry->Url, web->requester)) {
               char *server_date = Cache_parse_field(header, "Date");

               a_Cookies_set(Cookies, entry->Url, server_date);
               dFree(server_date);
               break;
            }
         }
      }
      if (i >= dList_length(ClientQueue)) {
         MSG("Cache: cookies not accepted from '%s'\n", URL_STR(entry->Url));
      }

      for (i = 0; (data = dList_nth_data(Cookies, i)); ++i)
         dFree(data);
      dList_free(Cookies);
   }
#endif /* !DISABLE_COOKIES */

   /*
    * Get Content-Encoding and initialize decoder
    */
   encoding = Cache_parse_field(header, "Content-Encoding");
   entry->ContentDecoder = a_Decode_content_init(encoding);
   dFree(encoding);

   if (entry->ExpectedSize > 0) {
      if (entry->ExpectedSize > HUGE_FILESIZE) {
         entry->Flags |= CA_HugeFile;
      }
      /* Avoid some reallocs. With MAX_INIT_BUF we avoid a SEGFAULT
       * with huge files (e.g. iso files).
       * Note: the buffer grows automatically. */
      dStr_free(entry->Data, 1);
      entry->Data = dStr_sized_new(MIN(entry->ExpectedSize, MAX_INIT_BUF));
   }

   /* Get Content-Type */
   if ((Type = Cache_parse_field(header, "Content-Type"))) {
      /* This HTTP Content-Type is not trusted. It's checked against real data
       * in Cache_process_queue(); only then CA_GotContentType becomes true. */
      a_Cache_set_content_type(entry->Url, Type, "http");
      _MSG("TypeHdr  {%s} {%s}\n", Type, URL_STR(entry->Url));
      _MSG("TypeMeta {%s}\n", entry->TypeMeta);
      dFree(Type);
   }
   Cache_ref_data(entry);
}