Add an internal-representation no-op function.
[u/mdw/catacomb] / pixie-common.c
1 /* -*-c-*-
2 *
3 * $Id: pixie-common.c,v 1.1 1999/12/22 15:58:41 mdw Exp $
4 *
5 * Common code for Pixie client and server (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 /*----- Revision history --------------------------------------------------*
31 *
32 * $Log: pixie-common.c,v $
33 * Revision 1.1 1999/12/22 15:58:41 mdw
34 * Passphrase pixie support.
35 *
36 */
37
38 /*----- Header files ------------------------------------------------------*/
39
40 #include <errno.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45
46 #include <sys/types.h>
47 #include <unistd.h>
48 #include <fcntl.h>
49 #include <termios.h>
50 #include <pwd.h>
51
52 #include <sys/socket.h>
53 #include <sys/un.h>
54
55 #include <mLib/alloc.h>
56 #include <mLib/dstr.h>
57
58 #include "pixie.h"
59
60 /*----- Main code ---------------------------------------------------------*/
61
62 /* --- @pixie_address@ --- *
63 *
64 * Arguments: @const char *sock@ = pointer to socket name
65 * @size_t *psz@ = where to write the address size
66 *
67 * Returns: Pointer to filled-in Unix-domain socket address.
68 *
69 * Use: Returns a Unix-domain socket address to use to find the
70 * passphrase pixie.
71 */
72
73 struct sockaddr_un *pixie_address(const char *sock, size_t *psz)
74 {
75 dstr d = DSTR_INIT;
76
77 /* --- Get the default socket path if none specified --- */
78
79 if (!sock)
80 sock = getenv("CATACOMB_PIXIE_SOCKET");
81 if (!sock)
82 sock = "%h/.catacomb/pixie";
83
84 /* --- Substitute interesting sequences in the path --- */
85
86 {
87 const char *q, *qq;
88
89 q = sock;
90 for (;;) {
91 qq = strchr(q, '%');
92 if (!qq || !qq[1]) {
93 DPUTS(&d, q);
94 break;
95 }
96 DPUTM(&d, q, qq - q);
97 q = qq + 1;
98 switch (*q) {
99 case 'u':
100 qq = getenv("USER");
101 if (!qq)
102 qq = getenv("LOGNAME");
103 if (!qq) {
104 struct passwd *pw = getpwuid(getuid());
105 if (pw)
106 qq = pw->pw_name;
107 else
108 qq = "<unknown>";
109 }
110 DPUTS(&d, qq);
111 break;
112 case 'h':
113 qq = getenv("HOME");
114 if (!qq) {
115 struct passwd *pw = getpwuid(getuid());
116 if (pw)
117 qq = pw->pw_dir;
118 else
119 qq = "<unknown>";
120 }
121 DPUTS(&d, qq);
122 break;
123 default:
124 DPUTC(&d, '%');
125 DPUTC(&d, *q);
126 break;
127 }
128 q++;
129 }
130 DPUTZ(&d);
131 }
132
133 /* --- Allocate and initialize the socket address --- */
134
135 {
136 struct sockaddr_un *sun;
137 size_t bsz = offsetof(struct sockaddr_un, sun_path);
138 *psz = bsz + d.len + 1;
139 sun = xmalloc(bsz + d.len + 1);
140 memset(sun, 0, bsz);
141 sun->sun_family = AF_UNIX;
142 memcpy(sun->sun_path, d.buf, d.len + 1);
143 dstr_destroy(&d);
144 return (sun);
145 }
146 }
147
148 /* --- @pixie_fdline@ --- *
149 *
150 * Arguments: @int fd@ = file descriptor to read from
151 * @char *buf@ = pointer to buffer
152 * @size_t sz@ = size of buffer
153 *
154 * Returns: ---
155 *
156 * Use: Reads a line from a file descriptor. The read is done one
157 * character at a time. If the entire line won't fit, the end
158 * is truncated. The line is null terminated.
159 */
160
161 void pixie_fdline(int fd, char *buf, size_t sz)
162 {
163 char *p = buf;
164 char *q = p + sz - 1;
165
166 for (;;) {
167 char c;
168 if (read(fd, &c, 1) < 1)
169 break;
170 if (c == '\n')
171 break;
172 if (p < q)
173 *p++ = c;
174 }
175 *p = 0;
176 }
177
178 /* --- @pixie_getpass@ --- *
179 *
180 * Arguments: @const char *prompt@ = pointer to prompt string
181 * @char *buf@ = pointer to buffer
182 * @size_t sz@ = size of buffer
183 *
184 * Returns: Zero if it worked OK, nonzero otherwise.
185 *
186 * Use: Reads a passphrase from the terminal or some other requested
187 * source.
188 */
189
190 int pixie_getpass(const char *prompt, char *buf, size_t sz)
191 {
192 const char *pfd = getenv("CATACOMB_PASSPHRASE_FD");
193 int fd = 0;
194
195 /* --- See whether a terminal is what's wanted --- */
196
197 if (pfd) {
198 fd = atoi(pfd);
199 pixie_fdline(fd, buf, sz);
200 } else {
201 struct termios ta;
202 struct termios ota;
203 char nl = '\n';
204
205 if ((fd = open("/dev/tty", O_RDWR)) < 0)
206 goto fail_0;
207 if (tcgetattr(fd, &ta) < 0)
208 goto fail_1;
209 ota = ta;
210 ta.c_lflag &= ~(ECHO | ISIG);
211 if (tcsetattr(fd, TCSAFLUSH, &ta))
212 goto fail_1;
213 write(fd, prompt, strlen(prompt));
214 pixie_fdline(fd, buf, sz);
215 tcsetattr(fd, TCSAFLUSH, &ota);
216 write(fd, &nl, 1);
217 close(fd);
218 }
219 return (0);
220
221 /* --- Tidy up if things went wrong --- */
222
223 fail_1:
224 close(fd);
225 fail_0:
226 return (-1);
227 }
228
229
230 /*----- That's all, folks -------------------------------------------------*/
231