⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 https.c

📁 基于minigui的浏览器. 这是最新版本.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Dpi for HTTPS. * * * *                            W A R N I N G * * One of the important things to have in mind 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, peeking-up in * memory space, installing a key-grabber, ... * * * Copyright 2003, 2004 Jorge Arellano Cid <jcid@dillo.org> * Copyright 2004 Garrett Kajmowicz <gkajmowi@tbaytel.net> * * 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. * * As a special exception permission is granted to link the code of * the https dillo plugin with the OpenSSL project's "OpenSSL" * library, and distribute the linked executables, without including * the source code for OpenSSL in the source distribution. You must * obey the GNU General Public License, version 2, in all respects * for all of the code used other than "OpenSSL". * *//* * TODO: a lot of things, this is just a bare bones example. * * For instance: * - Handle cookies (now that they arrive with the dpip tag, it needs *   testing). * - Certificate authentication (asking the user in case it can't be verified) * - Certificate management. * - Session caching ... * */#include <config.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.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 <sys/stat.h>#include <glib.h>#include "../dpip/dpip.h"#include "dpiutil.h"#define ENABLE_SSL#undef ENABLE_SSL#ifdef ENABLE_SSL#include <openssl/ssl.h>#include <openssl/rand.h>static int get_network_connection(gchar * url);static int handle_certificate_problem(SSL * ssl_connection);static int save_certificate_home(X509 * cert);#endifint main(void);/*---------------------------------------------------------------------------*//* * Global variables */static gchar *root_url = NULL;  /*Holds the URL we are connecting to*/static SockHandler *sh;#ifdef ENABLE_SSL/* * Read the answer dpip tag for a dialog and return the number for * the user-selected alternative. * Return: (-1: parse error, 0: window closed, 1-5 alt. number) */static gint dialog_get_answer_number(void){   gint response_number = -1;   gchar *dpip_tag, *response;   /* Read the dpi command from STDIN */   dpip_tag = sock_handler_read(sh);   response = a_Dpip_get_attr(dpip_tag, strlen(dpip_tag), "msg");   response_number = (response) ? strtol (response, NULL, 10) : -1;   g_free(dpip_tag);   g_free(response);   return response_number;}/* *  This function does all of the work with SSL */static void yes_ssl_support(void){   /* The following variable will be set to 1 in the event of    * an error and skip any further processing    */   gint exit_error = 0;   SSL_CTX * ssl_context = NULL;   SSL * ssl_connection = NULL;   gchar *dpip_tag = NULL, *cmd = NULL, *url = NULL, *http_query = NULL;   gchar buf[4096];   int retval = 0;   int network_socket = -1;   g_printerr("{In https.filter.dpi}\n");   /*Initialize library*/   SSL_load_error_strings();   SSL_library_init();   if (RAND_status() != 1){      /*Insufficient entropy.  Deal with it?*/      g_printerr("Insufficient random entropy\n");   }   /*Create context and SSL object*/   if (exit_error == 0){      ssl_context = SSL_CTX_new(SSLv23_client_method());      if (ssl_context == NULL){         g_printerr("Error creating SSL context\n");         exit_error = 1;      }   }   /*Set directory to load certificates from*/   /*FIXME - provide for sysconfdir variables and such*/   if (exit_error == 0){      if (SSL_CTX_load_verify_locations(         ssl_context, NULL, "/etc/ssl/certs/" ) == 0){         g_printerr("Error opening system x509 certificate location\n");         exit_error = 1;      }   }   if (exit_error == 0){      g_snprintf(buf, 4095, "%s/.dillo/certs/", g_get_home_dir() );      if (SSL_CTX_load_verify_locations(ssl_context, NULL, buf )==0){         g_printerr("Error opening user x509 certificate location\n");         exit_error = 1;      }   }   if (exit_error == 0){      ssl_connection = SSL_new(ssl_context);      if (ssl_connection == NULL){         g_printerr("Error creating SSL connection\n");         exit_error = 1;      }   }   if (exit_error == 0){      /* Need to do the following if we want to deal with all       * possible ciphers       */      SSL_set_cipher_list(ssl_connection, "ALL");      /* Need to do this if we want to have the option of dealing       * with self-signed certs       */      SSL_set_verify(ssl_connection, SSL_VERIFY_NONE, 0);      /*Get the network address and command to be used*/      dpip_tag = sock_handler_read(sh);      cmd = a_Dpip_get_attr(dpip_tag, strlen(dpip_tag), "cmd");      url = a_Dpip_get_attr(dpip_tag, strlen(dpip_tag), "url");      http_query = a_Dpip_get_attr(dpip_tag, strlen(dpip_tag), "query");      if (cmd == NULL || url == NULL || http_query == NULL){         g_printerr("***Value of cmd, url or http_query is NULL"                    " - cannot continue\n");         exit_error = 1;      }   }   if (exit_error == 0){      network_socket = get_network_connection(url);      if (network_socket<0){         g_printerr("Network socket create error\n");         exit_error = 1;      }   }   if (exit_error == 0){      /* Configure SSL to use network file descriptor */      if (SSL_set_fd(ssl_connection, network_socket) == 0){         g_printerr("Error connecting network socket to SSL\n");         exit_error = 1;     }   }   if (exit_error == 0){      /*Actually do SSL connection handshake*/      if (SSL_connect(ssl_connection) != 1){         g_printerr("SSL_connect failed\n");         exit_error = 1;      }   }   /*Use handle error function to decide what to do*/   if (exit_error == 0){      if (handle_certificate_problem(ssl_connection) < 0){         g_printerr("Certificate verification error\n");         exit_error = 1;      }   }   if (exit_error == 0) {      char *d_cmd;      /*Send query we want*/      SSL_write(ssl_connection, http_query, (int)strlen(http_query));      /*Analyse response from server*/      /*Send dpi command*/      d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", url);      sock_handler_write_str(sh, d_cmd, 1);      g_free(d_cmd);      /*Send remaining data*/      while ((retval = SSL_read(ssl_connection, buf, 4096)) > 0 ){         sock_handler_write(sh, buf, (size_t)retval, 0);      }   }   /*Begin cleanup of all resources used*/   g_free(dpip_tag);   g_free(cmd);   g_free(url);   g_free(http_query);   if (network_socket != -1){      close(network_socket);      network_socket = -1;   }   if (ssl_connection != NULL){      SSL_free(ssl_connection);      ssl_connection = NULL;   }   if (ssl_context != NULL){      SSL_CTX_free(ssl_context);      ssl_context = NULL;   }}/* * The following function attempts to open up a connection to the * remote server and return the file descriptor number of the * socket.  Returns -1 in the event of an error */static int get_network_connection(gchar * url){   struct sockaddr_in address;   struct hostent *hp;   int s;   int url_offset = 0;   int portnum = 443;   unsigned int url_look_up_length = 0;   gchar * url_look_up = NULL;   /*Determine how much of url we chop off as unneeded*/   if (g_strncasecmp(url, "https://", 8) == 0){      url_offset = 8;   }   /*Find end of URL*/   if (strpbrk(url+url_offset, ":/") != NULL){      url_look_up_length = strpbrk(url+url_offset, ":/") - (url+url_offset);      url_look_up = g_strndup(url+url_offset, url_look_up_length);      /*Check for port number*/      if (strchr(url+url_offset, ':') ==          (url + url_offset + url_look_up_length)){         portnum = atoi(url + url_offset + url_look_up_length + 1);      }   } else {      url_look_up = url + url_offset;   }   root_url = g_strdup(url_look_up);   hp=gethostbyname(url_look_up);   /*url_look_uip no longer needed, so free if neccessary*/   if (url_look_up_length != 0){      g_free(url_look_up);   }   if (hp == NULL){      g_printerr("gethostbyname() failed\n");      return -1;   }   memset(&address,0,sizeof(address));   memcpy((char *)&address.sin_addr, hp->h_addr, (size_t)hp->h_length);   address.sin_family=hp->h_addrtype;   address.sin_port= htons((u_short)portnum);   s = socket(hp->h_addrtype, SOCK_STREAM, 0);   if (connect(s, (struct sockaddr *)&address, sizeof(address)) != 0){      close(s);      s = -1;      g_printerr("errno: %i\n", errno);   }   return s;}/* This function is run only when the certificate cannot * be completely trusted.  This will notify the user and * allow the user to decide what to do.  It may save the * certificate to the user's .dillo directory if it is * trusted. * Return value: -1 on abort, 0 or higher on continue */static int handle_certificate_problem(SSL * ssl_connection){   gint response_number;   int retval = -1;   long st;   char *cn, *cn_end;   char buf[4096], *d_cmd, *msg;   X509 * remote_cert;   remote_cert = SSL_get_peer_certificate(ssl_connection);   if (remote_cert == NULL){      /*Inform user that remote system cannot be trusted*/      d_cmd = a_Dpip_build_cmd(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -