Exemple #1
0
int libmail_gpg_checksign(const char *gpgdir, const char *content,
		  const char *signature,
		  int (*dump_func)(const char *, size_t, void *),
		  void *voidarg)
{
	char *argvec[10];
	int rc;

	argvec[0]="gpg";
	argvec[1]="--no-tty";
	argvec[2]="--verify";
	argvec[3]=(char *)signature;
	argvec[4]=(char *)content;
	argvec[5]=0;

	if (libmail_gpg_fork(&libmail_gpg_stdin, &libmail_gpg_stdout,
			     &libmail_gpg_stderr, gpgdir, argvec) < 0)
		rc= -1;
	else
	{
		int rc2;

		rc=dochecksign(dump_func, voidarg);
		rc2=libmail_gpg_cleanup();
		if (rc2)
			rc=rc2;
	}
	return (rc);
}
Exemple #2
0
static void checksign(struct mimestack **stack, int *iseof,
                      struct header *h,
                      FILE *fpin, FILE *fpout,
                      int argc, char **argv)
{
    char buf[BUFSIZ];
    struct header *h2;

    char signed_content[TEMPNAMEBUFSIZE];
    char signature[TEMPNAMEBUFSIZE];
    int signed_file, signature_file;
    FILE *signed_file_fp, *signature_file_fp;
    int clos_flag;
    int need_nl, check_boundary;
    struct mimestack *b=0;
    struct mime_header *mh;
    int qpdecode=0;

    signed_file=mimegpg_tempfile(signed_content);

    if (signed_file < 0 || (signed_file_fp=fdopen(signed_file, "w+")) == 0)
    {
        if (signed_file > 0)
        {
            close(signed_file);
            unlink(signed_content);
        }
        perror("open");
        exit(1);
    }
    noexec(signed_file_fp);

    find_boundary(stack, iseof, fpin, NULL, 0);
    if (*iseof)
        return;

    need_nl=0;
    check_boundary=1;

    while (!*iseof)
    {
        const char *p;

        if (fgets(buf, sizeof(buf), fpin) == NULL)
        {
            *iseof=1;
            continue;
        }

        if (check_boundary
                && (b=is_boundary(*stack, buf, &clos_flag)) != 0)
            break;
        if (need_nl)
            fprintf(signed_file_fp, "\r\n");

        for (p=buf; *p && *p != '\n'; p++)
            putc(*p, signed_file_fp);
        need_nl=check_boundary= *p != 0;
    }

    if (my_rewind(signed_file_fp) < 0)
    {
        perror(signed_content);
        fclose(signed_file_fp);
        unlink(signed_content);
        exit(1);
    }

    if (clos_flag)
    {
        fclose(signed_file_fp);
        unlink(signed_content);
        if (b)
            pop_mimestack_to(stack, b);
        find_boundary(stack, iseof, fpin, fpout, 1);
        return;
    }

    h=read_headers(stack, iseof, fpin, fpout, 0);

    if (!h || !(h2=find_header(h, "content-type:")))
    {
        fclose(signed_file_fp);
        unlink(signed_content);
        if (!*iseof)
            find_boundary(stack, iseof, fpin, fpout, 1);
        return;
    }

    mh=parse_mime_header(h2->header+sizeof("content-type:")-1);

    if (!mh)
    {
        perror("malloc");
        free_header(h);
        fclose(signed_file_fp);
        unlink(signed_content);
        exit(1);
    }

    if (!mh || strcasecmp(mh->header_name, "application/pgp-signature"))
    {
        if (!mh)
            free_mime_header(mh);
        free_header(h);
        fclose(signed_file_fp);
        unlink(signed_content);
        if (!*iseof)
            find_boundary(stack, iseof, fpin, fpout, 1);
        return;
    }
    free_mime_header(mh);

    /*
    ** In rare instances, the signature is qp-encoded.
    */

    if ((h2=find_header(h, "content-transfer-encoding:")) != NULL)
    {
        mh=parse_mime_header(h2->header
                             +sizeof("content-transfer-encoding:")-1);
        if (!mh)
        {
            perror("malloc");
            free_header(h);
            fclose(signed_file_fp);
            unlink(signed_content);
            exit(1);
        }

        if (strcasecmp(mh->header_name,
                       "quoted-printable") == 0)
            qpdecode=1;
        free_mime_header(mh);
    }
    free_header(h);

    signature_file=mimegpg_tempfile(signature);

    if (signature_file < 0
            || (signature_file_fp=fdopen(signature_file, "w+")) == 0)
    {
        if (signature_file > 0)
        {
            close(signature_file);
            unlink(signature);
        }
        fclose(signed_file_fp);
        unlink(signed_content);
        perror("open");
        exit(1);
    }

    while (!*iseof)
    {
        const char *p;

        if (fgets(buf, sizeof(buf), fpin) == NULL)
        {
            *iseof=1;
            continue;
        }

        if ((b=is_boundary(*stack, buf, &clos_flag)) != 0)
            break;

        for (p=buf; *p; p++)
        {
            int n;

            if (!qpdecode)
            {
                putc(*p, signature_file_fp);
                continue;
            }

            if (*p == '=' && p[1] == '\n')
                break;

            if (*p == '=' && p[1] && p[2])
            {
                n=nybble(p[1]) * 16 + nybble(p[2]);
                if ( (char)n )
                {
                    putc((char)n, signature_file_fp);
                    p += 2;
                }
                p += 2;
                continue;
            }
            putc(*p, signature_file_fp);

            /* If some spits out qp-lines > BUFSIZ, they deserve
            ** this crap.
            */
        }
    }

    fflush(signature_file_fp);
    if (ferror(signature_file_fp) || fclose(signature_file_fp))
    {
        unlink(signature);
        fclose(signed_file_fp);
        unlink(signed_content);
        perror("open");
        exit(1);
    }

    dochecksign(*stack, signed_file_fp, fpout, signed_content, signature,
                argc, argv);

    fclose(signed_file_fp);
    unlink(signature);
    unlink(signed_content);

    fprintf(fpout, "\n--%s--\n", b->boundary);

    while (!clos_flag)
    {
        if (fgets(buf, sizeof(buf), fpin) == NULL)
        {
            *iseof=1;
            break;
        }
        if (!(b=is_boundary(*stack, buf, &clos_flag)))
            clos_flag=0;
    }
    if (b)
        pop_mimestack_to(stack, b);

    if (iseof)
        return;
}