LCOV - code coverage report
Current view: top level - agent - preset-passphrase.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 43 91 47.3 %
Date: 2015-11-05 17:10:59 Functions: 4 6 66.7 %

          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 <http://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_homedir;
      70             : static const char *opt_passphrase;
      71             : 
      72             : static ARGPARSE_OPTS opts[] = {
      73             : 
      74             :   { 301, NULL, 0, N_("@Options:\n ") },
      75             : 
      76             :   { oVerbose, "verbose",   0, "verbose" },
      77             :   { oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" },
      78             :   { oPreset,  "preset",   256, "preset passphrase"},
      79             :   { oForget,  "forget",  256, "forget passphrase"},
      80             : 
      81             :   { oHomedir, "homedir", 2, "@" },
      82             :   {0}
      83             : };
      84             : 
      85             : 
      86             : static const char *
      87           0 : my_strusage (int level)
      88             : {
      89             :   const char *p;
      90           0 :   switch (level)
      91             :     {
      92           0 :     case 11: p = "gpg-preset-passphrase (@GNUPG@)";
      93           0 :       break;
      94           0 :     case 13: p = VERSION; break;
      95           0 :     case 17: p = PRINTABLE_OS_NAME; break;
      96           0 :     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
      97             : 
      98             :     case 1:
      99             :     case 40:
     100           0 :       p =  _("Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n");
     101           0 :       break;
     102             :     case 41:
     103           0 :       p = _("Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
     104             :                     "Password cache maintenance\n");
     105           0 :     break;
     106             : 
     107           0 :     default: p = NULL;
     108             :     }
     109           0 :   return p;
     110             : }
     111             : 
     112             : 
     113             : 
     114             : 
     115             : /* Include the implementation of map_spwq_error.  */
     116          10 : MAP_SPWQ_ERROR_IMPL
     117             : 
     118             : 
     119             : static void
     120          10 : preset_passphrase (const char *keygrip)
     121             : {
     122             :   int  rc;
     123             :   char *line;
     124             :   /* FIXME: Use secure memory.  */
     125             :   char passphrase[500];
     126             :   char *passphrase_esc;
     127             : 
     128          10 :   if (!opt_passphrase)
     129             :     {
     130           0 :       rc = read (0, passphrase, sizeof (passphrase) - 1);
     131           0 :       if (rc < 0)
     132             :         {
     133           0 :           log_error ("reading passphrase failed: %s\n",
     134             :                      gpg_strerror (gpg_error_from_syserror ()));
     135           0 :           return;
     136             :         }
     137           0 :       passphrase[rc] = '\0';
     138           0 :       line = strchr (passphrase, '\n');
     139           0 :       if (line)
     140             :         {
     141           0 :           if (line > passphrase && line[-1] == '\r')
     142           0 :             line--;
     143           0 :           *line = '\0';
     144             :         }
     145             : 
     146             :       /* FIXME: How to handle empty passwords?  */
     147             :     }
     148             : 
     149             :   {
     150          10 :     const char *s = opt_passphrase ? opt_passphrase : passphrase;
     151          10 :     passphrase_esc = bin2hex (s, strlen (s), NULL);
     152             :   }
     153          10 :   if (!passphrase_esc)
     154             :     {
     155           0 :       log_error ("can not escape string: %s\n",
     156             :                  gpg_strerror (gpg_error_from_syserror ()));
     157           0 :       return;
     158             :     }
     159             : 
     160          10 :   rc = asprintf (&line, "PRESET_PASSPHRASE %s -1 %s\n", keygrip,
     161             :                  passphrase_esc);
     162          10 :   wipememory (passphrase_esc, strlen (passphrase_esc));
     163          10 :   xfree (passphrase_esc);
     164             : 
     165          10 :   if (rc < 0)
     166             :     {
     167           0 :       log_error ("caching passphrase failed: %s\n",
     168             :                  gpg_strerror (gpg_error_from_syserror ()));
     169           0 :       return;
     170             :     }
     171          10 :   if (!opt_passphrase)
     172           0 :     wipememory (passphrase, sizeof (passphrase));
     173             : 
     174          10 :   rc = map_spwq_error (simple_query (line));
     175          10 :   if (rc)
     176             :     {
     177           0 :       log_error ("caching passphrase failed: %s\n", gpg_strerror (rc));
     178           0 :       return;
     179             :     }
     180             : 
     181          10 :   wipememory (line, strlen (line));
     182          10 :   xfree (line);
     183             : }
     184             : 
     185             : 
     186             : static void
     187           0 : forget_passphrase (const char *keygrip)
     188             : {
     189             :   int rc;
     190             :   char *line;
     191             : 
     192           0 :   rc = asprintf (&line, "CLEAR_PASSPHRASE %s\n", keygrip);
     193           0 :   if (rc < 0)
     194           0 :     rc = gpg_error_from_syserror ();
     195             :   else
     196           0 :     rc = map_spwq_error (simple_query (line));
     197           0 :   if (rc)
     198             :     {
     199           0 :       log_error ("clearing passphrase failed: %s\n", gpg_strerror (rc));
     200           0 :       return;
     201             :     }
     202             : 
     203           0 :   xfree (line);
     204             : }
     205             : 
     206             : 
     207             : int
     208          10 : main (int argc, char **argv)
     209             : {
     210             :   ARGPARSE_ARGS pargs;
     211          10 :   int cmd = 0;
     212          10 :   const char *keygrip = NULL;
     213             : 
     214          10 :   early_system_init ();
     215          10 :   set_strusage (my_strusage);
     216          10 :   log_set_prefix ("gpg-preset-passphrase", 1);
     217             : 
     218             :   /* Make sure that our subsystems are ready.  */
     219          10 :   i18n_init ();
     220          10 :   init_common_subsystems (&argc, &argv);
     221             : 
     222          10 :   opt_homedir = default_homedir ();
     223             : 
     224          10 :   pargs.argc = &argc;
     225          10 :   pargs.argv = &argv;
     226          10 :   pargs.flags=  1;  /* (do not remove the args) */
     227          40 :   while (arg_parse (&pargs, opts) )
     228             :     {
     229          20 :       switch (pargs.r_opt)
     230             :         {
     231           0 :         case oVerbose: opt.verbose++; break;
     232           0 :         case oHomedir: opt_homedir = pargs.r.ret_str; break;
     233             : 
     234          10 :         case oPreset: cmd = oPreset; break;
     235           0 :         case oForget: cmd = oForget; break;
     236          10 :         case oPassphrase: opt_passphrase = pargs.r.ret_str; break;
     237             : 
     238           0 :         default : pargs.err = 2; break;
     239             :         }
     240             :     }
     241          10 :   if (log_get_errorcount(0))
     242           0 :     exit(2);
     243             : 
     244          10 :   if (argc == 1)
     245          10 :     keygrip = *argv;
     246             :   else
     247           0 :     usage (1);
     248             : 
     249             :   /* Tell simple-pwquery about the the standard socket name.  */
     250             :   {
     251          10 :     char *tmp = make_filename (opt_homedir, GPG_AGENT_SOCK_NAME, NULL);
     252          10 :     simple_pw_set_socket (tmp);
     253          10 :     xfree (tmp);
     254             :   }
     255             : 
     256          10 :   if (cmd == oPreset)
     257          10 :     preset_passphrase (keygrip);
     258           0 :   else if (cmd == oForget)
     259           0 :     forget_passphrase (keygrip);
     260             :   else
     261           0 :     log_error ("one of the options --preset or --forget must be given\n");
     262             : 
     263          10 :   agent_exit (0);
     264             :   return 8; /*NOTREACHED*/
     265             : }
     266             : 
     267             : 
     268             : void
     269          10 : agent_exit (int rc)
     270             : {
     271          10 :   rc = rc? rc : log_get_errorcount(0)? 2 : 0;
     272          10 :   exit (rc);
     273             : }

Generated by: LCOV version 1.11