* Copyright (C) 2007, 2008 g10 Code GmbH
*
* This file is part of GpgOL.
- *
+ *
* GpgOL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* GpgOL 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 Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#define COBJMACROS
#include <windows.h>
-#include <objidl.h>
+#include <objidl.h>
#include "mymapi.h"
#include "mymapitags.h"
{0x2A, 0x86, 0x48, 0x86, 0xf7, 0x14, 0x03, 0x0a, 0x04};
/* The base-64 list used for base64 encoding. */
-static unsigned char bintoasc[64+1] = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789+/");
+static unsigned char bintoasc[64+1] = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/");
/* The object we use instead of IStream. It allows us to have a
callback method for output and thus for processing stuff
if (hr)
{
log_error ("%s:%s: can't create attachment: hr=%#lx\n",
- SRCNAME, __func__, hr);
+ SRCNAME, __func__, hr);
return NULL;
}
if (hr)
{
log_error ("%s:%s: can't set attach method: hr=%#lx\n",
- SRCNAME, __func__, hr);
+ SRCNAME, __func__, hr);
goto failure;
}
if (get_gpgolattachtype_tag (message, &prop.ulPropTag) )
goto failure;
prop.Value.l = ATTACHTYPE_MOSSTEMPL;
- hr = HrSetOneProp ((LPMAPIPROP)att, &prop);
+ hr = HrSetOneProp ((LPMAPIPROP)att, &prop);
if (hr)
{
log_error ("%s:%s: can't set %s property: hr=%#lx\n",
- SRCNAME, __func__, "GpgOL Attach Type", hr);
+ SRCNAME, __func__, "GpgOL Attach Type", hr);
goto failure;
}
if (hr)
{
log_error ("%s:%s: can't set attach filename: hr=%#lx\n",
- SRCNAME, __func__, hr);
+ SRCNAME, __func__, hr);
goto failure;
}
if (hr)
{
log_error ("%s:%s: can't set attach mime tag: hr=%#lx\n",
- SRCNAME, __func__, hr);
+ SRCNAME, __func__, hr);
goto failure;
}
-
+
punk = NULL;
hr = IAttach_OpenProperty (att, PR_ATTACH_DATA_BIN, &IID_IStream, 0,
(MAPI_CREATE|MAPI_MODIFY), &punk);
- if (FAILED (hr))
+ if (FAILED (hr))
{
log_error ("%s:%s: can't create output stream: hr=%#lx\n",
- SRCNAME, __func__, hr);
+ SRCNAME, __func__, hr);
goto failure;
}
sink->cb_data = (LPSTREAM)punk;
/* Write data to a sink_t. */
-static int
+static int
write_buffer (sink_t sink, const void *data, size_t datalen)
{
if (!sink || !sink->writefnc)
/* Write the string TEXT to the IStream STREAM. Returns 0 on sucsess,
prints an error message and returns -1 on error. */
-static int
+static int
write_string (sink_t sink, const char *text)
{
return write_buffer (sink, text, strlen (text));
va_list arg_ptr;
int rc;
const char *s;
-
+
va_start (arg_ptr, text1);
s = text1;
do
|((inbuf[2]>>6)&03))&077];
outbuf[outlen++] = bintoasc[inbuf[2]&077];
idx = 0;
- if (++quads >= (64/4))
+ if (++quads >= (64/4))
{
quads = 0;
outbuf[outlen++] = '\r';
outbuf[outlen++] = '=';
outbuf[outlen++] = '=';
}
- else
- {
+ else
+ {
outbuf[outlen++] = bintoasc[(((*inbuf<<4)&060)
|((inbuf[1]>>4)&017))&077];
outbuf[outlen++] = bintoasc[((inbuf[1]<<2)&074)&077];
outbuf[outlen++] = '=';
}
- if ((rc = write_buffer (sink, outbuf, 4)))
- return rc;
++quads;
}
- if (quads)
+ if (quads)
{
outbuf[outlen++] = '\r';
outbuf[outlen++] = '\n';
outidx = 0; \
} \
} while (0)
-
+
log_debug (" writing qp of length %d\n", (int)datalen);
outidx = 0;
for (p = data; datalen; p++, datalen--)
}
}
else if (!outidx && *p == '.'
- && ( (datalen > 2 && p[1] == '\r' && p[2] == '\n')
- || (datalen > 1 && p[1] == '\n')
+ && ( (datalen > 2 && p[1] == '\r' && p[2] == '\n')
+ || (datalen > 1 && p[1] == '\n')
|| datalen == 1))
{
/* Better protect a line with just a single dot. We do
have been used. */
log_error ("%s:%s: BUG: line longer than exepcted",
SRCNAME, __func__);
- return -1;
+ return -1;
}
else
outbuf[outidx++] = *p;
char b64;
const char *suffix;
const char *ct;
- } suffix_table[] =
+ } suffix_table[] =
{
{ 1, "3gp", "video/3gpp" },
{ 1, "abw", "application/x-abiword" },
lowbin++;
else if (len == 1 && datalen > 2
&& *p == '-' && p[1] == '-' && p[2] == ' '
- && ( (datalen > 4 && p[3] == '\r' && p[4] == '\n')
- || (datalen > 3 && p[3] == '\n')
+ && ( (datalen > 4 && p[3] == '\r' && p[4] == '\n')
+ || (datalen > 3 && p[3] == '\n')
|| datalen == 3))
{
/* This is a "-- \r\n" line, thus it indicates the usual
identical we use that value to behave closely to it. */
if (ntotal && ((float)(lowbin+highbin))/ntotal < 0.20)
return 1; /* Use quoted printable. */
-
+
return 2; /* Use base64. */
}
that there might be slashes or backslashes. */
const char *s1 = strrchr (filename, '/');
const char *s2 = strrchr (filename, '\\');
-
+
if (!s1)
s1 = s2;
else if (s1 && s2 && s2 > s1)
}
log_debug ("Writing part of length %d%s filename=`%s'\n",
- (int)datalen, is_mapibody? " (body)":"",
+ (int)datalen, is_mapibody? " (body)":"",
filename?filename:"[none]");
ct = infer_content_type (data, datalen, filename, is_mapibody, &use_b64);
use_qp? "quoted-printable\r\n":"7bit\r\n"),
NULL)))
return rc;
-
+
if (filename)
if ((rc=write_multistring (sink,
"Content-Disposition: attachment;\r\n"
NULL)))
return rc;
-
+
/* Write delimiter. */
if ((rc = write_string (sink, "\r\n")))
return rc;
-
+
/* Write the content. */
if (use_b64)
rc = write_b64 (sink, data, datalen);
count_usable_attachments (mapi_attach_item_t *table)
{
int idx, count = 0;
-
+
if (table)
for (idx=0; !table[idx].end_of_table; idx++)
if (table[idx].attach_type == ATTACHTYPE_UNKNOWN
/* Write out all attachments from TABLE separated by BOUNDARY to SINK.
This function needs to be syncronized with count_usable_attachments. */
static int
-write_attachments (sink_t sink,
- LPMESSAGE message, mapi_attach_item_t *table,
+write_attachments (sink_t sink,
+ LPMESSAGE message, mapi_attach_item_t *table,
const char *boundary)
{
int idx, rc;
if (hr)
{
log_error ("%s:%s: DeleteAttach failed: hr=%#lx\n",
- SRCNAME, __func__, hr);
+ SRCNAME, __func__, hr);
return -1;
}
}
if (hr)
{
log_error ("%s:%s: SaveChanges of the attachment failed: hr=%#lx\n",
- SRCNAME, __func__, hr);
+ SRCNAME, __func__, hr);
return -1;
}
IAttach_Release (*attach);
/* Set the message class. */
prop.ulPropTag = PR_MESSAGE_CLASS_A;
- prop.Value.lpszA = "IPM.Note.SMIME.MultipartSigned";
+ prop.Value.lpszA = "IPM.Note.SMIME.MultipartSigned";
hr = IMessage_SetProps (message, 1, &prop, NULL);
if (hr)
{
property. This override is at least required for encrypted
messages. */
if (mapi_set_gpgol_msg_class (message,
- (encrypt?
- (protocol == PROTOCOL_SMIME?
+ (encrypt?
+ (protocol == PROTOCOL_SMIME?
"IPM.Note.GpgOL.OpaqueEncrypted" :
"IPM.Note.GpgOL.MultipartEncrypted") :
"IPM.Note.GpgOL.MultipartSigned")))
log_error ("%s:%s: sink not setup for writing", SRCNAME, __func__);
return -1;
}
-
+
rc = engine_filter (filter, data, datalen);
if (!rc && data && datalen)
write_buffer (hashsink->extrasink, data, datalen);
attachment table at R_ATT_TABLE or sets this to NULL on error. If
TMPSINK is set no attachment will be created but the output
written to that sink. */
-static int
-do_mime_sign (LPMESSAGE message, HWND hwnd, protocol_t protocol,
+static int
+do_mime_sign (LPMESSAGE message, HWND hwnd, protocol_t protocol,
mapi_attach_item_t **r_att_table, sink_t tmpsink,
unsigned int session_number)
{
attachment or more than one attachment. */
if ((body && n_att_usable) || n_att_usable > 1)
generate_boundary (inner_boundary);
- else
+ else
*inner_boundary = 0;
/* Write the boundary so that it is not included in the hashing. */
header, thus we do the same to avoid running all through an
IConverterSession first. */
if (*inner_boundary
- && (rc=write_multistring (hashsink,
+ && (rc=write_multistring (hashsink,
"Content-Type: multipart/mixed;\r\n",
"\tboundary=\"", inner_boundary, "\"\r\n",
"\r\n", /* <-- extra line */
goto failure;
filter = NULL; /* Not valid anymore. */
hashsink->cb_data = NULL; /* Not needed anymore. */
-
+
/* Write signature attachment. */
if ((rc = write_boundary (sink, boundary, 0)))
/* Write the signature. We add an extra CR,LF which should not harm
and a terminating 0. */
- collect_signature (&sigbuffer, "\r\n", 3);
+ collect_signature (&sigbuffer, "\r\n", 3);
if ((rc = write_string (sink, sigbuffer.buf)))
goto failure;
PGP or S/MIME) signed message. On failure the function tries to
keep the original message intact but there is no 100% guarantee for
it. */
-int
+int
mime_sign (LPMESSAGE message, HWND hwnd, protocol_t protocol)
{
int result = -1;
mapi_attach_item_t *att_table;
- result = do_mime_sign (message, hwnd, protocol, &att_table, 0,
+ result = do_mime_sign (message, hwnd, protocol, &att_table, 0,
engine_new_session_number ());
if (!result)
{
outbuf[2] = '=';
outbuf[3] = '=';
}
- else
- {
+ else
+ {
outbuf[1] = bintoasc[(((*inbuf<<4)&060)|
((inbuf[1]>>4)&017))&077];
outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077];
outbuflen = 4;
quads++;
}
-
+
if (quads)
{
outbuf[outbuflen++] = '\r';
|((inbuf[2]>>6)&03))&077];
outbuf[3] = bintoasc[inbuf[2]&077];
outbuflen = 4;
- if (++quads >= (64/4))
+ if (++quads >= (64/4))
{
quads = 0;
outbuf[4] = '\r';
encsink->b64.idx = idx;
memcpy (encsink->b64.inbuf, inbuf, idx);
encsink->b64.quads = quads;
-
+
return 0;
}
#endif /*Not used.*/
"Version: 1\r\n", NULL);
if (rc)
return rc;
-
+
/* And start the second part. */
rc = write_boundary (sink, boundary, 0);
if (rc)
/* Encrypt the MESSAGE. */
-int
-mime_encrypt (LPMESSAGE message, HWND hwnd,
+int
+mime_encrypt (LPMESSAGE message, HWND hwnd,
protocol_t protocol, char **recipients)
{
int result = -1;
/* Create a new sink for encrypting the following stuff. */
encsink->cb_data = filter;
encsink->writefnc = sink_encryption_write;
-
+
if ((body && n_att_usable) || n_att_usable > 1)
{
/* A body and at least one attachment or more than one attachment */
generate_boundary (inner_boundary);
- if ((rc=write_multistring (encsink,
+ if ((rc=write_multistring (encsink,
"Content-Type: multipart/mixed;\r\n",
"\tboundary=\"", inner_boundary, "\"\r\n",
NULL)))
*inner_boundary = 0;
if (body)
- rc = write_part (encsink, body, strlen (body),
+ rc = write_part (encsink, body, strlen (body),
*inner_boundary? inner_boundary : NULL, NULL, 1);
if (!rc && n_att_usable)
rc = write_attachments (encsink, message, att_table,
/* Write the final boundary (for OpenPGP) and finish the attachment. */
if (*boundary && (rc = write_boundary (sink, boundary, 1)))
goto failure;
-
+
if (close_mapi_attachment (&attach, sink))
goto failure;
\f
/* Sign and Encrypt the MESSAGE. */
-int
-mime_sign_encrypt (LPMESSAGE message, HWND hwnd,
+int
+mime_sign_encrypt (LPMESSAGE message, HWND hwnd,
protocol_t protocol, char **recipients)
{
int result = -1;
}
- /* Create a temporary sink to construct the signed data. */
+ /* Create a temporary sink to construct the signed data. */
hr = OpenStreamOnFile (MAPIAllocateBuffer, MAPIFreeBuffer,
(SOF_UNIQUEFILENAME | STGM_DELETEONRELEASE
| STGM_CREATE | STGM_READWRITE),
- NULL, "GPG", &tmpstream);
- if (FAILED (hr))
+ NULL, "GPG", &tmpstream);
+ if (FAILED (hr))
{
log_error ("%s:%s: can't create temp file: hr=%#lx\n",
- SRCNAME, __func__, hr);
+ SRCNAME, __func__, hr);
rc = -1;
goto failure;
}
}
sender = mapi_get_sender (message);
- if ((rc=engine_encrypt_prepare (filter, hwnd,
+ if ((rc=engine_encrypt_prepare (filter, hwnd,
protocol, ENGINE_FLAG_SIGN_FOLLOWS,
sender, recipients, &protocol)))
goto failure;
we need to fix up that ugly micalg parameter after having created
the signature. Note that the protocol to use is taken from the
encryption operation. */
- if (do_mime_sign (message, hwnd, protocol, &att_table, tmpsink,
+ if (do_mime_sign (message, hwnd, protocol, &att_table, tmpsink,
session_number))
goto failure;
hr = IStream_Read (tmpstream, buffer, sizeof buffer, &nread);
if (hr)
{
- log_error ("%s:%s: IStream::Read failed: hr=%#lx",
+ log_error ("%s:%s: IStream::Read failed: hr=%#lx",
SRCNAME, __func__, hr);
rc = gpg_error (GPG_ERR_EIO);
goto failure;
rc = write_buffer (encsink, buffer, nread);
if (rc)
{
- log_error ("%s:%s: writing tmpstream to encsink failed: %s",
+ log_error ("%s:%s: writing tmpstream to encsink failed: %s",
SRCNAME, __func__, gpg_strerror (rc));
goto failure;
}
log_debug ("%s:%s: nothing received from engine", SRCNAME, __func__);
goto failure;
}
-
+
/* Write the final boundary (for OpenPGP) and finish the attachment. */
if (*boundary && (rc = write_boundary (sink, boundary, 1)))
goto failure;
-
+
if (close_mapi_attachment (&attach, sink))
goto failure;
failure:
if (result)
- log_debug ("%s:%s: failed rc=%d (%s) <%s>", SRCNAME, __func__, rc,
+ log_debug ("%s:%s: failed rc=%d (%s) <%s>", SRCNAME, __func__, rc,
gpg_strerror (rc), gpg_strsource (rc));
engine_cancel (filter);
if (tmpstream)