chiark / gitweb /
progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / key / passphrase.c
1 /* -*-c-*-
2  *
3  * Reading of passphrases (Unix-specific)
4  *
5  * (c) 1999 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Catacomb.
11  *
12  * Catacomb is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * Catacomb is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with Catacomb; if not, write to the Free
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include <unistd.h>
36
37 #include <mLib/dstr.h>
38 #include <mLib/macros.h>
39
40 #include "passphrase.h"
41 #include "pixie.h"
42
43 /*----- Static variables --------------------------------------------------*/
44
45 static int fd = -1;
46 static unsigned flags = 0;
47
48 #define f_fail 1u
49
50 /*----- Main code ---------------------------------------------------------*/
51
52 /* --- @passphrase_connect@ ---
53  *
54  * Arguments:   @const char *sock@ = socket name to connect to, or null for
55  *              default
56  *
57  * Returns:     Zero if OK, nonzero if it failed
58  *
59  * Use:         Attempts to connect to the passphrase pixie.
60  */
61
62 int passphrase_connect(const char *sock)
63 {
64   if (fd != -1)
65     close(fd);
66   if ((fd = pixie_open(sock)) < 0) {
67     flags |= f_fail;
68     return (-1);
69   }
70   flags &= ~f_fail;
71   return (0);
72 }
73
74 static int pconn(void)
75 {
76   if (fd != -1)
77     return (0);
78   if (flags & f_fail)
79     return (-1);
80   return (passphrase_connect(0));
81 }
82
83 /* --- @passphrase_read@ --- *
84  *
85  * Arguments:   @const char *tag@ = pointer to passphrase tag string
86  *              @unsigned mode@ = reading mode
87  *              @char *buf@ = pointer to destination buffer
88  *              @size_t sz@ = size of destination buffer
89  *
90  * Returns:     Zero if successful, nonzero on failure.
91  *
92  * Use:         Reads a passphrase from the user, using some system-specific
93  *              secure mechanism.  The mechanism may keep a cache of
94  *              passphrases, so the user may not necessarily be prompted.
95  */
96
97 int passphrase_read(const char *tag, unsigned mode, char *buf, size_t sz)
98 {
99   dstr d = DSTR_INIT;
100   int rc = 1;
101
102   /* --- Try talking to the pixie --- */
103
104   if (!pconn()) {
105     rc = pixie_read(fd, tag, mode, buf, sz);
106     if (rc < 0) {
107       close(fd);
108       fd = -1;
109       return (-1);
110     }
111     if (rc == 0)
112       return (0);
113   }
114
115   /* --- Read from the terminal --- */
116
117   dstr_putf(&d, "%s %s: ",
118             mode == PMODE_READ ? "Passphrase" : "New passphrase",
119             tag);
120   if (pixie_getpass(d.buf, buf, sz))
121     goto fail;
122   if (mode == PMODE_VERIFY) {
123     char b[1024];
124     DRESET(&d);
125     dstr_putf(&d, "Verify passphrase %s: ", tag);
126     if (pixie_getpass(d.buf, b, sizeof(b)) || STRCMP(b, !=, buf)) {
127       memset(b, 0, sizeof(b));
128       goto fail;
129     }
130   }
131   dstr_destroy(&d);
132
133   /* --- If the pixie is interested, tell it the new passphrase --- */
134
135   if (fd >= 0)
136     pixie_set(fd, tag, buf);
137   return (0);
138
139   /* --- Tidy up after a failure --- */
140
141 fail:
142   dstr_destroy(&d);
143   memset(buf, 0, sz);
144   return (-1);
145 }
146
147 /* --- @passphrase_cancel@ --- *
148  *
149  * Arguments:   @const char *tag@ = pointer to passphrase tag string
150  *
151  * Returns:     ---
152  *
153  * Use:         Attempts to make the passphrase cache forget about a
154  *              particular passphrase.  This may be useful if the passphrase
155  *              turns out to be wrong, or if the user is attempting to change
156  *              the passphrase.
157  */
158
159 void passphrase_cancel(const char *tag)
160 {
161   if (!pconn())
162     pixie_cancel(fd, tag);
163 }
164
165 /*----- That's all, folks -------------------------------------------------*/