Implement MD5 and SHA1 Link Fingerprint support
If a URL has an embedded link fingerprint the checksum and algorithm is shown in the download prompt. After a file has been saved to disk a warning icon will be shown if the checksum doesn't match and clicking the icon will explain that the file is erroneous and not open it. See http://mdhashtool.mozdev.org/lfinfo.html
This commit is contained in:
parent
a9b771ab5c
commit
9ca1271020
2 changed files with 112 additions and 5 deletions
|
@ -2857,6 +2857,13 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
|
||||||
GtkWidget* dialog;
|
GtkWidget* dialog;
|
||||||
gchar* content_type;
|
gchar* content_type;
|
||||||
gchar* description;
|
gchar* description;
|
||||||
|
gchar* file_type;
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||||
|
WebKitWebDataSource* datasource;
|
||||||
|
WebKitNetworkRequest* original_request;
|
||||||
|
#endif
|
||||||
|
const gchar* original_uri;
|
||||||
|
gchar** fingerprint;
|
||||||
#if GTK_CHECK_VERSION (2, 14, 0)
|
#if GTK_CHECK_VERSION (2, 14, 0)
|
||||||
GIcon* icon;
|
GIcon* icon;
|
||||||
GtkWidget* image;
|
GtkWidget* image;
|
||||||
|
@ -2916,12 +2923,38 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
|
||||||
#endif
|
#endif
|
||||||
g_free (content_type);
|
g_free (content_type);
|
||||||
if (g_strrstr (description, mime_type))
|
if (g_strrstr (description, mime_type))
|
||||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
file_type = g_strdup_printf (_("File Type: '%s'"), mime_type);
|
||||||
_("File Type: '%s'"), mime_type);
|
|
||||||
else
|
else
|
||||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
file_type = g_strdup_printf (_("File Type: %s ('%s')"), description, mime_type);
|
||||||
_("File Type: %s ('%s')"), description, mime_type);
|
|
||||||
g_free (description);
|
g_free (description);
|
||||||
|
|
||||||
|
/* Link Fingerprint */
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||||
|
/* We look at the original URI because redirection would lose the fragment */
|
||||||
|
datasource = webkit_web_frame_get_provisional_data_source (web_frame);
|
||||||
|
original_request = webkit_web_data_source_get_initial_request (datasource);
|
||||||
|
original_uri = webkit_network_request_get_uri (original_request);
|
||||||
|
#else
|
||||||
|
original_uri = webkit_network_request_get_uri (request);
|
||||||
|
#endif
|
||||||
|
fingerprint = g_strsplit (original_uri, "#!md5!", 2);
|
||||||
|
if (fingerprint && fingerprint[0] && fingerprint[1])
|
||||||
|
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||||
|
"%s\n%s %s", file_type, _("MD5-Checksum:"), fingerprint[1]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_strfreev (fingerprint);
|
||||||
|
fingerprint = g_strsplit (original_uri, "#!sha1!", 2);
|
||||||
|
if (fingerprint && fingerprint[0] && fingerprint[1])
|
||||||
|
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||||
|
"%s\n%s %s", file_type, _("SHA1-Checksum:"), fingerprint[1]);
|
||||||
|
else
|
||||||
|
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||||
|
"%s", file_type);
|
||||||
|
}
|
||||||
|
g_strfreev (fingerprint);
|
||||||
|
g_free (file_type);
|
||||||
|
|
||||||
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
|
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
|
||||||
/* i18n: A file open dialog title, ie. "Open http://fila.com/manual.tgz" */
|
/* i18n: A file open dialog title, ie. "Open http://fila.com/manual.tgz" */
|
||||||
title = g_strdup_printf (_("Open %s"),
|
title = g_strdup_printf (_("Open %s"),
|
||||||
|
@ -2989,6 +3022,16 @@ webkit_web_view_download_requested_cb (GtkWidget* web_view,
|
||||||
MidoriView* view)
|
MidoriView* view)
|
||||||
{
|
{
|
||||||
gboolean handled;
|
gboolean handled;
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||||
|
/* Propagate original URI to make it available when the download finishes */
|
||||||
|
WebKitWebFrame* web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
|
||||||
|
WebKitWebDataSource* datasource = webkit_web_frame_get_provisional_data_source (web_frame);
|
||||||
|
WebKitNetworkRequest* original_request = webkit_web_data_source_get_initial_request (datasource);
|
||||||
|
const gchar* original_uri = webkit_network_request_get_uri (original_request);
|
||||||
|
WebKitNetworkRequest* request = webkit_download_get_network_request (download);
|
||||||
|
g_object_set_data_full (G_OBJECT (request), "midori-original-uri",
|
||||||
|
g_strdup (original_uri), g_free);
|
||||||
|
#endif
|
||||||
g_object_set_data (G_OBJECT (download), "open-download",
|
g_object_set_data (G_OBJECT (download), "open-download",
|
||||||
g_object_get_data (G_OBJECT (view), "open-download"));
|
g_object_get_data (G_OBJECT (view), "open-download"));
|
||||||
g_object_set_data (G_OBJECT (download), "save-as-download",
|
g_object_set_data (G_OBJECT (download), "save-as-download",
|
||||||
|
|
|
@ -137,6 +137,11 @@ midori_transferbar_download_notify_status_cb (WebKitDownload* download,
|
||||||
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
|
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
|
||||||
{
|
{
|
||||||
MidoriBrowser* browser = midori_browser_get_for_widget (button);
|
MidoriBrowser* browser = midori_browser_get_for_widget (button);
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||||
|
WebKitNetworkRequest* request;
|
||||||
|
#endif
|
||||||
|
const gchar* original_uri;
|
||||||
|
gchar** fingerprint;
|
||||||
|
|
||||||
icon = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
|
icon = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
|
||||||
gtk_button_set_image (GTK_BUTTON (button), icon);
|
gtk_button_set_image (GTK_BUTTON (button), icon);
|
||||||
|
@ -155,6 +160,53 @@ midori_transferbar_download_notify_status_cb (WebKitDownload* download,
|
||||||
_("Transfer completed"), msg);
|
_("Transfer completed"), msg);
|
||||||
g_free (msg);
|
g_free (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Link Fingerprint */
|
||||||
|
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||||
|
request = webkit_download_get_network_request (download);
|
||||||
|
original_uri = g_object_get_data (G_OBJECT (request), "midori-original-uri");
|
||||||
|
#else
|
||||||
|
original_uri = webkit_download_get_uri (download);
|
||||||
|
#endif
|
||||||
|
fingerprint = g_strsplit (original_uri, "#!md5!", 2);
|
||||||
|
if (fingerprint && fingerprint[0] && fingerprint[1])
|
||||||
|
{
|
||||||
|
gchar* filename = g_filename_from_uri (
|
||||||
|
webkit_download_get_destination_uri (download), NULL, NULL);
|
||||||
|
gchar* contents;
|
||||||
|
gsize length;
|
||||||
|
gboolean y = g_file_get_contents (filename, &contents, &length, NULL);
|
||||||
|
gchar* checksum = g_compute_checksum_for_data (G_CHECKSUM_MD5,
|
||||||
|
(guchar*)contents, length);
|
||||||
|
g_free (filename);
|
||||||
|
g_free (contents);
|
||||||
|
if (!y || !g_str_equal (fingerprint[1], checksum))
|
||||||
|
gtk_image_set_from_stock (GTK_IMAGE (icon),
|
||||||
|
GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU);
|
||||||
|
g_free (checksum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gchar* filename = g_filename_from_uri (
|
||||||
|
webkit_download_get_destination_uri (download), NULL, NULL);
|
||||||
|
g_strfreev (fingerprint);
|
||||||
|
fingerprint = g_strsplit (original_uri, "#!sha1!", 2);
|
||||||
|
if (fingerprint && fingerprint[0] && fingerprint[1])
|
||||||
|
{
|
||||||
|
gchar* contents;
|
||||||
|
gsize length;
|
||||||
|
gboolean y = g_file_get_contents (filename, &contents, &length, NULL);
|
||||||
|
gchar* checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1,
|
||||||
|
(guchar*)contents, length);
|
||||||
|
g_free (contents);
|
||||||
|
if (!y || !g_str_equal (fingerprint[1], checksum))
|
||||||
|
gtk_image_set_from_stock (GTK_IMAGE (icon),
|
||||||
|
GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU);
|
||||||
|
g_free (checksum);
|
||||||
|
}
|
||||||
|
g_free (filename);
|
||||||
|
}
|
||||||
|
g_strfreev (fingerprint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
|
case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
|
||||||
|
@ -181,7 +233,19 @@ midori_transferbar_download_button_clicked_cb (GtkWidget* button,
|
||||||
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
|
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
|
||||||
{
|
{
|
||||||
const gchar* uri = webkit_download_get_destination_uri (download);
|
const gchar* uri = webkit_download_get_destination_uri (download);
|
||||||
if (sokoke_show_uri (gtk_widget_get_screen (button),
|
GtkWidget* icon = gtk_button_get_image (GTK_BUTTON (button));
|
||||||
|
gchar* stock_id;
|
||||||
|
gtk_image_get_stock (GTK_IMAGE (icon), &stock_id, NULL);
|
||||||
|
if (g_str_equal (stock_id, GTK_STOCK_DIALOG_WARNING))
|
||||||
|
{
|
||||||
|
sokoke_message_dialog (GTK_MESSAGE_WARNING,
|
||||||
|
_("The downloaded file is erroneous."),
|
||||||
|
_("The checksum provided with the link did not match. " \
|
||||||
|
"This means the file is probably incomplete or was " \
|
||||||
|
"modified afterwards."),
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
else if (sokoke_show_uri (gtk_widget_get_screen (button),
|
||||||
uri, gtk_get_current_event_time (), NULL))
|
uri, gtk_get_current_event_time (), NULL))
|
||||||
gtk_widget_destroy (button);
|
gtk_widget_destroy (button);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue