Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F23020559
gpafileverifyop.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
10 KB
Subscribers
None
gpafileverifyop.c
View Options
/* gpafileverifyop.c - The GpaOperation object.
* Copyright (C) 2003, Miguel Coca.
*
* This file is part of GPA
*
* GPA 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.
*
* GPA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include
<glib.h>
#ifdef G_OS_UNIX
#include
<unistd.h>
#include
<sys/types.h>
#include
<sys/wait.h>
#else
#include
<io.h>
#endif
#include
"gpa.h"
#include
"gtktools.h"
#include
"gpgmetools.h"
#include
"gpafileverifyop.h"
#include
"verifydlg.h"
/* Internal functions */
static
gboolean
gpa_file_verify_operation_idle_cb
(
gpointer
data
);
static
void
gpa_file_verify_operation_done_error_cb
(
GpaContext
*
context
,
gpg_error_t
err
,
GpaFileVerifyOperation
*
op
);
static
void
gpa_file_verify_operation_done_cb
(
GpaContext
*
context
,
gpg_error_t
err
,
GpaFileVerifyOperation
*
op
);
static
void
gpa_file_verify_operation_response_cb
(
GtkDialog
*
dialog
,
gint
response
,
gpointer
user_data
);
/* GObject */
static
GObjectClass
*
parent_class
=
NULL
;
static
void
gpa_file_verify_operation_finalize
(
GObject
*
object
)
{
GpaFileVerifyOperation
*
op
=
GPA_FILE_VERIFY_OPERATION
(
object
);
gtk_widget_destroy
(
op
->
dialog
);
G_OBJECT_CLASS
(
parent_class
)
->
finalize
(
object
);
}
static
void
gpa_file_verify_operation_init
(
GpaFileVerifyOperation
*
op
)
{
op
->
sig_fd
=
-1
;
op
->
signed_text_fd
=
-1
;
op
->
sig
=
NULL
;
op
->
signed_text
=
NULL
;
op
->
signed_file
=
NULL
;
op
->
signature_file
=
NULL
;
}
static
GObject
*
gpa_file_verify_operation_constructor
(
GType
type
,
guint
n_construct_properties
,
GObjectConstructParam
*
construct_properties
)
{
GObject
*
object
;
GpaFileVerifyOperation
*
op
;
/* Invoke parent's constructor */
object
=
parent_class
->
constructor
(
type
,
n_construct_properties
,
construct_properties
);
op
=
GPA_FILE_VERIFY_OPERATION
(
object
);
/* Initialize */
/* Start with the first file after going back into the main loop */
g_idle_add
(
gpa_file_verify_operation_idle_cb
,
op
);
/* Connect to the "done" signal */
g_signal_connect
(
G_OBJECT
(
GPA_OPERATION
(
op
)
->
context
),
"done"
,
G_CALLBACK
(
gpa_file_verify_operation_done_error_cb
),
op
);
g_signal_connect
(
G_OBJECT
(
GPA_OPERATION
(
op
)
->
context
),
"done"
,
G_CALLBACK
(
gpa_file_verify_operation_done_cb
),
op
);
/* Give a title to the progress dialog */
gtk_window_set_title
(
GTK_WINDOW
(
GPA_FILE_OPERATION
(
op
)
->
progress_dialog
),
_
(
"Verifying..."
));
/* Create the verification dialog */
op
->
dialog
=
gpa_file_verify_dialog_new
(
GPA_OPERATION
(
op
)
->
window
);
g_signal_connect
(
G_OBJECT
(
op
->
dialog
),
"response"
,
G_CALLBACK
(
gpa_file_verify_operation_response_cb
),
op
);
return
object
;
}
static
void
gpa_file_verify_operation_class_init
(
GpaFileVerifyOperationClass
*
klass
)
{
GObjectClass
*
object_class
=
G_OBJECT_CLASS
(
klass
);
parent_class
=
g_type_class_peek_parent
(
klass
);
object_class
->
constructor
=
gpa_file_verify_operation_constructor
;
object_class
->
finalize
=
gpa_file_verify_operation_finalize
;
}
GType
gpa_file_verify_operation_get_type
(
void
)
{
static
GType
file_verify_operation_type
=
0
;
if
(
!
file_verify_operation_type
)
{
static
const
GTypeInfo
file_verify_operation_info
=
{
sizeof
(
GpaFileVerifyOperationClass
),
(
GBaseInitFunc
)
NULL
,
(
GBaseFinalizeFunc
)
NULL
,
(
GClassInitFunc
)
gpa_file_verify_operation_class_init
,
NULL
,
/* class_finalize */
NULL
,
/* class_data */
sizeof
(
GpaFileVerifyOperation
),
0
,
/* n_preallocs */
(
GInstanceInitFunc
)
gpa_file_verify_operation_init
,
};
file_verify_operation_type
=
g_type_register_static
(
GPA_FILE_OPERATION_TYPE
,
"GpaFileVerifyOperation"
,
&
file_verify_operation_info
,
0
);
}
return
file_verify_operation_type
;
}
/* API */
GpaFileVerifyOperation
*
gpa_file_verify_operation_new
(
GtkWidget
*
window
,
GList
*
files
)
{
GpaFileVerifyOperation
*
op
;
op
=
g_object_new
(
GPA_FILE_VERIFY_OPERATION_TYPE
,
"window"
,
window
,
"input_files"
,
files
,
NULL
);
return
op
;
}
/* Internal */
static
gboolean
ask_use_detached_sig
(
const
gchar
*
file
,
const
gchar
*
sig
,
GtkWidget
*
parent
)
{
GtkWidget
*
dialog
=
gtk_message_dialog_new
(
GTK_WINDOW
(
parent
),
GTK_DIALOG_MODAL
,
GTK_MESSAGE_WARNING
,
GTK_BUTTONS_NONE
,
_
(
"GPA found a file that could be a signature of %s. "
"Would you like to verify it instead?
\n\n
"
"The file found is: %s"
),
file
,
sig
);
gboolean
result
;
gtk_dialog_add_buttons
(
GTK_DIALOG
(
dialog
),
_
(
"_Yes"
),
GTK_RESPONSE_YES
,
_
(
"_No"
),
GTK_RESPONSE_NO
,
NULL
);
result
=
(
gtk_dialog_run
(
GTK_DIALOG
(
dialog
))
==
GTK_RESPONSE_YES
);
gtk_widget_destroy
(
dialog
);
return
result
;
}
/* Check whether the file is a detached signature and deduce the name of the
* original file. Since we only have access to the filename, this is not
* very solid.
*/
static
gboolean
is_detached_sig
(
const
gchar
*
filename
,
gchar
**
signature_file
,
gchar
**
signed_file
,
GtkWidget
*
window
)
{
const
gchar
*
sig_extension
[]
=
{
".sig"
,
".sign"
};
int
i
;
gchar
*
extension
;
/* First, check whether this file is a dettached signature */
*
signed_file
=
g_strdup
(
filename
);
extension
=
g_strrstr
(
*
signed_file
,
"."
);
if
(
extension
&&
(
g_str_equal
(
extension
,
".sig"
)
||
g_str_equal
(
extension
,
".sign"
)))
{
*
extension
++
=
'\0'
;
*
signature_file
=
g_strdup
(
filename
);
return
TRUE
;
}
/* Now, check whether a dettached signature exists for this file */
else
{
g_free
(
*
signed_file
);
*
signed_file
=
NULL
;
for
(
i
=
0
;
i
<
sizeof
(
sig_extension
)
/
sizeof
(
sig_extension
[
0
]);
i
++
)
{
gchar
*
sig
=
g_strconcat
(
filename
,
sig_extension
[
i
],
NULL
);
if
(
g_file_test
(
sig
,
G_FILE_TEST_EXISTS
)
&&
ask_use_detached_sig
(
filename
,
sig
,
window
))
{
*
signed_file
=
g_strdup
(
filename
);
*
signature_file
=
sig
;
return
TRUE
;
}
else
{
g_free
(
sig
);
}
}
return
FALSE
;
}
}
static
gboolean
gpa_file_verify_operation_start
(
GpaFileVerifyOperation
*
op
,
const
gchar
*
sig_filename
)
{
gpg_error_t
err
;
if
(
is_detached_sig
(
sig_filename
,
&
op
->
signature_file
,
&
op
->
signed_file
,
GPA_OPERATION
(
op
)
->
window
))
{
/* Allocate data objects for a detached signature */
op
->
sig_fd
=
gpa_open_input
(
op
->
signature_file
,
&
op
->
sig
,
GPA_OPERATION
(
op
)
->
window
);
if
(
op
->
sig_fd
==
-1
)
{
return
FALSE
;
}
op
->
signed_text_fd
=
gpa_open_input
(
op
->
signed_file
,
&
op
->
signed_text
,
GPA_OPERATION
(
op
)
->
window
);
if
(
op
->
signed_text_fd
==
-1
)
{
gpgme_data_release
(
op
->
sig
);
close
(
op
->
sig_fd
);
return
FALSE
;
}
op
->
plain
=
NULL
;
}
else
{
/* Allocate data object for non-detached signatures */
op
->
sig_fd
=
gpa_open_input
(
sig_filename
,
&
op
->
sig
,
GPA_OPERATION
(
op
)
->
window
);
if
(
op
->
sig_fd
==
-1
)
{
return
FALSE
;
}
if
(
gpg_err_code
(
gpgme_data_new
(
&
op
->
plain
))
!=
GPG_ERR_NO_ERROR
)
{
gpgme_data_release
(
op
->
sig
);
close
(
op
->
sig_fd
);
return
FALSE
;
}
op
->
signed_text_fd
=
-1
;
op
->
signed_text
=
NULL
;
}
/* Start the operation */
err
=
gpgme_op_verify_start
(
GPA_OPERATION
(
op
)
->
context
->
ctx
,
op
->
sig
,
op
->
signed_text
,
op
->
plain
);
if
(
gpg_err_code
(
err
)
!=
GPG_ERR_NO_ERROR
)
{
gpa_gpgme_warning
(
err
);
return
FALSE
;
}
/* Show and update the progress dialog */
gtk_widget_show_all
(
GPA_FILE_OPERATION
(
op
)
->
progress_dialog
);
gpa_progress_dialog_set_label
(
GPA_PROGRESS_DIALOG
(
GPA_FILE_OPERATION
(
op
)
->
progress_dialog
),
sig_filename
);
return
TRUE
;
}
static
void
gpa_file_verify_operation_next
(
GpaFileVerifyOperation
*
op
)
{
if
(
!
GPA_FILE_OPERATION
(
op
)
->
current
||
!
gpa_file_verify_operation_start
(
op
,
GPA_FILE_OPERATION
(
op
)
->
current
->
data
))
{
/* All files have been verified: show the results dialog */
gtk_widget_show_all
(
op
->
dialog
);
}
}
static
void
gpa_file_verify_operation_done_cb
(
GpaContext
*
context
,
gpg_error_t
err
,
GpaFileVerifyOperation
*
op
)
{
/* Do clean up on the operation */
if
(
op
->
plain
)
{
gpgme_data_release
(
op
->
plain
);
}
if
(
op
->
signed_text
)
{
gpgme_data_release
(
op
->
signed_text
);
close
(
op
->
signed_text_fd
);
}
gpgme_data_release
(
op
->
sig
);
close
(
op
->
sig_fd
);
gtk_widget_hide
(
GPA_FILE_OPERATION
(
op
)
->
progress_dialog
);
/* Check for error */
if
(
gpg_err_code
(
err
)
!=
GPG_ERR_NO_ERROR
)
{
/* Abort further verifications */
}
else
{
gpgme_verify_result_t
result
;
result
=
gpgme_op_verify_result
(
GPA_OPERATION
(
op
)
->
context
->
ctx
);
/* Add the file to the result dialog */
gpa_file_verify_dialog_add_file
(
GPA_FILE_VERIFY_DIALOG
(
op
->
dialog
),
GPA_FILE_OPERATION
(
op
)
->
current
->
data
,
op
->
signed_file
,
op
->
signature_file
,
result
->
signatures
);
/* If this was a dettached sig, reset the signed file */
if
(
op
->
signed_file
)
{
g_free
(
op
->
signed_file
);
op
->
signed_file
=
NULL
;
g_free
(
op
->
signature_file
);
op
->
signature_file
=
NULL
;
}
/* Go to the next file in the list and verify it */
GPA_FILE_OPERATION
(
op
)
->
current
=
g_list_next
(
GPA_FILE_OPERATION
(
op
)
->
current
);
gpa_file_verify_operation_next
(
op
);
}
}
static
gboolean
gpa_file_verify_operation_idle_cb
(
gpointer
data
)
{
GpaFileVerifyOperation
*
op
=
data
;
gpa_file_verify_operation_next
(
op
);
return
FALSE
;
}
static
void
gpa_file_verify_operation_response_cb
(
GtkDialog
*
dialog
,
gint
response
,
gpointer
user_data
)
{
GpaFileVerifyOperation
*
op
=
GPA_FILE_VERIFY_OPERATION
(
user_data
);
g_signal_emit_by_name
(
GPA_OPERATION
(
op
),
"completed"
);
}
static
void
gpa_file_verify_operation_done_error_cb
(
GpaContext
*
context
,
gpg_error_t
err
,
GpaFileVerifyOperation
*
op
)
{
gchar
*
message
;
switch
(
gpg_err_code
(
err
))
{
case
GPG_ERR_NO_ERROR
:
case
GPG_ERR_CANCELED
:
/* Ignore these */
break
;
case
GPG_ERR_NO_DATA
:
message
=
g_strdup_printf
(
_
(
"The file
\"
%s
\"
contained no OpenPGP "
"data."
),
gpa_file_operation_current_file
(
GPA_FILE_OPERATION
(
op
)));
gpa_window_error
(
message
,
GPA_OPERATION
(
op
)
->
window
);
g_free
(
message
);
break
;
case
GPG_ERR_BAD_PASSPHRASE
:
gpa_window_error
(
_
(
"Wrong passphrase!"
),
GPA_OPERATION
(
op
)
->
window
);
break
;
default
:
gpa_gpgme_warning
(
err
);
break
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Mon, May 12, 6:22 PM (1 d, 9 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
f3/b8/109fd610ec55d98a21a18d8f8876
Attached To
rGPA Gnu Privacy Assistant
Event Timeline
Log In to Comment