LCOV - code coverage report
Current view: top level - agent - preset-passphrase.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 41 89 46.1 %
Date: 2016-11-29 15:00:56 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /* preset-passphrase.c - A tool to preset a passphrase.
       2             :  *      Copyright (C) 2004 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG 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 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : 
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <stddef.h>
      25             : #include <stdarg.h>
      26             : #include <string.h>
      27             : #include <errno.h>
      28             : #include <assert.h>
      29             : #include <sys/stat.h>
      30             : #include <unistd.h>
      31             : #ifdef HAVE_LOCALE_H
      32             : #include <locale.h>
      33             : #endif
      34             : #ifdef HAVE_LANGINFO_CODESET
      35             : #include <langinfo.h>
      36             : #endif
      37             : #ifdef HAVE_DOSISH_SYSTEM
      38             : #include <fcntl.h> /* for setmode() */
      39             : #endif
      40             : #ifdef HAVE_W32_SYSTEM
      41             : # ifdef HAVE_WINSOCK2_H
      42             : #  include <winsock2.h>
      43             : # endif
      44             : # include <windows.h>  /* To initialize the sockets.  fixme */
      45             : #endif
      46             : 
      47             : #include "agent.h"
      48             : #include "simple-pwquery.h"
      49             : #include "i18n.h"
      50             : #include "sysutils.h"
      51             : #include "../common/init.h"
      52             : 
      53             : 
      54             : enum cmd_and_opt_values
      55             : { aNull = 0,
      56             :   oVerbose        = 'v',
      57             :   oPassphrase     = 'P',
      58             : 
      59             :   oPreset         = 'c',
      60             :   oForget         = 'f',
      61             : 
      62             :   oNoVerbose = 500,
      63             : 
      64             :   oHomedir,
      65             : 
      66             : aTest };
      67             : 
      68             : 
      69             : static const char *opt_passphrase;
      70             : 
      71             : static ARGPARSE_OPTS opts[] = {
      72             : 
      73             :   { 301, NULL, 0, N_("@Options:\n ") },
      74             : 
      75             :   { oVerbose, "verbose",   0, "verbose" },
      76             :   { oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" },
      77             :   { oPreset,  "preset",   256, "preset passphrase"},
      78             :   { oForget,  "forget",  256, "forget passphrase"},
      79             : 
      80             :   { oHomedir, "homedir", 2, "@" },
      81             :   {0}
      82             : };
      83             : 
      84             : 
      85             : static const char *
      86           0 : my_strusage (int level)
      87             : {
      88             :   const char *p;
      89           0 :   switch (level)
      90             :     {
      91           0 :     case 11: p = "gpg-preset-passphrase (@GNUPG@)";
      92           0 :       break;
      93           0 :     case 13: p = VERSION; break;
      94           0 :     case 17: p = PRINTABLE_OS_NAME; break;
      95           0 :     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
      96             : 
      97             :     case 1:
      98             :     case 40:
      99           0 :       p =  _("Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n");
     100           0 :       break;
     101             :     case 41:
     102           0 :       p = _("Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
     103             :                     "Password cache maintenance\n");
     104           0 :     break;
     105             : 
     106           0 :     default: p = NULL;
     107             :     }
     108           0 :   return p;
     109             : }
     110             : 
     111             : 
     112             : 
     113             : 
     114             : static void
     115         135 : preset_passphrase (const char *keygrip)
     116             : {
     117             :   int  rc;
     118             :   char *line;
     119             :   /* FIXME: Use secure memory.  */
     120             :   char passphrase[500];
     121             :   char *passphrase_esc;
     122             : 
     123         135 :   if (!opt_passphrase)
     124             :     {
     125           0 :       rc = read (0, passphrase, sizeof (passphrase) - 1);
     126           0 :       if (rc < 0)
     127             :         {
     128           0 :           log_error ("reading passphrase failed: %s\n",
     129             :                      gpg_strerror (gpg_error_from_syserror ()));
     130           0 :           return;
     131             :         }
     132           0 :       passphrase[rc] = '\0';
     133           0 :       line = strchr (passphrase, '\n');
     134           0 :       if (line)
     135             :         {
     136           0 :           if (line > passphrase && line[-1] == '\r')
     137           0 :             line--;
     138           0 :           *line = '\0';
     139             :         }
     140             : 
     141             :       /* FIXME: How to handle empty passwords?  */
     142             :     }
     143             : 
     144             :   {
     145         135 :     const char *s = opt_passphrase ? opt_passphrase : passphrase;
     146         135 :     passphrase_esc = bin2hex (s, strlen (s), NULL);
     147             :   }
     148         135 :   if (!passphrase_esc)
     149             :     {
     150           0 :       log_error ("can not escape string: %s\n",
     151             :                  gpg_strerror (gpg_error_from_syserror ()));
     152           0 :       return;
     153             :     }
     154             : 
     155         135 :   rc = asprintf (&line, "PRESET_PASSPHRASE %s -1 %s\n", keygrip,
     156             :                  passphrase_esc);
     157         135 :   wipememory (passphrase_esc, strlen (passphrase_esc));
     158         135 :   xfree (passphrase_esc);
     159             : 
     160         135 :   if (rc < 0)
     161             :     {
     162           0 :       log_error ("caching passphrase failed: %s\n",
     163             :                  gpg_strerror (gpg_error_from_syserror ()));
     164           0 :       return;
     165             :     }
     166         135 :   if (!opt_passphrase)
     167           0 :     wipememory (passphrase, sizeof (passphrase));
     168             : 
     169         135 :   rc = simple_query (line);
     170         135 :   if (rc)
     171             :     {
     172           0 :       log_error ("caching passphrase failed: %s\n", gpg_strerror (rc));
     173           0 :       return;
     174             :     }
     175             : 
     176         135 :   wipememory (line, strlen (line));
     177         135 :   xfree (line);
     178             : }
     179             : 
     180             : 
     181             : static void
     182           0 : forget_passphrase (const char *keygrip)
     183             : {
     184             :   int rc;
     185             :   char *line;
     186             : 
     187           0 :   rc = asprintf (&line, "CLEAR_PASSPHRASE %s\n", keygrip);
     188           0 :   if (rc < 0)
     189           0 :     rc = gpg_error_from_syserror ();
     190             :   else
     191           0 :     rc = simple_query (line);
     192           0 :   if (rc)
     193             :     {
     194           0 :       log_error ("clearing passphrase failed: %s\n", gpg_strerror (rc));
     195           0 :       return;
     196             :     }
     197             : 
     198           0 :   xfree (line);
     199             : }
     200             : 
     201             : 
     202             : int
     203         135 : main (int argc, char **argv)
     204             : {
     205             :   ARGPARSE_ARGS pargs;
     206         135 :   int cmd = 0;
     207         135 :   const char *keygrip = NULL;
     208             : 
     209         135 :   early_system_init ();
     210         135 :   set_strusage (my_strusage);
     211         135 :   log_set_prefix ("gpg-preset-passphrase", GPGRT_LOG_WITH_PREFIX);
     212             : 
     213             :   /* Make sure that our subsystems are ready.  */
     214         135 :   i18n_init ();
     215         135 :   init_common_subsystems (&argc, &argv);
     216             : 
     217         135 :   pargs.argc = &argc;
     218         135 :   pargs.argv = &argv;
     219         135 :   pargs.flags=  1;  /* (do not remove the args) */
     220         540 :   while (arg_parse (&pargs, opts) )
     221             :     {
     222         270 :       switch (pargs.r_opt)
     223             :         {
     224           0 :         case oVerbose: opt.verbose++; break;
     225           0 :         case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
     226             : 
     227         135 :         case oPreset: cmd = oPreset; break;
     228           0 :         case oForget: cmd = oForget; break;
     229         135 :         case oPassphrase: opt_passphrase = pargs.r.ret_str; break;
     230             : 
     231           0 :         default : pargs.err = 2; break;
     232             :         }
     233             :     }
     234         135 :   if (log_get_errorcount(0))
     235           0 :     exit(2);
     236             : 
     237         135 :   if (argc == 1)
     238         135 :     keygrip = *argv;
     239             :   else
     240           0 :     usage (1);
     241             : 
     242             :   /* Tell simple-pwquery about the the standard socket name.  */
     243             :   {
     244         135 :     char *tmp = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
     245         135 :     simple_pw_set_socket (tmp);
     246         135 :     xfree (tmp);
     247             :   }
     248             : 
     249         135 :   if (cmd == oPreset)
     250         135 :     preset_passphrase (keygrip);
     251           0 :   else if (cmd == oForget)
     252           0 :     forget_passphrase (keygrip);
     253             :   else
     254           0 :     log_error ("one of the options --preset or --forget must be given\n");
     255             : 
     256         135 :   agent_exit (0);
     257             :   return 8; /*NOTREACHED*/
     258             : }
     259             : 
     260             : 
     261             : void
     262         135 : agent_exit (int rc)
     263             : {
     264         135 :   rc = rc? rc : log_get_errorcount(0)? 2 : 0;
     265         135 :   exit (rc);
     266             : }

Generated by: LCOV version 1.11