[gmime] Modified GMimeParser to auto-detect OpenPGP markers
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime] Modified GMimeParser to auto-detect OpenPGP markers
- Date: Tue, 14 Mar 2017 00:27:20 +0000 (UTC)
commit e1f9abdff4ca8cb994a6d5879bdf783567c7dd94
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Mon Mar 13 16:09:03 2017 -0400
Modified GMimeParser to auto-detect OpenPGP markers
If the parser detects OpenPGP markers, it will set
that state on the GMimePart for easier detection by
mail clients using GMime w/o the need to manually
scan for those markers themselves.
docs/reference/gmime-sections.txt | 3 +
gmime/gmime-parser.c | 85 +++++++++++++++++++++++++++----------
gmime/gmime-part.c | 35 +++++++++++++++
gmime/gmime-part.h | 19 ++++++++
4 files changed, 120 insertions(+), 22 deletions(-)
---
diff --git a/docs/reference/gmime-sections.txt b/docs/reference/gmime-sections.txt
index 8ff0a2f..40f06f0 100644
--- a/docs/reference/gmime-sections.txt
+++ b/docs/reference/gmime-sections.txt
@@ -713,6 +713,7 @@ GMimeObjectClass
<SECTION>
<FILE>gmime-part</FILE>
GMimePart
+GMimeOpenPGPData
g_mime_part_new
g_mime_part_new_with_type
g_mime_part_is_attachment
@@ -730,6 +731,8 @@ g_mime_part_get_content_encoding
g_mime_part_get_best_content_encoding
g_mime_part_set_filename
g_mime_part_get_filename
+g_mime_part_get_openpgp_data
+g_mime_part_set_openpgp_data
g_mime_part_get_content
g_mime_part_set_content
diff --git a/gmime/gmime-parser.c b/gmime/gmime-parser.c
index 389fce7..5b485db 100644
--- a/gmime/gmime-parser.c
+++ b/gmime/gmime-parser.c
@@ -64,6 +64,18 @@
* into multiple #GMimeMessage objects.
**/
+typedef struct {
+ const char *begin;
+ const char *end;
+ size_t begin_len;
+ size_t end_len;
+} GMimeOpenPGPMarker;
+
+static const GMimeOpenPGPMarker openpgp_markers[] = {
+ { "-----BEGIN PGP MESSAGE-----", "-----END PGP MESSAGE-----", 27, 25 },
+ { "-----BEGIN PGP SIGNED MESSAGE-----", "-----END PGP SIGNED MESSAGE-----", 34, 32 }
+};
+
typedef struct _boundary_stack {
struct _boundary_stack *parent;
char *boundary;
@@ -109,7 +121,7 @@ static GObjectClass *parent_class = NULL;
#define HEADER_RAW_INIT_SIZE 1024
-enum {
+typedef enum {
GMIME_PARSER_STATE_ERROR = -1,
GMIME_PARSER_STATE_INIT,
GMIME_PARSER_STATE_FROM,
@@ -119,7 +131,7 @@ enum {
GMIME_PARSER_STATE_HEADERS_END,
GMIME_PARSER_STATE_CONTENT,
GMIME_PARSER_STATE_COMPLETE,
-};
+} GMimeParserState;
struct _GMimeParserPrivate {
GMimeStream *stream;
@@ -168,12 +180,14 @@ struct _GMimeParserPrivate {
short int state;
- unsigned short int unused:11;
unsigned short int midline:1;
unsigned short int seekable:1;
unsigned short int have_regex:1;
unsigned short int persist_stream:1;
unsigned short int respect_content_length:1;
+ unsigned short int openpgp_begin:2;
+ unsigned short int openpgp_end:2;
+ unsigned short int unused:7;
HeaderRaw *headers;
@@ -387,6 +401,9 @@ parser_init (GMimeParser *parser, GMimeStream *stream)
priv->header_offset = -1;
+ priv->openpgp_begin = GMIME_OPENPGP_DATA_NONE;
+ priv->openpgp_end = GMIME_OPENPGP_DATA_NONE;
+
priv->midline = FALSE;
priv->seekable = offset != -1;
@@ -1393,7 +1410,9 @@ check_boundary (struct _GMimeParserPrivate *priv, const char *start, size_t len)
{
gint64 offset = parser_offset (priv, start);
const char *marker;
+ BoundaryStack *s;
size_t mlen;
+ guint i;
switch (priv->format) {
case GMIME_FORMAT_MBOX: marker = MBOX_BOUNDARY; mlen = MBOX_BOUNDARY_LEN; break;
@@ -1404,29 +1423,46 @@ check_boundary (struct _GMimeParserPrivate *priv, const char *start, size_t len)
if (len > 0 && start[len - 1] == '\r')
len--;
- if (possible_boundary (marker, mlen, start, len)) {
- BoundaryStack *s;
+ if (!possible_boundary (marker, mlen, start, len))
+ return FOUND_NOTHING;
+
+ d(printf ("checking boundary '%.*s'\n", len, start));
+
+ s = priv->bounds;
+ while (s) {
+ if (offset >= s->content_end &&
+ is_boundary (priv, start, len, s->boundary, s->boundarylenfinal)) {
+ d(printf ("found %s\n", s->content_end != -1 && offset >= s->content_end ?
+ "end of content" : "end boundary"));
+ return FOUND_END_BOUNDARY;
+ }
- d(printf ("checking boundary '%.*s'\n", len, start));
+ if (is_boundary (priv, start, len, s->boundary, s->boundarylen)) {
+ d(printf ("found boundary\n"));
+ return FOUND_BOUNDARY;
+ }
- s = priv->bounds;
- while (s) {
- if (offset >= s->content_end &&
- is_boundary (priv, start, len, s->boundary, s->boundarylenfinal)) {
- d(printf ("found %s\n", s->content_end != -1 && offset >= s->content_end ?
- "end of content" : "end boundary"));
- return FOUND_END_BOUNDARY;
- }
-
- if (is_boundary (priv, start, len, s->boundary, s->boundarylen)) {
- d(printf ("found boundary\n"));
- return FOUND_BOUNDARY;
- }
+ s = s->parent;
+ }
+
+ d(printf ("'%.*s' not a boundary\n", len, start));
+
+ if (!strncmp (start, "--", 2)) {
+ start += 2;
+ len -= 2;
+
+ /* check for OpenPGP markers... */
+ for (i = 0; i < G_N_ELEMENTS (openpgp_markers); i++) {
+ size_t begin_len = openpgp_markers[i].begin_len - 2;
+ const char *begin = openpgp_markers[i].begin + 2;
+ size_t end_len = openpgp_markers[i].end_len - 2;
+ const char *end = openpgp_markers[i].end + 2;
- s = s->parent;
+ if (len == begin_len && !strncmp (begin, start, len))
+ priv->openpgp_begin = (GMimeOpenPGPData) (i + 1);
+ else if (len == end_len && !strncmp (end, start, len))
+ priv->openpgp_end = (GMimeOpenPGPData) (i + 1);
}
-
- d(printf ("'%.*s' not a boundary\n", len, start));
}
return FOUND_NOTHING;
@@ -1476,6 +1512,8 @@ parser_scan_content (GMimeParser *parser, GByteArray *content, guint *crlf)
d(printf ("scan-content\n"));
+ priv->openpgp_begin = GMIME_OPENPGP_DATA_NONE;
+ priv->openpgp_end = GMIME_OPENPGP_DATA_NONE;
priv->midline = FALSE;
g_assert (priv->inptr <= priv->inend);
@@ -1615,6 +1653,9 @@ parser_scan_mime_part_content (GMimeParser *parser, GMimePart *mime_part, int *f
g_mime_part_set_content (mime_part, wrapper);
g_object_unref (wrapper);
g_object_unref (stream);
+
+ if (priv->openpgp_begin && priv->openpgp_begin == priv->openpgp_end)
+ g_mime_part_set_openpgp_data (mime_part, priv->openpgp_begin);
}
static void
diff --git a/gmime/gmime-part.c b/gmime/gmime-part.c
index 91dd1a0..ea06c6d 100644
--- a/gmime/gmime-part.c
+++ b/gmime/gmime-part.c
@@ -916,6 +916,41 @@ g_mime_part_get_filename (GMimePart *mime_part)
}
+/**
+ * g_mime_part_set_openpgp_data:
+ * @mime_part: a #GMimePart
+ * @data: a #GMimeOpenPGPData
+ *
+ * Sets whether or not (and what type) of OpenPGP data is contained
+ * within the #GMimePart.
+ **/
+void
+g_mime_part_set_openpgp_data (GMimePart *mime_part, GMimeOpenPGPData data)
+{
+ g_return_if_fail (GMIME_IS_PART (mime_part));
+
+ mime_part->openpgp = data;
+}
+
+
+/**
+ * g_mime_part_get_openpgp_data:
+ * @mime_part: a #GMimePart
+ *
+ * Gets whether or not (and what type) of OpenPGP data is contained
+ * within the #GMimePart.
+ *
+ * Returns: a #GMimeOpenPGPData.
+ **/
+GMimeOpenPGPData
+g_mime_part_get_openpgp_data (GMimePart *mime_part)
+{
+ g_return_val_if_fail (GMIME_IS_PART (mime_part), GMIME_OPENPGP_DATA_NONE);
+
+ return mime_part->openpgp;
+}
+
+
static void
set_content (GMimePart *mime_part, GMimeDataWrapper *content)
{
diff --git a/gmime/gmime-part.h b/gmime/gmime-part.h
index 0391eef..38a9098 100644
--- a/gmime/gmime-part.h
+++ b/gmime/gmime-part.h
@@ -43,9 +43,24 @@ typedef struct _GMimePart GMimePart;
typedef struct _GMimePartClass GMimePartClass;
/**
+ * GMimeOpenPGPData:
+ * @GMIME_OPENPGP_DATA_NONE: The #GMimePart does not contain any OpenPGP data.
+ * @GMIME_OPENPGP_DATA_ENCRYPTED: The #GMimePart contains OpenPGP encrypted data.
+ * @GMIME_OPENPGP_DATA_SIGNED: The #GMimePart contains OpenPGP signed data.
+ *
+ * The type of OpenPGP data contained within the content of the #GMimePart, if any.
+ **/
+typedef enum {
+ GMIME_OPENPGP_DATA_NONE,
+ GMIME_OPENPGP_DATA_ENCRYPTED,
+ GMIME_OPENPGP_DATA_SIGNED
+} GMimeOpenPGPData;
+
+/**
* GMimePart:
* @parent_object: parent #GMimeObject
* @encoding: a #GMimeContentEncoding
+ * @openpgp: a #GMimeOpenPGPData
* @content_description: Content-Description string
* @content_location: Content-Location string
* @content_md5: Content-MD5 string
@@ -57,6 +72,7 @@ struct _GMimePart {
GMimeObject parent_object;
GMimeContentEncoding encoding;
+ GMimeOpenPGPData openpgp;
char *content_description;
char *content_location;
char *content_md5;
@@ -101,6 +117,9 @@ gboolean g_mime_part_is_attachment (GMimePart *mime_part);
void g_mime_part_set_filename (GMimePart *mime_part, const char *filename);
const char *g_mime_part_get_filename (GMimePart *mime_part);
+void g_mime_part_set_openpgp_data (GMimePart *mime_part, GMimeOpenPGPData data);
+GMimeOpenPGPData g_mime_part_get_openpgp_data (GMimePart *mime_part);
+
void g_mime_part_set_content (GMimePart *mime_part, GMimeDataWrapper *content);
GMimeDataWrapper *g_mime_part_get_content (GMimePart *mime_part);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]