General utilities cleanup. Add signature support to catcrypt. Throw in
[u/mdw/catacomb] / pixie-client.c
1 /* -*-c-*-
2 *
3 * $Id: pixie-client.c,v 1.3 2004/04/08 01:36:15 mdw Exp $
4 *
5 * Simple passphrase pixie client (Unix-specific)
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30 /*----- Header files ------------------------------------------------------*/
31
32 #include <errno.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include <sys/types.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <pwd.h>
41
42 #include <sys/socket.h>
43 #include <sys/un.h>
44
45 #include <mLib/dstr.h>
46 #include <mLib/fdflags.h>
47 #include <mLib/str.h>
48
49 #include "passphrase.h"
50 #include "pixie.h"
51
52 /*----- Main code ---------------------------------------------------------*/
53
54 /* --- @pixie_open@ --- *
55 *
56 * Arguments: @const char *sock@ = path to pixie socket
57 *
58 * Returns: Less than zero if it failed, or file descriptor.
59 *
60 * Use: Opens a connection to a passphrase pixie.
61 */
62
63 int pixie_open(const char *sock)
64 {
65 struct sockaddr_un *sun;
66 size_t sz;
67 int fd;
68
69 /* --- Open the connection --- */
70
71 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
72 goto fail_0;
73 sun = pixie_address(sock, &sz);
74 if (connect(fd, (struct sockaddr *)sun, sz))
75 goto fail_1;
76 free(sun);
77 return (fd);
78
79 /* --- Tidy up if things went wrong --- */
80
81 fail_1:
82 free(sun);
83 close(fd);
84 fail_0:
85 return (-1);
86 }
87
88 /* --- @pixie_read@ --- *
89 *
90 * Arguments: @int fd@ = connection to passphrase pixie
91 * @const char *tag@ = pointer to tag string
92 * @unsigned mode@ = reading mode
93 * @char *buf@ = pointer to destination buffer
94 * @size_t sz@ = size of the buffer
95 *
96 * Returns: Zero if all went well, @-1@ if the read fails, @+1@ to
97 * request the passphrase from the user.
98 *
99 * Use: Reads a passphrase from the pixie.
100 */
101
102 int pixie_read(int fd, const char *tag, unsigned mode, char *buf, size_t sz)
103 {
104 dstr d = DSTR_INIT;
105 char *p, *q;
106
107 /* --- Send the request --- */
108
109 dstr_putf(&d, "%s %s\n", mode == PMODE_READ ? "PASS" : "VERIFY", tag);
110 write(fd, d.buf, d.len);
111 dstr_destroy(&d);
112
113 /* --- Sort out the result --- */
114
115 again:
116 pixie_fdline(fd, buf, sz);
117 p = buf;
118 if ((q = str_getword(&p)) == 0)
119 return (-1);
120 if (strcmp(q, "INFO") == 0)
121 goto again;
122 else if (strcmp(q, "MISSING") == 0)
123 return (+1);
124 else if (strcmp(q, "OK") != 0)
125 return (-1);
126
127 /* --- Return the final answer --- */
128
129 if (p)
130 memmove(buf, p, strlen(p) + 1);
131 else
132 *buf = 0;
133 return (0);
134 }
135
136 /* --- @pixie_set@ --- *
137 *
138 * Arguments: @int fd@ = pixie file descriptor
139 * @const char *tag@ = pointer to tag string
140 * @const char *phrase@ = pointer to passphrase string
141 *
142 * Returns: ---
143 *
144 * Use: Sends a passphrase to the passphrase pixie.
145 */
146
147 void pixie_set(int fd, const char *tag, const char *phrase)
148 {
149 dstr d = DSTR_INIT;
150 char buf[16];
151 size_t sz = strlen(phrase);
152 char nl = '\n';
153 char *p, *q;
154
155 /* --- Send the request --- *
156 *
157 * I didn't want to copy it out of the caller's buffer. @writev@ may
158 * produce a copy, too, so I didn't do that either.
159 */
160
161 dstr_putf(&d, "SET %s -- ", tag);
162 write(fd, d.buf, d.len);
163 write(fd, phrase, sz);
164 write(fd, &nl, 1);
165 dstr_destroy(&d);
166
167 /* --- Pick up the pieces --- */
168
169 again:
170 pixie_fdline(fd, buf, sizeof(buf));
171 p = buf;
172 if ((q = str_getword(&p)) != 0 && strcmp(q, "INFO") == 0)
173 goto again;
174 }
175
176 /* --- @pixie_cancel@ --- *
177 *
178 * Arguments: @int fd@ = pixie file descriptor
179 * @const char *tag@ = pointer to tag string
180 *
181 * Returns: ---
182 *
183 * Use: Cancels a passphrase if it turns out to be bogus.
184 */
185
186 void pixie_cancel(int fd, const char *tag)
187 {
188 dstr d = DSTR_INIT;
189 char buf[16];
190 char *p, *q;
191
192 /* --- Send the request --- */
193
194 dstr_putf(&d, "FLUSH %s\n", tag);
195 write(fd, d.buf, d.len);
196 dstr_destroy(&d);
197
198 /* --- Sort out the result --- */
199
200 again:
201 pixie_fdline(fd, buf, sizeof(buf));
202 p = buf;
203 if ((q = str_getword(&p)) != 0 && strcmp(q, "INFO") == 0)
204 goto again;
205 }
206
207 /*----- That's all, folks -------------------------------------------------*/