source: roaraudio/libroar/pinentry.c @ 5326:dd73c777e8dd

Last change on this file since 5326:dd73c777e8dd was 5270:e25346c13638, checked in by phi, 12 years ago

fixed some gcc -Wextra warnings

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