po/
[gnupg.git] / tools / symcryptrun.c
blobb46990cd29c0bfafa9b8ec319741316ac0eaa25d
1 /* symcryptrun.c - Tool to call simple symmetric encryption tools.
2 * Copyright (C) 2005, 2007 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
21 /* Sometimes simple encryption tools are already in use for a long
22 time and there is a desire to integrate them into the GnuPG
23 framework. The protocols and encryption methods might be
24 non-standard or not even properly documented, so that a
25 full-fledged encryption tool with an interface like gpg is not
26 doable. This simple wrapper program provides a solution: It
27 operates by calling the encryption/decryption module and providing
28 the passphrase for a key (or even the key directly) using the
29 standard pinentry mechanism through gpg-agent. */
31 /* This program is invoked in the following way:
33 symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE \
34 [--decrypt | --encrypt]
36 For encryption, the plain text must be provided on STDIN, and the
37 ciphertext will be output to STDOUT. For decryption vice versa.
39 CLASS can currently only be "confucius".
41 PROGRAM must be the path to the crypto engine.
43 KEYFILE must contain the secret key, which may be protected by a
44 passphrase. The passphrase is retrieved via the pinentry program.
47 The GPG Agent _must_ be running before starting symcryptrun.
49 The possible exit status codes:
51 0 Success
52 1 Some error occured
53 2 No valid passphrase was provided
54 3 The operation was canceled by the user
56 Other classes may be added in the future. */
58 #define SYMC_BAD_PASSPHRASE 2
59 #define SYMC_CANCELED 3
62 #include <config.h>
64 #include <unistd.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <errno.h>
69 #include <assert.h>
70 #include <signal.h>
71 #include <sys/stat.h>
72 #include <sys/types.h>
73 #include <sys/wait.h>
74 #ifdef HAVE_PTY_H
75 #include <pty.h>
76 #endif
77 #include <utmp.h>
78 #include <ctype.h>
79 #ifdef HAVE_LOCALE_H
80 #include <locale.h>
81 #endif
82 #ifdef HAVE_LANGINFO_CODESET
83 #include <langinfo.h>
84 #endif
85 #include <gpg-error.h>
87 #define JNLIB_NEED_LOG_LOGV
88 #include "i18n.h"
89 #include "../common/util.h"
90 #include "mkdtemp.h"
92 /* FIXME: Bah. For spwq_secure_free. */
93 #define SIMPLE_PWQUERY_IMPLEMENTATION 1
94 #include "../common/simple-pwquery.h"
97 /* From simple-gettext.c. */
99 /* We assume to have `unsigned long int' value with at least 32 bits. */
100 #define HASHWORDBITS 32
102 /* The so called `hashpjw' function by P.J. Weinberger
103 [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
104 1986, 1987 Bell Telephone Laboratories, Inc.] */
106 static __inline__ ulong
107 hash_string( const char *str_param )
109 unsigned long int hval, g;
110 const char *str = str_param;
112 hval = 0;
113 while (*str != '\0')
115 hval <<= 4;
116 hval += (unsigned long int) *str++;
117 g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
118 if (g != 0)
120 hval ^= g >> (HASHWORDBITS - 8);
121 hval ^= g;
124 return hval;
128 /* Constants to identify the commands and options. */
129 enum cmd_and_opt_values
131 aNull = 0,
132 oQuiet = 'q',
133 oVerbose = 'v',
135 oNoVerbose = 500,
136 oOptions,
137 oNoOptions,
138 oLogFile,
139 oHomedir,
140 oClass,
141 oProgram,
142 oKeyfile,
143 oDecrypt,
144 oEncrypt,
145 oInput
149 /* The list of commands and options. */
150 static ARGPARSE_OPTS opts[] =
152 { 301, NULL, 0, N_("@\nCommands:\n ") },
154 { oDecrypt, "decrypt", 0, N_("decryption modus") },
155 { oEncrypt, "encrypt", 0, N_("encryption modus") },
157 { 302, NULL, 0, N_("@\nOptions:\n ") },
159 { oClass, "class", 2, N_("tool class (confucius)") },
160 { oProgram, "program", 2, N_("program filename") },
162 { oKeyfile, "keyfile", 2, N_("secret key file (required)") },
163 { oInput, "inputfile", 2, N_("input file name (default stdin)") },
164 { oVerbose, "verbose", 0, N_("verbose") },
165 { oQuiet, "quiet", 0, N_("quiet") },
166 { oLogFile, "log-file", 2, N_("use a log file for the server") },
167 { oOptions, "options" , 2, N_("|FILE|read options from FILE") },
169 /* Hidden options. */
170 { oNoVerbose, "no-verbose", 0, "@" },
171 { oHomedir, "homedir", 2, "@" },
172 { oNoOptions, "no-options", 0, "@" },/* shortcut for --options /dev/null */
178 /* We keep all global options in the structure OPT. */
179 struct
181 int verbose; /* Verbosity level. */
182 int quiet; /* Be extra quiet. */
183 const char *homedir; /* Configuration directory name */
185 char *class;
186 char *program;
187 char *keyfile;
188 char *input;
189 } opt;
192 /* Print usage information and and provide strings for help. */
193 static const char *
194 my_strusage (int level)
196 const char *p;
198 switch (level)
200 case 11: p = "symcryptrun (GnuPG)";
201 break;
202 case 13: p = VERSION; break;
203 case 17: p = PRINTABLE_OS_NAME; break;
204 case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
206 case 1:
207 case 40: p = _("Usage: symcryptrun [options] (-h for help)");
208 break;
209 case 41:
210 p = _("Syntax: symcryptrun --class CLASS --program PROGRAM "
211 "--keyfile KEYFILE [options...] COMMAND [inputfile]\n"
212 "Call a simple symmetric encryption tool\n");
213 break;
214 case 31: p = "\nHome: "; break;
215 case 32: p = opt.homedir; break;
216 case 33: p = "\n"; break;
218 default: p = NULL; break;
220 return p;
225 /* This is in the GNU C library in unistd.h. */
227 #ifndef TEMP_FAILURE_RETRY
228 /* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno'
229 set to EINTR. */
231 # define TEMP_FAILURE_RETRY(expression) \
232 (__extension__ \
233 ({ long int __result; \
234 do __result = (long int) (expression); \
235 while (__result == -1L && errno == EINTR); \
236 __result; }))
237 #endif
239 /* Include the implementation of map_spwq_error. */
240 MAP_SPWQ_ERROR_IMPL
242 /* Unlink a file, and shred it if SHRED is true. */
244 remove_file (char *name, int shred)
246 if (!shred)
247 return unlink (name);
248 else
250 int status;
251 pid_t pid;
253 pid = fork ();
254 if (pid == 0)
256 /* Child. */
258 /* -f forces file to be writable, and -u unlinks it afterwards. */
259 char *args[] = { SHRED, "-uf", name, NULL };
261 execv (SHRED, args);
262 _exit (127);
264 else if (pid < 0)
266 /* Fork failed. */
267 status = -1;
269 else
271 /* Parent. */
273 if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
274 status = -1;
277 if (!WIFEXITED (status))
279 log_error (_("%s on %s aborted with status %i\n"),
280 SHRED, name, status);
281 unlink (name);
282 return 1;
284 else if (WEXITSTATUS (status))
286 log_error (_("%s on %s failed with status %i\n"), SHRED, name,
287 WEXITSTATUS (status));
288 unlink (name);
289 return 1;
292 return 0;
297 /* Class Confucius.
299 "Don't worry that other people don't know you;
300 worry that you don't know other people." Analects--1.16. */
302 /* Create temporary directory with mode 0700. Returns a dynamically
303 allocated string with the filename of the directory. */
304 static char *
305 confucius_mktmpdir (void)
307 char *name;
309 name = strdup ("/tmp/gpg-XXXXXX");
310 if (!name || !mkdtemp (name))
312 log_error (_("can't create temporary directory `%s': %s\n"),
313 name?name:"", strerror (errno));
314 return NULL;
317 return name;
321 /* Buffer size for I/O operations. */
322 #define CONFUCIUS_BUFSIZE 4096
324 /* Buffer size for output lines. */
325 #define CONFUCIUS_LINESIZE 4096
328 /* Copy the file IN to OUT, either of which may be "-". If PLAIN is
329 true, and the copying fails, and OUT is not STDOUT, then shred the
330 file instead unlinking it. */
331 static int
332 confucius_copy_file (char *infile, char *outfile, int plain)
334 FILE *in;
335 int in_is_stdin = 0;
336 FILE *out;
337 int out_is_stdout = 0;
338 char data[CONFUCIUS_BUFSIZE];
339 ssize_t data_len;
341 if (infile[0] == '-' && infile[1] == '\0')
343 /* FIXME: Is stdin in binary mode? */
344 in = stdin;
345 in_is_stdin = 1;
347 else
349 in = fopen (infile, "rb");
350 if (!in)
352 log_error (_("could not open %s for writing: %s\n"),
353 infile, strerror (errno));
354 return 1;
358 if (outfile[0] == '-' && outfile[1] == '\0')
360 /* FIXME: Is stdout in binary mode? */
361 out = stdout;
362 out_is_stdout = 1;
364 else
366 out = fopen (outfile, "wb");
367 if (!out)
369 log_error (_("could not open %s for writing: %s\n"),
370 infile, strerror (errno));
371 return 1;
375 /* Now copy the data. */
376 while ((data_len = fread (data, 1, sizeof (data), in)) > 0)
378 if (fwrite (data, 1, data_len, out) != data_len)
380 log_error (_("error writing to %s: %s\n"), outfile,
381 strerror (errno));
382 goto copy_err;
385 if (data_len < 0 || ferror (in))
387 log_error (_("error reading from %s: %s\n"), infile, strerror (errno));
388 goto copy_err;
391 /* Close IN if appropriate. */
392 if (!in_is_stdin && fclose (in) && ferror (in))
394 log_error (_("error closing %s: %s\n"), infile, strerror (errno));
395 goto copy_err;
398 /* Close OUT if appropriate. */
399 if (!out_is_stdout && fclose (out) && ferror (out))
401 log_error (_("error closing %s: %s\n"), infile, strerror (errno));
402 goto copy_err;
405 return 0;
407 copy_err:
408 if (!out_is_stdout)
409 remove_file (outfile, plain);
411 return 1;
415 /* Get a passphrase in secure storage (if possible). If AGAIN is
416 true, then this is a repeated attempt. If CANCELED is not a null
417 pointer, it will be set to true or false, depending on if the user
418 canceled the operation or not. On error (including cancelation), a
419 null pointer is returned. The passphrase must be deallocated with
420 confucius_drop_pass. CACHEID is the ID to be used for passphrase
421 caching and can be NULL to disable caching. */
422 char *
423 confucius_get_pass (const char *cacheid, int again, int *canceled)
425 int err;
426 char *pw;
427 char *orig_codeset;
429 if (canceled)
430 *canceled = 0;
432 orig_codeset = i18n_switchto_utf8 ();
433 pw = simple_pwquery (cacheid,
434 again ? _("does not match - try again"):NULL,
435 _("Passphrase:"), NULL, 0, &err);
436 err = map_spwq_error (err);
437 i18n_switchback (orig_codeset);
439 if (!pw)
441 if (err)
442 log_error (_("error while asking for the passphrase: %s\n"),
443 gpg_strerror (err));
444 else
446 log_info (_("cancelled\n"));
447 if (canceled)
448 *canceled = 1;
452 return pw;
456 /* Drop a passphrase retrieved with confucius_get_pass. */
457 void
458 confucius_drop_pass (char *pass)
460 if (pass)
461 spwq_secure_free (pass);
465 /* Run a confucius crypto engine. If MODE is oEncrypt, encryption is
466 requested. If it is oDecrypt, decryption is requested. INFILE and
467 OUTFILE are the temporary files used in the process. */
469 confucius_process (int mode, char *infile, char *outfile,
470 int argc, char *argv[])
472 char **args;
473 int cstderr[2];
474 int master;
475 int slave;
476 int res;
477 pid_t pid;
478 pid_t wpid;
479 int tries = 0;
480 char cacheid[40];
482 signal (SIGPIPE, SIG_IGN);
484 if (!opt.program)
486 log_error (_("no --program option provided\n"));
487 return 1;
490 if (mode != oDecrypt && mode != oEncrypt)
492 log_error (_("only --decrypt and --encrypt are supported\n"));
493 return 1;
496 if (!opt.keyfile)
498 log_error (_("no --keyfile option provided\n"));
499 return 1;
502 /* Generate a hash from the keyfile name for caching. */
503 snprintf (cacheid, sizeof (cacheid), "confucius:%lu",
504 hash_string (opt.keyfile));
505 cacheid[sizeof (cacheid) - 1] = '\0';
506 args = malloc (sizeof (char *) * (10 + argc));
507 if (!args)
509 log_error (_("cannot allocate args vector\n"));
510 return 1;
512 args[0] = opt.program;
513 args[1] = (mode == oEncrypt) ? "-m1" : "-m2";
514 args[2] = "-q";
515 args[3] = infile;
516 args[4] = "-z";
517 args[5] = outfile;
518 args[6] = "-s";
519 args[7] = opt.keyfile;
520 args[8] = (mode == oEncrypt) ? "-af" : "-f";
521 args[9 + argc] = NULL;
522 while (argc--)
523 args[9 + argc] = argv[argc];
525 if (pipe (cstderr) < 0)
527 log_error (_("could not create pipe: %s\n"), strerror (errno));
528 free (args);
529 return 1;
532 if (openpty (&master, &slave, NULL, NULL, NULL) == -1)
534 log_error (_("could not create pty: %s\n"), strerror (errno));
535 close (cstderr[0]);
536 close (cstderr[1]);
537 free (args);
538 return -1;
541 /* We don't want to deal with the worst case scenarios. */
542 assert (master > 2);
543 assert (slave > 2);
544 assert (cstderr[0] > 2);
545 assert (cstderr[1] > 2);
547 pid = fork ();
548 if (pid < 0)
550 log_error (_("could not fork: %s\n"), strerror (errno));
551 close (master);
552 close (slave);
553 close (cstderr[0]);
554 close (cstderr[1]);
555 free (args);
556 return 1;
558 else if (pid == 0)
560 /* Child. */
562 /* Close the parent ends. */
563 close (master);
564 close (cstderr[0]);
566 /* Change controlling terminal. */
567 if (login_tty (slave))
569 /* It's too early to output a debug message. */
570 _exit (1);
573 dup2 (cstderr[1], 2);
574 close (cstderr[1]);
576 /* Now kick off the engine program. */
577 execv (opt.program, args);
578 log_error (_("execv failed: %s\n"), strerror (errno));
579 _exit (1);
581 else
583 /* Parent. */
584 char buffer[CONFUCIUS_LINESIZE];
585 int buffer_len = 0;
586 fd_set fds;
587 int slave_closed = 0;
588 int stderr_closed = 0;
590 close (slave);
591 close (cstderr[1]);
592 free (args);
594 /* Listen on the output FDs. */
597 FD_ZERO (&fds);
599 if (!slave_closed)
600 FD_SET (master, &fds);
601 if (!stderr_closed)
602 FD_SET (cstderr[0], &fds);
604 res = select (FD_SETSIZE, &fds, NULL, NULL, NULL);
605 if (res < 0)
607 log_error (_("select failed: %s\n"), strerror (errno));
609 kill (pid, SIGTERM);
610 close (master);
611 close (cstderr[0]);
612 return 1;
615 if (FD_ISSET (cstderr[0], &fds))
617 /* We got some output on stderr. This is just passed
618 through via the logging facility. */
620 res = read (cstderr[0], &buffer[buffer_len],
621 sizeof (buffer) - buffer_len - 1);
622 if (res < 0)
624 log_error (_("read failed: %s\n"), strerror (errno));
626 kill (pid, SIGTERM);
627 close (master);
628 close (cstderr[0]);
629 return 1;
631 else
633 char *newline;
635 buffer_len += res;
636 for (;;)
638 buffer[buffer_len] = '\0';
639 newline = strchr (buffer, '\n');
640 if (newline)
642 *newline = '\0';
643 log_error ("%s\n", buffer);
644 buffer_len -= newline + 1 - buffer;
645 memmove (buffer, newline + 1, buffer_len);
647 else if (buffer_len == sizeof (buffer) - 1)
649 /* Overflow. */
650 log_error ("%s\n", buffer);
651 buffer_len = 0;
653 else
654 break;
657 if (res == 0)
658 stderr_closed = 1;
661 else if (FD_ISSET (master, &fds))
663 char data[512];
665 res = read (master, data, sizeof (data));
666 if (res < 0)
668 if (errno == EIO)
670 /* Slave-side close leads to readable fd and
671 EIO. */
672 slave_closed = 1;
674 else
676 log_error (_("pty read failed: %s\n"), strerror (errno));
678 kill (pid, SIGTERM);
679 close (master);
680 close (cstderr[0]);
681 return 1;
684 else if (res == 0)
685 /* This never seems to be what happens on slave-side
686 close. */
687 slave_closed = 1;
688 else
690 /* Check for password prompt. */
691 if (data[res - 1] == ':')
693 char *pass;
694 int canceled;
696 /* If this is not the first attempt, the
697 passphrase seems to be wrong, so clear the
698 cache. */
699 if (tries)
700 simple_pwclear (cacheid);
702 pass = confucius_get_pass (cacheid,
703 tries ? 1 : 0, &canceled);
704 if (!pass)
706 kill (pid, SIGTERM);
707 close (master);
708 close (cstderr[0]);
709 return canceled ? SYMC_CANCELED : 1;
711 write (master, pass, strlen (pass));
712 write (master, "\n", 1);
713 confucius_drop_pass (pass);
715 tries++;
720 while (!stderr_closed || !slave_closed);
722 close (master);
723 close (cstderr[0]);
725 wpid = waitpid (pid, &res, 0);
726 if (wpid < 0)
728 log_error (_("waitpid failed: %s\n"), strerror (errno));
730 kill (pid, SIGTERM);
731 /* State of cached password is unclear. Just remove it. */
732 simple_pwclear (cacheid);
733 return 1;
735 else
737 /* Shouldn't happen, as we don't use WNOHANG. */
738 assert (wpid != 0);
740 if (!WIFEXITED (res))
742 log_error (_("child aborted with status %i\n"), res);
744 /* State of cached password is unclear. Just remove it. */
745 simple_pwclear (cacheid);
747 return 1;
750 if (WEXITSTATUS (res))
752 /* The passphrase was wrong. Remove it from the cache. */
753 simple_pwclear (cacheid);
755 /* We probably exceeded our number of attempts at guessing
756 the password. */
757 if (tries >= 3)
758 return SYMC_BAD_PASSPHRASE;
759 else
760 return 1;
763 return 0;
767 /* Not reached. */
771 /* Class confucius main program. If MODE is oEncrypt, encryption is
772 requested. If it is oDecrypt, decryption is requested. The other
773 parameters are taken from the global option data. */
775 confucius_main (int mode, int argc, char *argv[])
777 int res;
778 char *tmpdir;
779 char *infile;
780 int infile_from_stdin = 0;
781 char *outfile;
783 tmpdir = confucius_mktmpdir ();
784 if (!tmpdir)
785 return 1;
787 if (opt.input && !(opt.input[0] == '-' && opt.input[1] == '\0'))
788 infile = xstrdup (opt.input);
789 else
791 infile_from_stdin = 1;
793 /* TMPDIR + "/" + "in" + "\0". */
794 infile = malloc (strlen (tmpdir) + 1 + 2 + 1);
795 if (!infile)
797 log_error (_("cannot allocate infile string: %s\n"),
798 strerror (errno));
799 rmdir (tmpdir);
800 return 1;
802 strcpy (infile, tmpdir);
803 strcat (infile, "/in");
806 /* TMPDIR + "/" + "out" + "\0". */
807 outfile = malloc (strlen (tmpdir) + 1 + 3 + 1);
808 if (!outfile)
810 log_error (_("cannot allocate outfile string: %s\n"), strerror (errno));
811 free (infile);
812 rmdir (tmpdir);
813 return 1;
815 strcpy (outfile, tmpdir);
816 strcat (outfile, "/out");
818 if (infile_from_stdin)
820 /* Create INFILE and fill it with content. */
821 res = confucius_copy_file ("-", infile, mode == oEncrypt);
822 if (res)
824 free (outfile);
825 free (infile);
826 rmdir (tmpdir);
827 return res;
831 /* Run the engine and thus create the output file, handling
832 passphrase retrieval. */
833 res = confucius_process (mode, infile, outfile, argc, argv);
834 if (res)
836 remove_file (outfile, mode == oDecrypt);
837 if (infile_from_stdin)
838 remove_file (infile, mode == oEncrypt);
839 free (outfile);
840 free (infile);
841 rmdir (tmpdir);
842 return res;
845 /* Dump the output file to stdout. */
846 res = confucius_copy_file (outfile, "-", mode == oDecrypt);
847 if (res)
849 remove_file (outfile, mode == oDecrypt);
850 if (infile_from_stdin)
851 remove_file (infile, mode == oEncrypt);
852 free (outfile);
853 free (infile);
854 rmdir (tmpdir);
855 return res;
858 remove_file (outfile, mode == oDecrypt);
859 if (infile_from_stdin)
860 remove_file (infile, mode == oEncrypt);
861 free (outfile);
862 free (infile);
863 rmdir (tmpdir);
864 return 0;
868 /* symcryptrun's entry point. */
870 main (int argc, char **argv)
872 ARGPARSE_ARGS pargs;
873 int orig_argc;
874 char **orig_argv;
875 FILE *configfp = NULL;
876 char *configname = NULL;
877 unsigned configlineno;
878 int mode = 0;
879 int res;
880 char *logfile = NULL;
881 int default_config = 1;
883 set_strusage (my_strusage);
884 log_set_prefix ("symcryptrun", 1);
886 /* Make sure that our subsystems are ready. */
887 i18n_init();
888 init_common_subsystems ();
890 opt.homedir = default_homedir ();
892 /* Check whether we have a config file given on the commandline */
893 orig_argc = argc;
894 orig_argv = argv;
895 pargs.argc = &argc;
896 pargs.argv = &argv;
897 pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */
898 while (arg_parse( &pargs, opts))
900 if (pargs.r_opt == oOptions)
901 { /* Yes there is one, so we do not try the default one, but
902 read the option file when it is encountered at the
903 commandline */
904 default_config = 0;
906 else if (pargs.r_opt == oNoOptions)
907 default_config = 0; /* --no-options */
908 else if (pargs.r_opt == oHomedir)
909 opt.homedir = pargs.r.ret_str;
912 if (default_config)
913 configname = make_filename (opt.homedir, "symcryptrun.conf", NULL );
915 argc = orig_argc;
916 argv = orig_argv;
917 pargs.argc = &argc;
918 pargs.argv = &argv;
919 pargs.flags= 1; /* do not remove the args */
920 next_pass:
921 if (configname)
923 configlineno = 0;
924 configfp = fopen (configname, "r");
925 if (!configfp)
927 if (!default_config)
929 log_error (_("option file `%s': %s\n"),
930 configname, strerror(errno) );
931 exit(1);
933 xfree (configname);
934 configname = NULL;
936 default_config = 0;
939 /* Parse the command line. */
940 while (optfile_parse (configfp, configname, &configlineno, &pargs, opts))
942 switch (pargs.r_opt)
944 case oDecrypt: mode = oDecrypt; break;
945 case oEncrypt: mode = oEncrypt; break;
947 case oQuiet: opt.quiet = 1; break;
948 case oVerbose: opt.verbose++; break;
949 case oNoVerbose: opt.verbose = 0; break;
951 case oClass: opt.class = pargs.r.ret_str; break;
952 case oProgram: opt.program = pargs.r.ret_str; break;
953 case oKeyfile: opt.keyfile = pargs.r.ret_str; break;
954 case oInput: opt.input = pargs.r.ret_str; break;
956 case oLogFile: logfile = pargs.r.ret_str; break;
958 case oOptions:
959 /* Config files may not be nested (silently ignore them) */
960 if (!configfp)
962 xfree(configname);
963 configname = xstrdup(pargs.r.ret_str);
964 goto next_pass;
966 break;
967 case oNoOptions: break; /* no-options */
968 case oHomedir: /* Ignore this option here. */; break;
970 default : pargs.err = configfp? 1:2; break;
973 if (configfp)
975 fclose( configfp );
976 configfp = NULL;
977 configname = NULL;
978 goto next_pass;
980 xfree (configname);
981 configname = NULL;
983 if (!mode)
984 log_error (_("either %s or %s must be given\n"),
985 "--decrypt", "--encrypt");
987 if (log_get_errorcount (0))
988 exit (1);
990 if (logfile)
991 log_set_file (logfile);
993 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
994 if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
996 log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
997 NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
999 setup_libgcrypt_logging ();
1000 gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
1002 /* Tell simple-pwquery about the the standard socket name. */
1004 char *tmp = make_filename (opt.homedir, "S.gpg-agent", NULL);
1005 simple_pw_set_socket (tmp);
1006 xfree (tmp);
1009 if (!opt.class)
1011 log_error (_("no class provided\n"));
1012 res = 1;
1014 else if (!strcmp (opt.class, "confucius"))
1016 res = confucius_main (mode, argc, argv);
1018 else
1020 log_error (_("class %s is not supported\n"), opt.class);
1021 res = 1;
1024 return res;