Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
  3.  *
  4.  * This file is part of NetSurf, http://www.netsurf-browser.org/
  5.  *
  6.  * NetSurf is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; version 2 of the License.
  9.  *
  10.  * NetSurf is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19. /** \file
  20.  * SSL Certificate verification UI (implementation)
  21.  */
  22.  
  23. #include "utils/config.h"
  24.  
  25. #include <assert.h>
  26. #include <stdbool.h>
  27. #include <string.h>
  28. #include "content/content.h"
  29. #include "content/fetch.h"
  30. #include "content/hlcache.h"
  31. #include "content/urldb.h"
  32. #include "desktop/browser.h"
  33. #include "desktop/sslcert.h"
  34. #include "desktop/tree.h"
  35. #include "utils/log.h"
  36. #include "utils/messages.h"
  37. #include "utils/nsurl.h"
  38. #include "utils/utils.h"
  39.  
  40. /** Flags for each type of ssl tree node. */
  41. enum tree_element_ssl {
  42.         TREE_ELEMENT_SSL_VERSION = 0x01,
  43.         TREE_ELEMENT_SSL_VALID_FROM = 0x02,
  44.         TREE_ELEMENT_SSL_VALID_TO = 0x03,
  45.         TREE_ELEMENT_SSL_CERT_TYPE = 0x04,
  46.         TREE_ELEMENT_SSL_SERIAL = 0x05,
  47.         TREE_ELEMENT_SSL_ISSUER = 0x06,
  48. };
  49.  
  50. /** ssl certificate verification context. */
  51. struct sslcert_session_data {
  52.         unsigned long num; /**< The number of ssl certificates in the chain */
  53.         nsurl *url; /**< The url of the certificate */
  54.         struct tree *tree; /**< The root of the treeview */
  55.         llcache_query_response cb; /**< callback when cert is accepted or rejected */
  56.         void *cbpw; /**< context passed to callback */
  57. };
  58.  
  59. /** Handle for the window icon. */
  60. static hlcache_handle *sslcert_icon = NULL;
  61.  
  62. /** Initialise ssl certificate window. */
  63. void sslcert_init(const char* icon_name)
  64. {
  65.         sslcert_icon = tree_load_icon(icon_name);
  66. }
  67.  
  68.  
  69. /**
  70.  * Get flags with which the sslcert tree should be created;
  71.  *
  72.  * \return the flags
  73.  */
  74. unsigned int sslcert_get_tree_flags(void)
  75. {
  76.         return TREE_NO_DRAGS  | TREE_NO_SELECT;
  77. }
  78.  
  79.  
  80. void sslcert_cleanup(void)
  81. {
  82.         if (sslcert_icon != NULL)
  83.                 hlcache_handle_release(sslcert_icon);
  84. }
  85.  
  86. struct sslcert_session_data *
  87. sslcert_create_session_data(unsigned long num,
  88.                             nsurl *url,
  89.                             llcache_query_response cb,
  90.                             void *cbpw)
  91. {
  92.         struct sslcert_session_data *data;
  93.  
  94.         data = malloc(sizeof(struct sslcert_session_data));
  95.         if (data == NULL) {
  96.                 warn_user("NoMemory", 0);
  97.                 return NULL;
  98.         }
  99.         data->url = nsurl_ref(url);
  100.         if (data->url == NULL) {
  101.                 free(data);
  102.                 warn_user("NoMemory", 0);
  103.                 return NULL;
  104.         }
  105.         data->num = num;
  106.         data->cb = cb;
  107.         data->cbpw = cbpw;
  108.  
  109.         return data;
  110. }
  111.  
  112. static node_callback_resp sslcert_node_callback(void *user_data,
  113.                                                 struct node_msg_data *msg_data)
  114. {
  115.         if (msg_data->msg == NODE_DELETE_ELEMENT_IMG)
  116.                 return NODE_CALLBACK_HANDLED;
  117.         return NODE_CALLBACK_NOT_HANDLED;
  118. }
  119.  
  120. static struct node *sslcert_create_node(const struct ssl_cert_info *cert)
  121. {
  122.         struct node *node;
  123.         struct node_element *element;
  124.         char *text;
  125.  
  126.         text = messages_get_buff("SSL_Certificate_Subject", cert->subject);
  127.         if (text == NULL)
  128.                 return NULL;
  129.  
  130.         node = tree_create_leaf_node(NULL, NULL, text, false, false, false);
  131.         if (node == NULL) {
  132.                 free(text);
  133.                 return NULL;
  134.         }
  135.         tree_set_node_user_callback(node, sslcert_node_callback, NULL);
  136.  
  137.         /* add issuer node */
  138.         element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
  139.                                            TREE_ELEMENT_SSL_ISSUER, false);
  140.         if (element != NULL) {
  141.                 text = messages_get_buff("SSL_Certificate_Issuer", cert->issuer);
  142.                 if (text == NULL) {
  143.                         tree_delete_node(NULL, node, false);
  144.                         return NULL;
  145.                 }
  146.                 tree_update_node_element(NULL, element, text, NULL);
  147.         }
  148.  
  149.         /* add version node */
  150.         element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
  151.                                            TREE_ELEMENT_SSL_VERSION, false);
  152.         if (element != NULL) {
  153.                 text = messages_get_buff("SSL_Certificate_Version", cert->version);
  154.                 if (text == NULL) {
  155.                         tree_delete_node(NULL, node, false);
  156.                         return NULL;
  157.                 }
  158.                 tree_update_node_element(NULL, element, text, NULL);
  159.         }
  160.  
  161.         /* add valid from node */
  162.         element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
  163.                                            TREE_ELEMENT_SSL_VALID_FROM, false);
  164.         if (element != NULL) {
  165.                 text = messages_get_buff("SSL_Certificate_ValidFrom", cert->not_before);
  166.                 if (text == NULL) {
  167.                         tree_delete_node(NULL, node, false);
  168.                         return NULL;
  169.                 }
  170.                 tree_update_node_element(NULL, element, text, NULL);
  171.         }
  172.  
  173.  
  174.         /* add valid to node */
  175.         element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
  176.                                            TREE_ELEMENT_SSL_VALID_TO, false);
  177.         if (element != NULL) {
  178.                 text = messages_get_buff("SSL_Certificate_ValidTo", cert->not_after);
  179.                 if (text == NULL) {
  180.                         tree_delete_node(NULL, node, false);
  181.                         return NULL;
  182.                 }
  183.                 tree_update_node_element(NULL, element, text, NULL);
  184.         }
  185.  
  186.         /* add certificate type */
  187.         element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
  188.                                            TREE_ELEMENT_SSL_CERT_TYPE, false);
  189.         if (element != NULL) {
  190.                 text = messages_get_buff("SSL_Certificate_Type", cert->cert_type);
  191.                 if (text == NULL) {
  192.                         tree_delete_node(NULL, node, false);
  193.                         return NULL;
  194.                 }
  195.                 tree_update_node_element(NULL, element, text, NULL);
  196.         }
  197.  
  198.         /* add serial node */
  199.         element = tree_create_node_element(node, NODE_ELEMENT_TEXT,
  200.                                            TREE_ELEMENT_SSL_SERIAL, false);
  201.         if (element != NULL) {
  202.                 text = messages_get_buff("SSL_Certificate_Serial", cert->serial);
  203.                 if (text == NULL) {
  204.                         tree_delete_node(NULL, node, false);
  205.                         return NULL;
  206.                 }
  207.                 tree_update_node_element(NULL, element, text, NULL);
  208.         }
  209.  
  210.         /* set the display icon */
  211.         tree_set_node_icon(NULL, node, sslcert_icon);
  212.  
  213.         return node;
  214. }
  215.  
  216. bool sslcert_load_tree(struct tree *tree,
  217.                        const struct ssl_cert_info *certs,
  218.                        struct sslcert_session_data *data)
  219. {
  220.         struct node *tree_root;
  221.         struct node *node;
  222.         unsigned long cert_loop;
  223.  
  224.         assert(data != NULL && certs != NULL && tree != NULL);
  225.  
  226.         tree_root = tree_get_root(tree);
  227.  
  228.         for (cert_loop = 0; cert_loop < data->num; cert_loop++) {
  229.                 node = sslcert_create_node(&(certs[cert_loop]));
  230.                 if (node != NULL) {
  231.                         /* There is no problem creating the node
  232.                          * add an entry for it in the root of the
  233.                          * treeview .
  234.                          */
  235.                         tree_link_node(tree, tree_root, node, false);
  236.                 }
  237.         }
  238.  
  239.         data->tree = tree;
  240.  
  241.         return true;
  242.  
  243. }
  244.  
  245.  
  246. static void sslcert_cleanup_session(struct sslcert_session_data *session)
  247. {
  248.         assert(session != NULL);
  249.  
  250.         if (session->url)
  251.                 nsurl_unref(session->url);
  252.  
  253.         free(session);
  254. }
  255.  
  256.  
  257.  
  258. bool sslcert_reject(struct sslcert_session_data *session)
  259. {
  260.         session->cb(false, session->cbpw);
  261.         sslcert_cleanup_session(session);
  262.         return true;
  263. }
  264.  
  265.  
  266. /**
  267.  * Handle acceptance of certificate
  268.  */
  269. bool sslcert_accept(struct sslcert_session_data *session)
  270. {
  271.         assert(session != NULL);
  272.  
  273.         urldb_set_cert_permissions(session->url, true);
  274.  
  275.         session->cb(true, session->cbpw);
  276.  
  277.         sslcert_cleanup_session(session);
  278.  
  279.         return true;
  280. }
  281.