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 -------------------------------------------------*/