source: roaraudio/libroar/pinentry.c @ 1790:ceaf44c70330

Last change on this file since 1790:ceaf44c70330 was 1790:ceaf44c70330, checked in by phi, 15 years ago

test for ROAR_HAVE_TTYNAME (dummy), ROAR_HAVE_FORK, ROAR_HAVE_PIPE

File size: 7.2 KB
Line 
1//pinentry.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "libroar.h"
36
37// TODO: need to check: && defined(ROAR_HAVE_TTYNAME)
38#if defined(ROAR_HAVE_FORK) && defined(ROAR_HAVE_PIPE)
39#define _CAN_POSIX
40#endif
41
42#if defined(ROAR_HAVE_BIN_PINENTRY) && defined(ROAR_SUPPORT_PASSWORD_API) && defined(_CAN_POSIX)
43#define _CAN_OPERATE
44#endif
45
46int roar_pinentry_open (struct roar_pinentry * pe, int flags, char * display, char * tty, char * term) {
47#ifdef _CAN_OPERATE
48 int in[2], out[2];
49
50 if ( pe == NULL )
51  return -1;
52
53 memset(pe, 0, sizeof(struct roar_pinentry));
54 pe->in  = -1;
55 pe->out = -1;
56
57 if ( display == NULL )
58  display = getenv("DISPLAY");
59
60 if ( display == NULL )
61  display = "(NONE)";
62
63 if ( tty == NULL )
64  tty = ttyname(ROAR_STDIN);
65
66 if ( tty == NULL )
67#ifdef ROAR_DEFAULT_TTY
68  tty = ROAR_DEFAULT_TTY;
69#else
70  return -1;
71#endif
72
73 if ( term == NULL )
74  term = getenv("TERM");
75
76 if ( term == NULL )
77  term = "dumb";
78
79 // open some pipes...
80 if ( pipe(in) != 0 )
81  return -1;
82
83 if ( pipe(out) != 0 ) {
84  close(in[0]);
85  close(in[1]);
86  return -1;
87 }
88
89 pe->pid = fork();
90
91 switch (pe->pid) {
92  case -1:
93    close(in[0]);
94    close(in[1]);
95    close(out[0]);
96    close(out[1]);
97    return -1;
98   break;
99  case 0:
100    close(in[0]);
101    close(out[1]);
102    close(ROAR_STDIN);
103    close(ROAR_STDOUT);
104
105    if ( dup2(out[0], ROAR_STDIN) == -1 )
106     _exit(1);
107
108    if ( dup2(in[1], ROAR_STDOUT) == -1 )
109     _exit(1);
110
111    execlp(ROAR_HAVE_BIN_PINENTRY, "RoarAudio", "--display", display, "--ttytype", term, "--ttyname", tty, NULL);
112
113    _exit(1);
114   break;
115 }
116
117 close(in[1]);
118 close(out[0]);
119
120 pe->in  = in[0];
121 pe->out = out[1];
122
123 pe->fin = fdopen(in[0], "r");
124
125 roar_pinentry_recv(pe, NULL, NULL);
126
127 return 0;
128#else
129 return -1;
130#endif
131}
132
133int roar_pinentry_simple_open(struct roar_pinentry * pe) {
134 return roar_pinentry_open(pe, 0, NULL, NULL, NULL);
135}
136
137int roar_pinentry_close(struct roar_pinentry * pe) {
138#ifdef _CAN_OPERATE
139 int status;
140
141 if ( pe == NULL )
142  return -1;
143
144 if ( pe->opened == 0 )
145  return 0;
146
147 if ( pe->out != -1 )
148  close(pe->out);
149
150 if ( pe->fin != NULL )
151  fclose(pe->fin);
152
153 if ( pe->in  != -1 )
154  close(pe->in);
155
156 waitpid(pe->pid, &status, 0);
157
158 memset(pe, 0, sizeof(struct roar_pinentry));
159
160 return 0;
161#else
162 return -1;
163#endif
164}
165
166int roar_pinentry_send (struct roar_pinentry * pe, char * cmd,  char * args) {
167#ifdef _CAN_OPERATE
168 size_t len;
169
170 if ( pe == NULL )
171  return -1;
172
173 if ( cmd == NULL )
174  return -1;
175
176 len = strlen(cmd);
177
178 if ( write(pe->out, cmd, len) != len )
179  return -1;
180
181 if ( args != NULL ) {
182  if ( write(pe->out, " ", 1) != 1 )
183   return -1;
184
185  len = strlen(args);
186
187  if ( write(pe->out, args, len) != len )
188   return -1;
189 }
190
191 if ( write(pe->out, "\n", 1) != 1 )
192  return -1;
193
194 return 0;
195#else
196 return -1;
197#endif
198}
199
200
201#define MAX_LINE_SIZE 2048
202int roar_pinentry_recv (struct roar_pinentry * pe, char ** line, char ** opts) {
203#ifdef _CAN_OPERATE
204 char realbuf[MAX_LINE_SIZE];
205 char * tp;
206
207 if ( pe == NULL )
208  return -1;
209
210 if ( pe->fin == NULL )
211  return -1;
212
213 if ( fgets(realbuf, MAX_LINE_SIZE, pe->fin) == NULL )
214  return -1;
215
216 tp = realbuf + strlen(realbuf) - 1;
217
218 for (; *tp == '\r' || *tp == '\n'; tp--)
219  *tp = 0;
220
221 if ( (tp = strstr(realbuf, " ")) == NULL ) {
222  if ( line != NULL )
223   *line = strdup(realbuf);
224
225  if ( opts != NULL )
226   *opts = NULL;
227
228  if ( !strcmp(realbuf, "OK") ) {
229   return 0;
230  } else if ( !strcmp(realbuf, "ERR") ) {
231   return 1;
232  } else {
233   return -1;
234  }
235 } else {
236  *tp = 0;
237
238  if ( !strcmp(realbuf, "D") ) {
239   if ( opts != NULL )
240    *opts = strdup(tp+1);
241
242   return roar_pinentry_recv(pe, line, NULL);
243  }
244
245  if ( line != NULL )
246   *line = strdup(realbuf);
247
248  if ( opts != NULL )
249   *opts = NULL;
250
251  if ( !strcmp(realbuf, "OK") ) {
252   return 0;
253  } else if ( !strcmp(realbuf, "ERR") ) {
254   return 1;
255  } else {
256   return -1;
257  }
258 }
259
260 return -1;
261#else
262 return -1;
263#endif
264}
265
266int roar_pinentry_req  (struct roar_pinentry * pe, char * cmd,  char * args, char ** line, char ** opts) {
267#ifdef ROAR_SUPPORT_PASSWORD_API
268 if ( pe == NULL )
269  return -1;
270
271 if ( roar_pinentry_send(pe, cmd, args) != 0 )
272  return -1;
273
274 return roar_pinentry_recv(pe, line, opts);
275#else
276 return -1;
277#endif
278}
279
280int roar_pinentry_set_desc (struct roar_pinentry * pe, char * desc) {
281 return roar_pinentry_set(pe, "DESC", desc);
282}
283
284int roar_pinentry_set_prompt(struct roar_pinentry * pe, char * prompt) {
285 return roar_pinentry_set(pe, "PROMPT", prompt);
286}
287
288int roar_pinentry_set_yes  (struct roar_pinentry * pe, char * yes) {
289 return roar_pinentry_set(pe, "OK", yes);
290}
291
292int roar_pinentry_set_no   (struct roar_pinentry * pe, char * no) {
293 return roar_pinentry_set(pe, "CANCEL", no);
294}
295
296int roar_pinentry_set      (struct roar_pinentry * pe, char * obj, char * text) {
297#ifdef ROAR_SUPPORT_PASSWORD_API
298 char req[80] = "SET";
299
300 if ( pe == NULL )
301  return -1;
302
303 if ( obj == NULL )
304  return -1;
305
306 if ( strlen(obj) > (80-(1 /* \0 */ + 3 /* "SET" */)) )
307  return -1;
308
309 strncat(req, obj, 80-4);
310
311 return roar_pinentry_req(pe, req, text, NULL, NULL);
312#else
313 return -1;
314#endif
315}
316
317int roar_pinentry_getpin   (struct roar_pinentry * pe, char ** pw, char * desc, char * prompt) {
318#ifdef ROAR_SUPPORT_PASSWORD_API
319 if ( pe == NULL )
320  return -1;
321
322 if ( pw == NULL )
323  return -1;
324
325 if ( desc != NULL )
326  if ( roar_pinentry_set_desc(pe, desc) != 0 )
327   return -1;
328
329 if ( prompt != NULL )
330  if ( roar_pinentry_set_prompt(pe, prompt) != 0 )
331   return -1;
332
333 if ( roar_pinentry_req(pe, "GETPIN", NULL, NULL, pw) == -1 )
334  return -1;
335
336 return 0;
337#else
338 return -1;
339#endif
340}
341
342int roar_pinentry_confirm  (struct roar_pinentry * pe, char * desc, char * yes, char * no) {
343#ifdef ROAR_SUPPORT_PASSWORD_API
344 if ( pe == NULL )
345  return -1;
346
347 if ( desc != NULL )
348  if ( roar_pinentry_set_desc(pe, desc) != 0 )
349   return -1;
350
351 if ( yes != NULL )
352  if ( roar_pinentry_set_yes(pe, yes) != 0 )
353   return -1;
354
355 if ( no != NULL )
356  if ( roar_pinentry_set_no(pe, no) != 0 )
357   return -1;
358
359 return roar_pinentry_req(pe, "CONFIRM", NULL, NULL, NULL);
360#else
361 return -1;
362#endif
363}
364
365//ll
Note: See TracBrowser for help on using the repository browser.