/** Store hex-encoded data from line to be signed/decrypted. */ gpg_error_t cmd_setdata (assuan_context_t ctx, char *line) { gpg_err_code_t error = GPG_ERR_GENERAL; cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx); int append = 0; int index; size_t len; while (*line != '\x0' && (isspace (*line) || *line == '-')) { if (*line == '-') { static const char *appendprm = "--append "; char *p = line; while (*line != '\x0' && !isspace (*line)) { line++; } line++; if (!strncmp (p, appendprm, strlen (appendprm))) { p += strlen (appendprm); append = 1; } } else { line++; } } if (!append) { cmd_free_data (ctx); } if (!encoding_hex2bin(line, NULL, &len)) { error = GPG_ERR_INV_DATA; goto cleanup; } if (!append) { index = 0; data->size = len; data->data = (unsigned char *)malloc(data->size); } else { index = data->size; data->size += len; data->data = (unsigned char *)realloc(data->data, data->size); } if (!encoding_hex2bin (line, data->data + index, NULL)) { error = GPG_ERR_INV_DATA; goto cleanup; } error = GPG_ERR_NO_ERROR; cleanup: return gpg_error (error); }
/** Command handler (single-threaded). If fd == -1, this is a pipe server, otherwise fd is UNIX socket fd to which client connected. */ static void command_handler (const int fd, dconfig_data_t *config) { assuan_context_t ctx = NULL; cmd_data_t data; int ret; memset (&data, 0, sizeof (data)); data.config = config; if ((ret = assuan_new(&ctx)) != 0) { common_log (LOG_ERROR,"failed to create assuan context %s", gpg_strerror (ret)); goto cleanup; } if(fd < 0) { assuan_fd_t fds[2] = {assuan_fdopen(0), assuan_fdopen(1)}; ret = assuan_init_pipe_server (ctx, fds); } else { ret = assuan_init_socket_server (ctx, INT2FD(fd), ASSUAN_SOCKET_SERVER_ACCEPTED); } if (ret != 0) { common_log (LOG_ERROR,"failed to initialize server: %s", gpg_strerror (ret)); goto cleanup; } if(((ret = register_commands(ctx))) != 0) { common_log (LOG_ERROR,"failed to register assuan commands: %s", gpg_strerror (ret)); goto cleanup; } if (config->verbose) { assuan_set_log_stream (ctx, common_get_log_stream()); } assuan_set_pointer (ctx, &data); while (1) { if ((ret = assuan_accept (ctx)) == -1) { break; } if (ret != 0) { common_log (LOG_WARNING,"assuan_accept failed: %s", gpg_strerror(ret)); break; } if ((ret = assuan_process (ctx)) != 0) { common_log (LOG_WARNING,"assuan_process failed: %s", gpg_strerror(ret)); } } cleanup: if (ctx != NULL) { cmd_free_data (ctx); assuan_release (ctx); ctx = NULL; } }