mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-21 18:38:08 +01:00
crypto: make shared crypto code behave library-like
If we're going to reuse the crypto code across both the library and the client, then it needs to report error states properly and not write to stderr.
This commit is contained in:
parent
197d67959b
commit
a18bbf7f15
5 changed files with 79 additions and 50 deletions
|
@ -413,6 +413,12 @@ notmuch_status_to_string (notmuch_status_t status)
|
||||||
return "Operation requires a database upgrade";
|
return "Operation requires a database upgrade";
|
||||||
case NOTMUCH_STATUS_PATH_ERROR:
|
case NOTMUCH_STATUS_PATH_ERROR:
|
||||||
return "Path supplied is illegal for this function";
|
return "Path supplied is illegal for this function";
|
||||||
|
case NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL:
|
||||||
|
return "Crypto protocol missing, malformed, or unintelligible";
|
||||||
|
case NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION:
|
||||||
|
return "Crypto engine initialization failure";
|
||||||
|
case NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL:
|
||||||
|
return "Unknown crypto protocol";
|
||||||
default:
|
default:
|
||||||
case NOTMUCH_STATUS_LAST_STATUS:
|
case NOTMUCH_STATUS_LAST_STATUS:
|
||||||
return "Unknown error status value";
|
return "Unknown error status value";
|
||||||
|
|
|
@ -191,6 +191,23 @@ typedef enum _notmuch_status {
|
||||||
* function, in a way not covered by a more specific argument.
|
* function, in a way not covered by a more specific argument.
|
||||||
*/
|
*/
|
||||||
NOTMUCH_STATUS_ILLEGAL_ARGUMENT,
|
NOTMUCH_STATUS_ILLEGAL_ARGUMENT,
|
||||||
|
/**
|
||||||
|
* A MIME object claimed to have cryptographic protection which
|
||||||
|
* notmuch tried to handle, but the protocol was not specified in
|
||||||
|
* an intelligible way.
|
||||||
|
*/
|
||||||
|
NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL,
|
||||||
|
/**
|
||||||
|
* Notmuch attempted to do crypto processing, but could not
|
||||||
|
* initialize the engine needed to do so.
|
||||||
|
*/
|
||||||
|
NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION,
|
||||||
|
/**
|
||||||
|
* A MIME object claimed to have cryptographic protection, and
|
||||||
|
* notmuch attempted to process it, but the specific protocol was
|
||||||
|
* something that notmuch doesn't know how to handle.
|
||||||
|
*/
|
||||||
|
NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL,
|
||||||
/**
|
/**
|
||||||
* Not an actual status value. Just a way to find out how many
|
* Not an actual status value. Just a way to find out how many
|
||||||
* valid status values there are.
|
* valid status values there are.
|
||||||
|
|
|
@ -269,7 +269,12 @@ _mime_node_create (mime_node_t *parent, GMimeObject *part)
|
||||||
|| (GMIME_IS_MULTIPART_SIGNED (part) && node->ctx->crypto->verify)) {
|
|| (GMIME_IS_MULTIPART_SIGNED (part) && node->ctx->crypto->verify)) {
|
||||||
GMimeContentType *content_type = g_mime_object_get_content_type (part);
|
GMimeContentType *content_type = g_mime_object_get_content_type (part);
|
||||||
const char *protocol = g_mime_content_type_get_parameter (content_type, "protocol");
|
const char *protocol = g_mime_content_type_get_parameter (content_type, "protocol");
|
||||||
cryptoctx = _notmuch_crypto_get_gmime_context (node->ctx->crypto, protocol);
|
notmuch_status_t status;
|
||||||
|
status = _notmuch_crypto_get_gmime_ctx_for_protocol (node->ctx->crypto,
|
||||||
|
protocol, &cryptoctx);
|
||||||
|
if (status) /* this is a warning, not an error */
|
||||||
|
fprintf (stderr, "Warning: %s (%s).\n", notmuch_status_to_string (status),
|
||||||
|
protocol ? protocol : "NULL");
|
||||||
if (!cryptoctx)
|
if (!cryptoctx)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,85 +25,86 @@
|
||||||
#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
|
#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
|
||||||
|
|
||||||
#if (GMIME_MAJOR_VERSION < 3)
|
#if (GMIME_MAJOR_VERSION < 3)
|
||||||
/* Create a GPG context (GMime 2.6) */
|
/* Create or pass on a GPG context (GMime 2.6) */
|
||||||
static GMimeCryptoContext *
|
static notmuch_status_t
|
||||||
create_gpg_context (_notmuch_crypto_t *crypto)
|
get_gpg_context (_notmuch_crypto_t *crypto, GMimeCryptoContext **ctx)
|
||||||
{
|
{
|
||||||
GMimeCryptoContext *gpgctx;
|
if (ctx == NULL || crypto == NULL)
|
||||||
|
return NOTMUCH_STATUS_NULL_POINTER;
|
||||||
|
|
||||||
if (crypto->gpgctx)
|
if (crypto->gpgctx) {
|
||||||
return crypto->gpgctx;
|
*ctx = crypto->gpgctx;
|
||||||
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: GMimePasswordRequestFunc */
|
/* TODO: GMimePasswordRequestFunc */
|
||||||
gpgctx = g_mime_gpg_context_new (NULL, crypto->gpgpath ? crypto->gpgpath : "gpg");
|
crypto->gpgctx = g_mime_gpg_context_new (NULL, crypto->gpgpath ? crypto->gpgpath : "gpg");
|
||||||
if (! gpgctx) {
|
if (! crypto->gpgctx) {
|
||||||
fprintf (stderr, "Failed to construct gpg context.\n");
|
return NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
crypto->gpgctx = gpgctx;
|
|
||||||
|
|
||||||
g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) gpgctx, true);
|
g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) crypto->gpgctx, true);
|
||||||
g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, false);
|
g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) crypto->gpgctx, false);
|
||||||
|
|
||||||
return gpgctx;
|
*ctx = crypto->gpgctx;
|
||||||
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a PKCS7 context (GMime 2.6) */
|
/* Create or pass on a PKCS7 context (GMime 2.6) */
|
||||||
static GMimeCryptoContext *
|
static notmuch_status_t
|
||||||
create_pkcs7_context (_notmuch_crypto_t *crypto)
|
get_pkcs7_context (_notmuch_crypto_t *crypto, GMimeCryptoContext **ctx)
|
||||||
{
|
{
|
||||||
GMimeCryptoContext *pkcs7ctx;
|
if (ctx == NULL || crypto == NULL)
|
||||||
|
return NOTMUCH_STATUS_NULL_POINTER;
|
||||||
|
|
||||||
if (crypto->pkcs7ctx)
|
if (crypto->pkcs7ctx) {
|
||||||
return crypto->pkcs7ctx;
|
*ctx = crypto->pkcs7ctx;
|
||||||
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: GMimePasswordRequestFunc */
|
/* TODO: GMimePasswordRequestFunc */
|
||||||
pkcs7ctx = g_mime_pkcs7_context_new (NULL);
|
crypto->pkcs7ctx = g_mime_pkcs7_context_new (NULL);
|
||||||
if (! pkcs7ctx) {
|
if (! crypto->pkcs7ctx) {
|
||||||
fprintf (stderr, "Failed to construct pkcs7 context.\n");
|
return NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
crypto->pkcs7ctx = pkcs7ctx;
|
|
||||||
|
|
||||||
g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) pkcs7ctx,
|
g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) crypto->pkcs7ctx,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
return pkcs7ctx;
|
*ctx = crypto->pkcs7ctx;
|
||||||
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *protocol;
|
const char *protocol;
|
||||||
GMimeCryptoContext *(*get_context) (_notmuch_crypto_t *crypto);
|
notmuch_status_t (*get_context) (_notmuch_crypto_t *crypto, GMimeCryptoContext **ctx);
|
||||||
} protocols[] = {
|
} protocols[] = {
|
||||||
{
|
{
|
||||||
.protocol = "application/pgp-signature",
|
.protocol = "application/pgp-signature",
|
||||||
.get_context = create_gpg_context,
|
.get_context = get_gpg_context,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.protocol = "application/pgp-encrypted",
|
.protocol = "application/pgp-encrypted",
|
||||||
.get_context = create_gpg_context,
|
.get_context = get_gpg_context,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.protocol = "application/pkcs7-signature",
|
.protocol = "application/pkcs7-signature",
|
||||||
.get_context = create_pkcs7_context,
|
.get_context = get_pkcs7_context,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.protocol = "application/x-pkcs7-signature",
|
.protocol = "application/x-pkcs7-signature",
|
||||||
.get_context = create_pkcs7_context,
|
.get_context = get_pkcs7_context,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* for the specified protocol return the context pointer (initializing
|
/* for the specified protocol return the context pointer (initializing
|
||||||
* if needed) */
|
* if needed) */
|
||||||
GMimeCryptoContext *
|
notmuch_status_t
|
||||||
_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol)
|
_notmuch_crypto_get_gmime_ctx_for_protocol (_notmuch_crypto_t *crypto,
|
||||||
|
const char *protocol,
|
||||||
|
GMimeCryptoContext **ctx)
|
||||||
{
|
{
|
||||||
GMimeCryptoContext *cryptoctx = NULL;
|
if (! protocol)
|
||||||
size_t i;
|
return NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL;
|
||||||
|
|
||||||
if (! protocol) {
|
|
||||||
fprintf (stderr, "Cryptographic protocol is empty.\n");
|
|
||||||
return cryptoctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* As per RFC 1847 section 2.1: "the [protocol] value token is
|
/* As per RFC 1847 section 2.1: "the [protocol] value token is
|
||||||
* comprised of the type and sub-type tokens of the Content-Type".
|
* comprised of the type and sub-type tokens of the Content-Type".
|
||||||
|
@ -111,15 +112,12 @@ _notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protoc
|
||||||
* parameter names as defined in this document are
|
* parameter names as defined in this document are
|
||||||
* case-insensitive." Thus, we use strcasecmp for the protocol.
|
* case-insensitive." Thus, we use strcasecmp for the protocol.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < ARRAY_SIZE (protocols); i++) {
|
for (size_t i = 0; i < ARRAY_SIZE (protocols); i++) {
|
||||||
if (strcasecmp (protocol, protocols[i].protocol) == 0)
|
if (strcasecmp (protocol, protocols[i].protocol) == 0)
|
||||||
return protocols[i].get_context (crypto);
|
return protocols[i].get_context (crypto, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "Unknown or unsupported cryptographic protocol %s.\n",
|
return NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL;
|
||||||
protocol);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#if (GMIME_MAJOR_VERSION < 3)
|
#if (GMIME_MAJOR_VERSION < 3)
|
||||||
#include "gmime-extra.h"
|
#include "gmime-extra.h"
|
||||||
|
#include "notmuch.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct _notmuch_crypto {
|
typedef struct _notmuch_crypto {
|
||||||
|
@ -18,8 +19,10 @@ typedef struct _notmuch_crypto {
|
||||||
|
|
||||||
|
|
||||||
#if (GMIME_MAJOR_VERSION < 3)
|
#if (GMIME_MAJOR_VERSION < 3)
|
||||||
GMimeCryptoContext *
|
notmuch_status_t
|
||||||
_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol);
|
_notmuch_crypto_get_gmime_ctx_for_protocol (_notmuch_crypto_t *crypto,
|
||||||
|
const char *protocol,
|
||||||
|
GMimeCryptoContext **ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue