|
|
@ -206,9 +206,61 @@ initialize_gpgme(void) |
|
|
|
errx(EXIT_FAILURE, "cannot initialize GPGME: %s", |
|
|
|
gpgme_strerror(gerr)); |
|
|
|
|
|
|
|
gpgme_set_armor(ctx, 1); |
|
|
|
|
|
|
|
return ctx; |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
sign_stream(gpgme_ctx_t ctx, FILE *in, FILE *out) |
|
|
|
{ |
|
|
|
gpgme_data_t gin, gout; |
|
|
|
char boundary[32], buffer[512]; |
|
|
|
int n; |
|
|
|
|
|
|
|
gpgme_data_new_from_stream(&gin, in); |
|
|
|
gpgme_data_new(&gout); |
|
|
|
|
|
|
|
gpgme_op_sign(ctx, gin, gout, GPGME_SIG_MODE_DETACH); |
|
|
|
|
|
|
|
generate_boundary(boundary, sizeof(boundary)); |
|
|
|
fprintf(out, "Content-Type: multipart/signed;\r\n" |
|
|
|
" boundary=\"%s\";\r\n" |
|
|
|
" protocol=\"application/pgp-signature\";\r\n" |
|
|
|
" micalg=pgp-sha1\r\n" |
|
|
|
"\r\n" |
|
|
|
"--%s\r\n", |
|
|
|
boundary, boundary); |
|
|
|
|
|
|
|
fseek(in, 0, SEEK_SET); |
|
|
|
while ( (n = fread(buffer, 1, sizeof(buffer), in)) > 0 ) |
|
|
|
fwrite(buffer, 1, n, out); |
|
|
|
|
|
|
|
fprintf(out, "\r\n" |
|
|
|
"--%s\r\n" |
|
|
|
"Content-Type: application/pgp-signature; name=signature.asc\r\n" |
|
|
|
"\r\n", |
|
|
|
boundary); |
|
|
|
|
|
|
|
gpgme_data_seek(gout, 0, SEEK_SET); |
|
|
|
while ( (n = gpgme_data_read(gout, buffer, sizeof(buffer))) > 0 ) { |
|
|
|
int i = 0; |
|
|
|
|
|
|
|
while ( i < n ) { |
|
|
|
if ( buffer[i] == '\n' ) |
|
|
|
fputc('\r', out); |
|
|
|
fputc(buffer[i], out); |
|
|
|
|
|
|
|
i += 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fprintf(out, "\r\n--%s--\r\n", boundary); |
|
|
|
|
|
|
|
gpgme_data_release(gin); |
|
|
|
gpgme_data_release(gout); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Main function. */ |
|
|
@ -265,12 +317,18 @@ main(int argc, char *argv[]) |
|
|
|
/* Write all headers. */ |
|
|
|
fprintf(stdout, "%s", sb_get(headers)); |
|
|
|
|
|
|
|
/* Write encoded body. */ |
|
|
|
process_text_body(stdin, stdout); |
|
|
|
if ( sign_ctx ) { |
|
|
|
FILE *tmp = tmpfile(); |
|
|
|
|
|
|
|
/* Clean-up. */ |
|
|
|
if ( sign_ctx ) |
|
|
|
process_text_body(stdin, tmp); |
|
|
|
fseek(tmp, 0, SEEK_SET); |
|
|
|
sign_stream(sign_ctx, tmp, stdout); |
|
|
|
|
|
|
|
fclose(tmp); |
|
|
|
gpgme_release(sign_ctx); |
|
|
|
} |
|
|
|
else |
|
|
|
process_text_body(stdin, stdout); |
|
|
|
|
|
|
|
return EXIT_SUCCESS; |
|
|
|
} |