/*
 * Dpi for HTTPS.
 *
 * THIS IS A PROTOTYPE to illustrate how it is done. Feel free to polish!
 *
 *
 *                            W A R N I N G
 *
 * Maybe the more important thing yet to be discussed is about whether
 * unix domain sockets (UDS) are secure for https. I mean, root can always
 * snoop on sockets (regardless of permissions) so he'd be able to "see" all
 * the traffic. OTOH, if someone has root access on a machine he can do
 * anything, and that includes modifying the binaries or peeking-up in 
 * memory space...
 *
 *
 * Copyright 2003 Jorge Arellano Cid <jcid@dillo.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 */

/*
 * TODO: a lot of things, this is just a bare bones example.
 *
 * For instance:
 * - Handle cookies (requires cookies to be made a dpi first)
 * - Certificate authentication (asking the user in case it can't be verified)
 * - ...
 *
 */

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/time.h>
#include <glib.h>

#define BUFLEN 256
#define TOUT 300

/*---------------------------------------------------------------------------*/

/*
 * Task: given a tag and an attribute name, return its value.
 *       (character stuffing is removed here)
 * Return value: the attribute value, or NULL if not present or malformed.
 * (copied from bookmarks.c)
 */          
char *Get_attr_value(char *tag, int tagsize, char *attrname)
{            
   char *p, *q, *ltag, quote, *start, *val = NULL;

   ltag = g_strndup(tag, tagsize);
   if ((p = strstr(ltag, attrname)) &&
       (p = strchr(p, '=')) &&
       (p = strpbrk(p, "'\"")) ) {
      quote = *p;                 
      start = ++p;
      while ((q = strchr(p, quote)) && q[1] == quote)
         p = q + 2;
      if (q) {
         val = g_strndup(start, q - start);
         for (p = q = val; (*q = *p); ++p, ++q)
            if ((*p == '"' || *p == '\'') && p[1] == p[0])
               ++p;
      }
   }         
   g_free(ltag);

   return val;
}


/*---------------------------------------------------------------------------*/

/*
 * Build a shell command using wget for this URL.
 */
gchar *make_wget_cmd(gchar *url)
{
   return g_strdup_printf("wget -O - '%s' 2>/dev/null", url);
}

/*
 * Send the stream with coarse buffering (fastest)
 * Return value: 1: data sent,  0: nothing sent
 */
gint send_stream_3(FILE *in_stream, gchar *url)
{
   gint header = 0;
   gchar buf[4096];
   size_t n;

   while ((n = fread (buf, 1, 4096, in_stream)) > 0) {
      if (n > 0 && !header) {
         printf("<dpi cmd='start_send_page' url='%s'>", url);
      // printf("Content-type: text/html\n\n");
         printf("\n\n");
         header = 1;
      }
      fwrite(buf, 1, n, stdout);
      //fwrite(buf, 1, n, stderr);
   }

   return header;
}

/*
 *
 */
int main(void)
{
   FILE *F_stdin, *in_stream;
   gchar *dpip_tag = NULL, *cmd = NULL, *url = NULL, *wget_cmd = NULL;
   gint i, rd_len, ret;
   gchar buf[4096];

   /* Read the dpi command from STDIN */
   F_stdin = fdopen (STDIN_FILENO, "r");
   rd_len = read(STDIN_FILENO, buf, 4096);
   dpip_tag = g_strndup(buf, rd_len);
   fclose(F_stdin);
// close(STDIN_FILENO); /* Necessary? */
// g_printerr("[%s]\n", dpip_tag);

   cmd = Get_attr_value(dpip_tag, strlen(dpip_tag), "cmd");
   url = Get_attr_value(dpip_tag, strlen(dpip_tag), "url");
   if (cmd && url) {
      wget_cmd = make_wget_cmd(url);
   }
   g_printerr("[%s]\n", wget_cmd);


   /* Fork, exec command, get its output and answer back */
   if ((in_stream = popen(wget_cmd, "r")) == NULL) {
      perror("popen");
      return EXIT_FAILURE;
   }

   /* Read/Write */
   i = send_stream_3(in_stream, url);

   if ((ret = pclose(in_stream)) != 0)
      g_printerr("popen: [%d]\n", ret);

   if (i == 0) {
      /* Nothing sent */
      printf("<dpi cmd='answer' to_cmd='open_url' msg='nothing sent...'>");
      fflush(stdout);
   }

   g_free(cmd);
   g_free(url);
   g_free(dpip_tag);
   g_free(wget_cmd);
   return 0;
}

