source: roaraudio/libroar/pinentry.c @ 1398:8285e9c45919

Last change on this file since 1398:8285e9c45919 was 1398:8285e9c45919, checked in by phi, 15 years ago

make password api optional

File size: 7.1 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
37int roar_pinentry_open (struct roar_pinentry * pe, int flags, char * display, char * tty, char * term) {
38#if defined(ROAR_HAVE_BIN_PINENTRY) && defined(ROAR_SUPPORT_PASSWORD_API)
39 int in[2], out[2];
40
41 if ( pe == NULL )
42  return -1;
43
44 memset(pe, 0, sizeof(struct roar_pinentry));
45 pe->in  = -1;
46 pe->out = -1;
47
48 if ( display == NULL )
49  display = getenv("DISPLAY");
50
51 if ( display == NULL )
52  display = "(NONE)";
53
54 if ( tty == NULL )
55  tty = ttyname(ROAR_STDIN);
56
57 if ( tty == NULL )
58#ifdef ROAR_DEFAULT_TTY
59  tty = ROAR_DEFAULT_TTY;
60#else
61  return -1;
62#endif
63
64 if ( term == NULL )
65  term = getenv("TERM");
66
67 if ( term == NULL )
68  term = "dumb";
69
70 // open some pipes...
71 if ( pipe(in) != 0 )
72  return -1;
73
74 if ( pipe(out) != 0 ) {
75  close(in[0]);
76  close(in[1]);
77  return -1;
78 }
79
80 pe->pid = fork();
81
82 switch (pe->pid) {
83  case -1:
84    close(in[0]);
85    close(in[1]);
86    close(out[0]);
87    close(out[1]);
88    return -1;
89   break;
90  case 0:
91    close(in[0]);
92    close(out[1]);
93    close(ROAR_STDIN);
94    close(ROAR_STDOUT);
95
96    if ( dup2(out[0], ROAR_STDIN) == -1 )
97     _exit(1);
98
99    if ( dup2(in[1], ROAR_STDOUT) == -1 )
100     _exit(1);
101
102    execlp(ROAR_HAVE_BIN_PINENTRY, "RoarAudio", "--display", display, "--ttytype", term, "--ttyname", tty, NULL);
103
104    _exit(1);
105   break;
106 }
107
108 close(in[1]);
109 close(out[0]);
110
111 pe->in  = in[0];
112 pe->out = out[1];
113
114 pe->fin = fdopen(in[0], "r");
115
116 roar_pinentry_recv(pe, NULL, NULL);
117
118 return 0;
119#else
120 return -1;
121#endif
122}
123
124int roar_pinentry_simple_open(struct roar_pinentry * pe) {
125 return roar_pinentry_open(pe, 0, NULL, NULL, NULL);
126}
127
128int roar_pinentry_close(struct roar_pinentry * pe) {
129#if defined(ROAR_HAVE_BIN_PINENTRY) && defined(ROAR_SUPPORT_PASSWORD_API)
130 int status;
131
132 if ( pe == NULL )
133  return -1;
134
135 if ( pe->opened == 0 )
136  return 0;
137
138 if ( pe->out != -1 )
139  close(pe->out);
140
141 if ( pe->fin != NULL )
142  fclose(pe->fin);
143
144 if ( pe->in  != -1 )
145  close(pe->in);
146
147 waitpid(pe->pid, &status, 0);
148
149 memset(pe, 0, sizeof(struct roar_pinentry));
150
151 return 0;
152#else
153 return -1;
154#endif
155}
156
157int roar_pinentry_send (struct roar_pinentry * pe, char * cmd,  char * args) {
158#if defined(ROAR_HAVE_BIN_PINENTRY) && defined(ROAR_SUPPORT_PASSWORD_API)
159 size_t len;
160
161 if ( pe == NULL )
162  return -1;
163
164 if ( cmd == NULL )
165  return -1;
166
167 len = strlen(cmd);
168
169 if ( write(pe->out, cmd, len) != len )
170  return -1;
171
172 if ( args != NULL ) {
173  if ( write(pe->out, " ", 1) != 1 )
174   return -1;
175
176  len = strlen(args);
177
178  if ( write(pe->out, args, len) != len )
179   return -1;
180 }
181
182 if ( write(pe->out, "\n", 1) != 1 )
183  return -1;
184
185 return 0;
186#else
187 return -1;
188#endif
189}
190
191
192#define MAX_LINE_SIZE 2048
193int roar_pinentry_recv (struct roar_pinentry * pe, char ** line, char ** opts) {
194#if defined(ROAR_HAVE_BIN_PINENTRY) && defined(ROAR_SUPPORT_PASSWORD_API)
195 char realbuf[MAX_LINE_SIZE];
196 char * tp;
197
198 if ( pe == NULL )
199  return -1;
200
201 if ( pe->fin == NULL )
202  return -1;
203
204 if ( fgets(realbuf, MAX_LINE_SIZE, pe->fin) == NULL )
205  return -1;
206
207 tp = realbuf + strlen(realbuf) - 1;
208
209 for (; *tp == '\r' || *tp == '\n'; tp--)
210  *tp = 0;
211
212 if ( (tp = strstr(realbuf, " ")) == NULL ) {
213  if ( line != NULL )
214   *line = strdup(realbuf);
215
216  if ( opts != NULL )
217   *opts = NULL;
218
219  if ( !strcmp(realbuf, "OK") ) {
220   return 0;
221  } else if ( !strcmp(realbuf, "ERR") ) {
222   return 1;
223  } else {
224   return -1;
225  }
226 } else {
227  *tp = 0;
228
229  if ( !strcmp(realbuf, "D") ) {
230   if ( opts != NULL )
231    *opts = strdup(tp+1);
232
233   return roar_pinentry_recv(pe, line, NULL);
234  }
235
236  if ( line != NULL )
237   *line = strdup(realbuf);
238
239  if ( opts != NULL )
240   *opts = NULL;
241
242  if ( !strcmp(realbuf, "OK") ) {
243   return 0;
244  } else if ( !strcmp(realbuf, "ERR") ) {
245   return 1;
246  } else {
247   return -1;
248  }
249 }
250
251 return -1;
252#else
253 return -1;
254#endif
255}
256
257int roar_pinentry_req  (struct roar_pinentry * pe, char * cmd,  char * args, char ** line, char ** opts) {
258#ifdef ROAR_SUPPORT_PASSWORD_API
259 if ( pe == NULL )
260  return -1;
261
262 if ( roar_pinentry_send(pe, cmd, args) != 0 )
263  return -1;
264
265 return roar_pinentry_recv(pe, line, opts);
266#else
267 return -1;
268#endif
269}
270
271int roar_pinentry_set_desc (struct roar_pinentry * pe, char * desc) {
272 return roar_pinentry_set(pe, "DESC", desc);
273}
274
275int roar_pinentry_set_prompt(struct roar_pinentry * pe, char * prompt) {
276 return roar_pinentry_set(pe, "PROMPT", prompt);
277}
278
279int roar_pinentry_set_yes  (struct roar_pinentry * pe, char * yes) {
280 return roar_pinentry_set(pe, "OK", yes);
281}
282
283int roar_pinentry_set_no   (struct roar_pinentry * pe, char * no) {
284 return roar_pinentry_set(pe, "CANCEL", no);
285}
286
287int roar_pinentry_set      (struct roar_pinentry * pe, char * obj, char * text) {
288#ifdef ROAR_SUPPORT_PASSWORD_API
289 char req[80] = "SET";
290
291 if ( pe == NULL )
292  return -1;
293
294 if ( obj == NULL )
295  return -1;
296
297 if ( strlen(obj) > (80-(1 /* \0 */ + 3 /* "SET" */)) )
298  return -1;
299
300 strncat(req, obj, 80-4);
301
302 return roar_pinentry_req(pe, req, text, NULL, NULL);
303#else
304 return -1;
305#endif
306}
307
308int roar_pinentry_getpin   (struct roar_pinentry * pe, char ** pw, char * desc, char * prompt) {
309#ifdef ROAR_SUPPORT_PASSWORD_API
310 if ( pe == NULL )
311  return -1;
312
313 if ( pw == NULL )
314  return -1;
315
316 if ( desc != NULL )
317  if ( roar_pinentry_set_desc(pe, desc) != 0 )
318   return -1;
319
320 if ( prompt != NULL )
321  if ( roar_pinentry_set_prompt(pe, prompt) != 0 )
322   return -1;
323
324 if ( roar_pinentry_req(pe, "GETPIN", NULL, NULL, pw) == -1 )
325  return -1;
326
327 return 0;
328#else
329 return -1;
330#endif
331}
332
333int roar_pinentry_confirm  (struct roar_pinentry * pe, char * desc, char * yes, char * no) {
334#ifdef ROAR_SUPPORT_PASSWORD_API
335 if ( pe == NULL )
336  return -1;
337
338 if ( desc != NULL )
339  if ( roar_pinentry_set_desc(pe, desc) != 0 )
340   return -1;
341
342 if ( yes != NULL )
343  if ( roar_pinentry_set_yes(pe, yes) != 0 )
344   return -1;
345
346 if ( no != NULL )
347  if ( roar_pinentry_set_no(pe, no) != 0 )
348   return -1;
349
350 return roar_pinentry_req(pe, "CONFIRM", NULL, NULL, NULL);
351#else
352 return -1;
353#endif
354}
355
356//ll
Note: See TracBrowser for help on using the repository browser.