execgpg.c
上传用户:knt0001
上传日期:2022-01-28
资源大小:264k
文件大小:3k
源码类别:

Email客户端

开发平台:

C/C++

  1. /**
  2.     eMail is a command line SMTP client.
  3.     Copyright (C) 2001 - 2008 email by Dean Jones
  4.     Software supplied and written by http://www.cleancode.org
  5.     This file is part of eMail.
  6.     eMail is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.     eMail is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.     You should have received a copy of the GNU General Public License
  15.     along with eMail; if not, write to the Free Software
  16.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. **/
  18. #if HAVE_CONFIG_H
  19. # include "config.h"
  20. #endif
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <unistd.h>
  25. #include <errno.h>
  26. #include <sys/wait.h>
  27. #include <sys/stat.h>
  28. #include "email.h"
  29. #include "utils.h"
  30. #include "execgpg.h"
  31. #include "error.h"
  32. static void
  33. readfile(dstrbuf *buf, FILE *file)
  34. {
  35. dstrbuf *tmp = DSB_NEW;
  36. while (!feof(file)) {
  37. dsbReadline(tmp, file);
  38. chomp(tmp->str);
  39. dsbCat(buf, tmp->str);
  40. dsbCat(buf, "rn");
  41. }
  42. dsbDestroy(tmp);
  43. }
  44. /**
  45.  * Calls gpg with popen so that we may write to stdin 
  46.  * to pass gpg the password provided.  
  47. **/
  48. static int
  49. execgpg(const char *command, char *passwd)
  50. {
  51. FILE *gpg_stdin = NULL;
  52. if (!passwd) {
  53. passwd = getpass("Please enter your GPG password: ");
  54. }
  55. gpg_stdin = popen(command, "w");
  56. if (!gpg_stdin) {
  57. return ERROR;
  58. }
  59. /* Push password to stdin */
  60. fputs(passwd, gpg_stdin);
  61. pclose(gpg_stdin);
  62. return 0;
  63. }
  64. /**
  65.  * Calls gpg to sign and encrypt message
  66.  * returns and open FILE
  67. **/
  68. dstrbuf *
  69. callGpg(dstrbuf *input, GpgCallType call_type)
  70. {
  71. int retval;
  72. FILE *fdfile, *fdtmp;
  73. char *gpg_bin, *gpg_pass;
  74. char filename[TMPFILE_TEMPLATE_SIZE]=TMPFILE_TEMPLATE;
  75. char tmpfile[TMPFILE_TEMPLATE_SIZE]=TMPFILE_TEMPLATE;
  76. dstrbuf *encto=NULL;
  77. dstrbuf *gpg=NULL;
  78. dstrbuf *cmd=NULL;
  79. dstrbuf *buf=NULL;
  80. gpg_bin = getConfValue("GPG_BIN");
  81. gpg_pass = getConfValue("GPG_PASS");
  82. if (!gpg_bin) {
  83. fatal("You must specify the path to GPG in email.confn");
  84. return NULL;
  85. }
  86. /* Get the first email from Mopts.to */
  87. encto = getFirstEmail();
  88. fdfile = fdopen(mkstemp(filename), "r");
  89. fdtmp = fdopen(mkstemp(tmpfile), "w");
  90. fwrite(input->str, 1, input->len, fdtmp);
  91. gpg = expandPath(gpg_bin);
  92. cmd = DSB_NEW;
  93. dsbPrintf(cmd, "%s -a -o '%s' --no-secmem-warning --passphrase-fd 0 "
  94. " --no-tty", gpg->str, filename);
  95. if ((call_type & GPG_SIG) && (call_type & GPG_ENC)) {
  96. dsbPrintf(cmd, " -r '%s' -s -e", encto->str);
  97. } else if (call_type & GPG_ENC) {
  98. dsbPrintf(cmd, " -e -r '%s'", encto->str);
  99. } else if (call_type & GPG_SIG) {
  100. dsbPrintf(cmd, " --digest-algo=SHA1 --sign --detach -u '%s'", encto->str);
  101. }
  102. dsbPrintf(cmd, " '%s'", tmpfile);
  103. retval = execgpg(cmd->str, gpg_pass);
  104. dsbDestroy(encto);
  105. fclose(fdtmp);
  106. unlink(tmpfile);
  107. if (retval == -1) {
  108. fatal("Error executing: %s", gpg->str);
  109. dsbDestroy(gpg);
  110. return NULL;
  111. }
  112. dsbDestroy(gpg);
  113. dsbDestroy(cmd);
  114. buf = DSB_NEW;
  115. readfile(buf, fdfile);
  116. fclose(fdfile);
  117. unlink(filename);
  118. return buf;
  119. }