简体   繁体   English

通过管道在c中进行实时流gpg加密

[英]realtime stream gpg encryption in c over pipe

I'm trying to use gpg to encrypt data in realtime. 我正在尝试使用gpg实时加密数据。 I'm already using libgcrypt directly but i need a standard format. 我已经在直接使用libgcrypt,但是我需要标准格式。 I discarded gpgme since it did not seem suitable for a realtime stream application. 我丢弃了gpgme,因为它似乎不适合实时流应用程序。

What I would like to accomplish is this command line: 我想完成的是以下命令行:

gpg --passphrase hackerpass --symmetric -c gpg --passphrase hackerpass --symmetric -c

in the terminal it works well, print header, out the data and ends with the footer with a EOF CTRL-D, perfect! 在终端中,它工作正常,打印页眉,输出数据,并以EOF CTRL-D结尾页脚,完美!

This is the sample code, simple fork, bidirectional pipe, i write the data and wait the result asynchronously but ... the execution of gpg does not end, in reality it seems that the data does not arrive, i receive only the header, at fd close gpg does not receive EOF: 这是示例代码,简单的fork,双向管道,我编写数据并异步等待结果, 但是 ... gpg的执行没有结束,实际上似乎数据没有到达,我只收到标头,在fd关闭时gpg没有收到EOF:

#include <fcntl.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[]) {

    pid_t pid = 0;
    int inpipefd[2];
    int outpipefd[2];
    char buf[256];
    int status;

    pipe(inpipefd);
    pipe(outpipefd);

    pid = fork();

    if (pid == 0) {
        // Child       

        dup2(outpipefd[0], STDIN_FILENO);
        dup2(inpipefd[1], STDOUT_FILENO);
        //dup2(inpipefd[1], STDERR_FILENO);

        //ask kernel to deliver SIGTERM in case the parent dies
        prctl(PR_SET_PDEATHSIG, SIGTERM);

        execlp("/bin/sh", "/bin/sh", "-c", "/usr/bin/gpg --passphrase pass --symmetric -c", (char *) NULL);

        exit(1);
    }

    //close unused pipe ends
    close(outpipefd[0]);
    close(inpipefd[1]);

    int flags;

    flags = fcntl(inpipefd[0], F_GETFL, 0);
    flags |= O_NONBLOCK;
    fcntl(inpipefd[0], F_SETFL, flags);

    // write example data       

    char *data = "dummy dummy";

    ssize_t out = write(outpipefd[1], data, strlen(data));

    if (out != strlen(data)) {
        printf("fail write\n");
        exit(-1);
    }

    close(outpipefd[1]);

    int hasPendingData = 1;

    while (hasPendingData) {

        ssize_t r = read(inpipefd[0], buf, 255);

        if (r == -1 && errno == EAGAIN) {
            // in process
            printf("no data available, wait...\n");
            usleep(500000);

        } else if (r > 0) {
            printf("Incoming %ld bytes\n", (long) r);

        } else {
            // EOF 
            hasPendingData = 0;
            printf("no mode data available, exit...\n");
        }

    }

    waitpid(pid, &status, 0);

    return 0;
}

Just a guess here, but you have several unclosed duplicate file descriptors in the sub-process. 这里只是一个猜测,但是在子流程中您有几个未关闭的重复文件描述符。 Gpg won't get EOF until those file descriptors are closed. 在这些文件描述符关闭之前,Gpg不会获得EOF。 As long as any process could possible write to them, it will just keep waiting for more. 只要有可能向他们发送任何进程,它就会一直等待更多。

Another thing to watch out for is the gpg blocking while writing waiting for your process to read the pipe. 还要注意的另一件事是在编写gpg阻塞,以等待进程读取管道。 If that happens, your writing stage could then get blocked. 如果发生这种情况,那么您的写作阶段可能会受阻。 Won't happen with very small amounts of data but could happen later if you put any volume through. 不会出现非常少量的数据,但是如果您放置任何卷,都可能在以后发生。 Both write and read need to be non-blocking and running simultaneously. 写入和读取都必须是非阻塞的,并且必须同时运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM