5 * Common code for Pixie client and server (Unix-specific)
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Header files ------------------------------------------------------*/
38 #include <sys/types.h>
44 #include <sys/socket.h>
47 #include <mLib/alloc.h>
48 #include <mLib/dstr.h>
53 /*----- Main code ---------------------------------------------------------*/
55 /* --- @pixie_address@ --- *
57 * Arguments: @const char *sock@ = pointer to socket name
58 * @size_t *psz@ = where to write the address size
60 * Returns: Pointer to filled-in Unix-domain socket address.
62 * Use: Returns a Unix-domain socket address to use to find the
66 struct sockaddr_un *pixie_address(const char *sock, size_t *psz)
70 /* --- Get the default socket path if none specified --- */
73 sock = getenv("CATACOMB_PIXIE_SOCKET");
75 sock = "%h/.catacomb/pixie";
77 /* --- Substitute interesting sequences in the path --- */
95 qq = getenv("LOGNAME");
97 struct passwd *pw = getpwuid(getuid());
108 struct passwd *pw = getpwuid(getuid());
126 /* --- Allocate and initialize the socket address --- */
129 struct sockaddr_un *sun;
130 size_t bsz = offsetof(struct sockaddr_un, sun_path);
131 *psz = bsz + d.len + 1;
132 sun = xmalloc(bsz + d.len + 1);
134 sun->sun_family = AF_UNIX;
135 memcpy(sun->sun_path, d.buf, d.len + 1);
141 /* --- @pixie_fdline@ --- *
143 * Arguments: @int fd@ = file descriptor to read from
144 * @char *buf@ = pointer to buffer
145 * @size_t sz@ = size of buffer
149 * Use: Reads a line from a file descriptor. The read is done one
150 * character at a time. If the entire line won't fit, the end
151 * is truncated. The line is null terminated.
154 void pixie_fdline(int fd, char *buf, size_t sz)
157 char *q = p + sz - 1;
161 if (read(fd, &c, 1) < 1)
171 /* --- @pixie_getpass@ --- *
173 * Arguments: @const char *prompt@ = pointer to prompt string
174 * @char *buf@ = pointer to buffer
175 * @size_t sz@ = size of buffer
177 * Returns: Zero if it worked OK, nonzero otherwise.
179 * Use: Reads a passphrase from the terminal or some other requested
183 int pixie_getpass(const char *prompt, char *buf, size_t sz)
185 const char *pfd = getenv("CATACOMB_PASSPHRASE_FD");
188 /* --- See whether a terminal is what's wanted --- */
192 pixie_fdline(fd, buf, sz);
198 if ((fd = open("/dev/tty", O_RDWR)) < 0)
200 if (tcgetattr(fd, &ta) < 0)
203 ta.c_lflag &= ~(ECHO | ISIG);
204 if (tcsetattr(fd, TCSAFLUSH, &ta))
206 write(fd, prompt, strlen(prompt));
207 pixie_fdline(fd, buf, sz);
208 tcsetattr(fd, TCSAFLUSH, &ota);
214 /* --- Tidy up if things went wrong --- */
222 /* --- @pixie_open@ --- *
224 * Arguments: @const char *sock@ = path to pixie socket
226 * Returns: Less than zero if it failed, or file descriptor.
228 * Use: Opens a connection to a passphrase pixie.
231 int pixie_open(const char *sock)
233 struct sockaddr_un *sun;
237 /* --- Open the connection --- */
239 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
241 sun = pixie_address(sock, &sz);
242 if (connect(fd, (struct sockaddr *)sun, sz))
247 /* --- Tidy up if things went wrong --- */
256 /* --- @pixie_read@ --- *
258 * Arguments: @int fd@ = connection to passphrase pixie
259 * @const char *tag@ = pointer to tag string
260 * @unsigned mode@ = reading mode
261 * @char *buf@ = pointer to destination buffer
262 * @size_t sz@ = size of the buffer
264 * Returns: Zero if all went well, @-1@ if the read fails, @+1@ to
265 * request the passphrase from the user.
267 * Use: Reads a passphrase from the pixie.
270 int pixie_read(int fd, const char *tag, unsigned mode, char *buf, size_t sz)
275 /* --- Send the request --- */
277 dstr_putf(&d, "%s %s\n", mode == PMODE_READ ? "PASS" : "VERIFY", tag);
278 write(fd, d.buf, d.len);
281 /* --- Sort out the result --- */
284 pixie_fdline(fd, buf, sz);
286 if ((q = str_getword(&p)) == 0)
288 if (strcmp(q, "INFO") == 0)
290 else if (strcmp(q, "MISSING") == 0)
292 else if (strcmp(q, "OK") != 0)
295 /* --- Return the final answer --- */
298 memmove(buf, p, strlen(p) + 1);
304 /* --- @pixie_set@ --- *
306 * Arguments: @int fd@ = pixie file descriptor
307 * @const char *tag@ = pointer to tag string
308 * @const char *phrase@ = pointer to passphrase string
312 * Use: Sends a passphrase to the passphrase pixie.
315 void pixie_set(int fd, const char *tag, const char *phrase)
319 size_t sz = strlen(phrase);
323 /* --- Send the request --- *
325 * I didn't want to copy it out of the caller's buffer. @writev@ may
326 * produce a copy, too, so I didn't do that either.
329 dstr_putf(&d, "SET %s -- ", tag);
330 write(fd, d.buf, d.len);
331 write(fd, phrase, sz);
335 /* --- Pick up the pieces --- */
338 pixie_fdline(fd, buf, sizeof(buf));
340 if ((q = str_getword(&p)) != 0 && strcmp(q, "INFO") == 0)
344 /* --- @pixie_cancel@ --- *
346 * Arguments: @int fd@ = pixie file descriptor
347 * @const char *tag@ = pointer to tag string
351 * Use: Cancels a passphrase if it turns out to be bogus.
354 void pixie_cancel(int fd, const char *tag)
360 /* --- Send the request --- */
362 dstr_putf(&d, "FLUSH %s\n", tag);
363 write(fd, d.buf, d.len);
366 /* --- Sort out the result --- */
369 pixie_fdline(fd, buf, sizeof(buf));
371 if ((q = str_getword(&p)) != 0 && strcmp(q, "INFO") == 0)
375 /*----- That's all, folks -------------------------------------------------*/