Esempio n. 1
0
static gboolean
request_passwd (GMimeCryptoContext *ctx, const char *user_id, const char *prompt, gboolean reprompt, GMimeStream *response, GError **err)
{
	g_mime_stream_write_string (response, "no.secret\n");
	
	return TRUE;
}
Esempio n. 2
0
static gboolean
password_requester (GMimeCryptoContext *ctx, const char *user_id,
		    const char* prompt_ctx, gboolean reprompt,
		    GMimeStream *response, GError **err)
{
	CallbackData *cbdata;
	gchar *password;
	ssize_t written;

	cbdata = g_object_get_data (G_OBJECT(ctx), CALLBACK_DATA);
	if (!cbdata || !cbdata->pw_func)
		return FALSE;

	password = cbdata->pw_func (user_id, prompt_ctx, reprompt,
				    cbdata->user_data);
	if (!password) {
		mu_util_g_set_error (err, MU_ERROR_CRYPTO,
				     "failed to get password");
		return FALSE;
	}

	written = g_mime_stream_write_string (response, password);
	if (written != -1)
		written = g_mime_stream_write_string (response, "\n");
	if (written == -1)
		mu_util_g_set_error (err, MU_ERROR_CRYPTO,
				     "writing password to mime stream failed");

	/* it seems that GMime tries to flush the fd; however, this
	 * does not work for pipes/sockets, causing getting a password
	 * to fail.
	 *
	 * I have reported this, and it has been fixed now:
	 *
	 * http://git.gnome.org/browse/gmime/commit/
	 *      ?id=bda4834d3d9a1fbefb6d97edfef2bc1da9357f58
	 *
	 * however, it may take a while before everybody has this
	 * version of GMime (ie. version > 2.6.10)
	 *
	 */

	memset (password, 0, strlen(password));
	g_free (password);

	return written != -1 ? TRUE : FALSE;
}
static ssize_t
default_writer (GMimeStream *stream, const char *name, const char *value)
{
	ssize_t nwritten;
	char *val;
	
	val = g_mime_utils_header_printf ("%s: %s\n", name, value);
	nwritten = g_mime_stream_write_string (stream, val);
	g_free (val);
	
	return nwritten;
}
Esempio n. 4
0
static gboolean
password_requester (GMimeCryptoContext *ctx, const char *user_id,
		    const char* prompt_ctx, gboolean reprompt,
		    GMimeStream *response, GError **err)
{
	CallbackData *cbdata;
	gchar *password;
	ssize_t written;

	cbdata = g_object_get_data (G_OBJECT(ctx), CALLBACK_DATA);
	if (!cbdata || !cbdata->pw_func)
		return FALSE;

	password = cbdata->pw_func (user_id, prompt_ctx, reprompt,
				    cbdata->user_data);
	if (!password) {
		mu_util_g_set_error (err, MU_ERROR_CRYPTO,
				     "failed to get password");
		return FALSE;
	}

	written = g_mime_stream_write_string (response, password);
	if (written != -1)
		written = g_mime_stream_write_string (response, "\n");
	if (written == -1)
		mu_util_g_set_error (err, MU_ERROR_CRYPTO,
			             "writing password to mime stream failed");

	if (g_mime_stream_flush (response) != 0)
		g_printerr ("error flushing stream\n");

	memset (password, 0, strlen(password));
	g_free (password);

	return written != -1 ? TRUE : FALSE;
}
Esempio n. 5
0
static ssize_t
message_part_write_to_stream (GMimeObject *object, GMimeFormatOptions *options, gboolean content_only, GMimeStream *stream)
{
	GMimeMessagePart *part = (GMimeMessagePart *) object;
	GMimeMessage *message = part->message;
	ssize_t nwritten, total = 0;
	const char *newline, *eoln;
	gboolean match;
	size_t len;
	
	newline = g_mime_format_options_get_newline (options);
	
	if (!content_only) {
		/* write the content headers */
		if ((nwritten = g_mime_header_list_write_to_stream (object->headers, options, stream)) == -1)
			return -1;
		
		total += nwritten;
		
		/* terminate the headers */
		if ((nwritten = g_mime_stream_write_string (stream, newline)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	/* write the message */
	if (message) {
		if (message->marker && (len = strlen (message->marker)) > 0) {
			if (*(eoln = message->marker + (len - 1)) == '\n') {
				if (eoln > message->marker && eoln[-1] == '\r')
					eoln--;
				
				/* check if newline sequences match... */
				if (!(match = !strcmp (eoln, newline))) {
					/* they don't match... trim off the eoln sequence */
					len = (size_t) (eoln - message->marker);
				}
			} else {
				match = FALSE;
			}
			
			if ((nwritten = g_mime_stream_write (stream, message->marker, len)) == -1)
				return -1;
			
			total += nwritten;
			
			if (!match) {
				if ((nwritten = g_mime_stream_write_string (stream, newline)) == -1)
					return -1;
				
				total += nwritten;
			}
		}
		
		if ((nwritten = g_mime_object_write_to_stream ((GMimeObject *) message, options, stream)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	return total;
}
Esempio n. 6
0
static ssize_t
multipart_write_to_stream (GMimeObject *object, GMimeStream *stream)
{
	GMimeMultipart *multipart = (GMimeMultipart *) object;
	ssize_t nwritten, total = 0;
	const char *boundary;
	GMimeObject *part;
	guint i;
	
	/* make sure a boundary is set unless we are writing out a raw
	 * header (in which case it should already be set... or if
	 * not, then it's a broken multipart and so we don't want to
	 * alter it or we'll completely break the output) */
	boundary = g_mime_object_get_content_type_parameter (object, "boundary");
	if (!boundary && !g_mime_header_list_get_stream (object->headers)) {
		g_mime_multipart_set_boundary (multipart, NULL);
		boundary = g_mime_object_get_content_type_parameter (object, "boundary");
	}
	
	/* write the content headers */
	if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
		return -1;
	
	total += nwritten;
	
	/* write the preface */
	if (multipart->preface) {
		/* terminate the headers */
		if (g_mime_stream_write (stream, "\n", 1) == -1)
			return -1;
		
		total++;
		
		if ((nwritten = g_mime_stream_write_string (stream, multipart->preface)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	for (i = 0; i < multipart->children->len; i++) {
		part = multipart->children->pdata[i];
		
		/* write the boundary */
		if ((nwritten = g_mime_stream_printf (stream, "\n--%s\n", boundary)) == -1)
			return -1;
		
		total += nwritten;
		
		/* write this part out */
		if ((nwritten = g_mime_object_write_to_stream (part, stream)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	/* write the end-boundary (but only if a boundary is set) */
	if (boundary) {
		if ((nwritten = g_mime_stream_printf (stream, "\n--%s--\n", boundary)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	/* write the postface */
	if (multipart->postface) {
		if ((nwritten = g_mime_stream_write_string (stream, multipart->postface)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	return total;
}
Esempio n. 7
0
int main (int argc, char **argv)
{
#ifdef ENABLE_CRYPTO
	const char *datadir = "data/pgp";
	GMimeStream *istream, *ostream;
	GMimeFilterOpenPGP *filter;
	GMimeCryptoContext *ctx;
	const char *what;
	char *gpg, *key;
	struct stat st;
	int i;
	
	g_mime_init ();
	
	testsuite_init (argc, argv);
	
	if (!(gpg = g_find_program_in_path ("gpg2")))
		if (!(gpg = g_find_program_in_path ("gpg")))
			return EXIT_FAILURE;
	
	if (testsuite_setup_gpghome (gpg) != 0)
		return EXIT_FAILURE;
	
	g_free (gpg);
	
	for (i = 1; i < argc; i++) {
		if (argv[i][0] != '-') {
			datadir = argv[i];
			break;
		}
	}
	
	if (i < argc && (stat (datadir, &st) == -1 || !S_ISDIR (st.st_mode)))
		return 0;
	
	testsuite_start ("GnuPG crypto context");
	
	ctx = g_mime_gpg_context_new ();
	g_mime_crypto_context_set_request_password (ctx, request_passwd);
	
	testsuite_check ("GMimeGpgContext::import");
	try {
		key = g_build_filename (datadir, "gmime.gpg.pub", NULL);
		import_key (ctx, key);
		g_free (key);
		
		key = g_build_filename (datadir, "gmime.gpg.sec", NULL);
		import_key (ctx, key);
		g_free (key);
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("GMimeGpgContext::import failed: %s", ex->message);
		return EXIT_FAILURE;
	} finally;
	
	key = g_build_filename (datadir, "gmime.gpg.pub", NULL);
	testsuite_check ("GMimeGpgContext::export");
	try {
		test_export (ctx, key);
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("GMimeGpgContext::export failed: %s", ex->message);
	} finally;
	
	g_free (key);
	
	istream = g_mime_stream_mem_new ();
	ostream = g_mime_stream_mem_new ();
	
	g_mime_stream_write_string (istream, "this is some cleartext\r\n");
	g_mime_stream_reset (istream);
	
	what = "GMimeGpgContext::sign";
	testsuite_check ("%s", what);
	try {
		test_sign (ctx, FALSE, istream, ostream);
		testsuite_check_passed ();
		
		what = "GMimeGpgContext::verify";
		testsuite_check ("%s", what);
		g_mime_stream_reset (istream);
		g_mime_stream_reset (ostream);
		test_verify (ctx, istream, ostream);
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("%s failed: %s", what, ex->message);
	} finally;
	
	g_object_unref (ostream);
	g_mime_stream_reset (istream);
	ostream = g_mime_stream_mem_new ();
	
	what = "GMimeGpgContext::sign (detached)";
	testsuite_check ("%s", what);
	try {
		test_sign (ctx, TRUE, istream, ostream);
		testsuite_check_passed ();
		
		what = "GMimeGpgContext::verify (detached)";
		testsuite_check ("%s", what);
		g_mime_stream_reset (istream);
		g_mime_stream_reset (ostream);
		test_verify_detached (ctx, istream, ostream);
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("%s failed: %s", what, ex->message);
	} finally;
	
	g_object_unref (ostream);
	g_mime_stream_reset (istream);
	ostream = g_mime_stream_mem_new ();
	
	what = "GMimeGpgContext::encrypt";
	testsuite_check ("%s", what);
	try {
		test_encrypt (ctx, FALSE, istream, ostream);
		testsuite_check_passed ();
		
		what = "GMimeGpgContext::decrypt";
		testsuite_check ("%s", what);
		g_mime_stream_reset (istream);
		g_mime_stream_reset (ostream);
		test_decrypt (ctx, FALSE, istream, ostream);
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("%s failed: %s", what, ex->message);
	} finally;
	
	g_object_unref (ostream);
	g_mime_stream_reset (istream);
	ostream = g_mime_stream_mem_new ();
	
	what = "GMimeGpgContext::encrypt+sign";
	testsuite_check ("%s", what);
	try {
		test_encrypt (ctx, TRUE, istream, ostream);
		testsuite_check_passed ();
		
		what = "GMimeGpgContext::decrypt+verify";
		testsuite_check ("%s", what);
		g_mime_stream_reset (istream);
		g_mime_stream_reset (ostream);
		test_decrypt (ctx, TRUE, istream, ostream);
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("%s failed: %s", what, ex->message);
	} finally;
	
	g_object_unref (istream);
	g_object_unref (ostream);
	g_object_unref (ctx);

	filter = (GMimeFilterOpenPGP *) g_mime_filter_openpgp_new ();
	
	what = "GMimeFilterOpenPGP::public key block";
	testsuite_check ("%s", what);
	try {
		key = g_build_filename (datadir, "gmime.gpg.pub", NULL);
		test_openpgp_filter (filter, key, GMIME_OPENPGP_DATA_PUBLIC_KEY, 0, 1720);
		g_free (key);
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("%s failed: %s", what, ex->message);
	} finally;
	
	g_mime_filter_reset ((GMimeFilter *) filter);
	
	what = "GMimeFilterOpenPGP::private key block";
	testsuite_check ("%s", what);
	try {
		key = g_build_filename (datadir, "gmime.gpg.sec", NULL);
		test_openpgp_filter (filter, key, GMIME_OPENPGP_DATA_PRIVATE_KEY, 0, 1928);
		g_free (key);
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("%s failed: %s", what, ex->message);
	} finally;
	
	g_mime_filter_reset ((GMimeFilter *) filter);
	
	what = "GMimeFilterOpenPGP::signed message block";
	testsuite_check ("%s", what);
	try {
		key = g_build_filename (datadir, "signed-message.txt", NULL);
		test_openpgp_filter (filter, key, GMIME_OPENPGP_DATA_SIGNED, 162, 440);
		g_free (key);
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("%s failed: %s", what, ex->message);
	} finally;
	
	g_mime_filter_reset ((GMimeFilter *) filter);
	
	what = "GMimeFilterOpenPGP::encrypted message block";
	testsuite_check ("%s", what);
	try {
		key = g_build_filename (datadir, "encrypted-message.txt", NULL);
		test_openpgp_filter (filter, key, GMIME_OPENPGP_DATA_ENCRYPTED, 165, 1084);
		g_free (key);
		
		testsuite_check_passed ();
	} catch (ex) {
		testsuite_check_failed ("%s failed: %s", what, ex->message);
	} finally;
	
	g_object_unref (filter);
	
	testsuite_end ();
	
	g_mime_shutdown ();
	
	if (testsuite_destroy_gpghome () != 0)
		return EXIT_FAILURE;
	
	return testsuite_exit ();
#else
	fprintf (stderr, "PGP support not enabled in this build.\n");
	return EXIT_SUCCESS;
#endif
}
Esempio n. 8
0
static int
uuencode (const char *progname, int argc, char **argv)
{
	GMimeStream *istream, *ostream, *fstream;
	GMimeContentEncoding encoding;
	const char *filename, *name;
	GMimeFilter *filter;
	gboolean base64;
	struct stat st;
	int fd, opt;
	
	base64 = FALSE;
	encoding = GMIME_CONTENT_ENCODING_UUENCODE;
	while ((opt = getopt_long (argc, argv, "hvm", longopts, NULL)) != -1) {
		switch (opt) {
		case 'h':
			usage (progname);
			return 0;
		case 'v':
			version (progname);
			return 0;
		case 'm':
			base64 = TRUE;
			encoding = GMIME_CONTENT_ENCODING_BASE64;
			break;
		default:
			printf ("Try `%s --help' for more information.\n", progname);
			return -1;
		}
	}
	
	if (optind >= argc) {
		printf ("Try `%s --help' for more information.\n", progname);
		return -1;
	}
	
	if (optind + 1 < argc)
		filename = argv[optind++];
	else
		filename = NULL;
	
	name = argv[optind];
	
	/* open our input file... */
	if ((fd = filename ? open (filename, O_RDONLY, 0) : dup (0)) == -1) {
		fprintf (stderr, "%s: %s: %s\n", progname,
			 filename ? filename : "stdin",
			 g_strerror (errno));
		return -1;
	}
	
	/* stat() our input file for file mode permissions */
	if (fstat (fd, &st) == -1) {
		fprintf (stderr, "%s: %s: %s\n", progname,
			 filename ? filename : "stdin",
			 g_strerror (errno));
		close (fd);
		return -1;
	}
	
	printf ("begin%s %.3o %s\n", base64 ? "-base64" : "", st.st_mode & 0777, name);
	fflush (stdout);
	
	istream = g_mime_stream_fs_new (fd);
	
	/* open our output stream */
	ostream = g_mime_stream_fs_new (1);
	g_mime_stream_fs_set_owner ((GMimeStreamFs *) ostream, FALSE);
	
	fstream = g_mime_stream_filter_new (ostream);
	
	/* attach an encode filter */
	filter = g_mime_filter_basic_new (encoding, TRUE);
	g_mime_stream_filter_add ((GMimeStreamFilter *) fstream, filter);
	g_object_unref (filter);
	
	if (g_mime_stream_write_to_stream (istream, fstream) == -1) {
		fprintf (stderr, "%s: %s\n", progname, g_strerror (errno));
		g_object_unref (fstream);
		g_object_unref (istream);
		g_object_unref (ostream);
		return -1;
	}
	
	g_mime_stream_flush (fstream);
	g_object_unref (fstream);
	g_object_unref (istream);
	
	if (g_mime_stream_write_string (ostream, base64 ? "====\n" : "end\n") == -1) {
		fprintf (stderr, "%s: %s\n", progname, g_strerror (errno));
		g_object_unref (ostream);
		return -1;
	}
	
	g_object_unref (ostream);
	
	return 0;
}