source: roaraudio/libroar/pinentry.c @ 5889:d866fb1213d6

Last change on this file since 5889:d866fb1213d6 was 5832:f0b38d5ea016, checked in by phi, 11 years ago

added roar_libroar_get_path_static() and make use of it

File size: 7.4 KB
Line 
1//pinentry.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2013
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, const char * display, const char * tty, const 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 = roar_env_get("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 = roar_env_get("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 = roar_fork(NULL);
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    roar_watchdog_stop();
102
103    close(in[0]);
104    close(out[1]);
105    close(ROAR_STDIN);
106    close(ROAR_STDOUT);
107
108    if ( dup2(out[0], ROAR_STDIN) == -1 )
109     ROAR_U_EXIT(1);
110
111    if ( dup2(in[1], ROAR_STDOUT) == -1 )
112     ROAR_U_EXIT(1);
113
114    execlp(roar_libroar_get_path_static("bin-pinentry"), "RoarAudio", "--display", display, "--ttytype", term, "--ttyname", tty, NULL);
115
116    ROAR_U_EXIT(1);
117   break;
118 }
119
120 close(in[1]);
121 close(out[0]);
122
123 pe->in  = in[0];
124 pe->out = out[1];
125
126 pe->fin = fdopen(in[0], "r");
127
128 roar_pinentry_recv(pe, NULL, NULL);
129
130 return 0;
131#else
132 return -1;
133#endif
134}
135
136int roar_pinentry_simple_open(struct roar_pinentry * pe) {
137 return roar_pinentry_open(pe, 0, NULL, NULL, NULL);
138}
139
140int roar_pinentry_close(struct roar_pinentry * pe) {
141#ifdef _CAN_OPERATE
142 int status;
143
144 if ( pe == NULL )
145  return -1;
146
147 if ( pe->opened == 0 )
148  return 0;
149
150 if ( pe->out != -1 )
151  close(pe->out);
152
153 if ( pe->fin != NULL )
154  fclose(pe->fin);
155
156 if ( pe->in  != -1 )
157  close(pe->in);
158
159 waitpid(pe->pid, &status, 0);
160
161 memset(pe, 0, sizeof(struct roar_pinentry));
162
163 return 0;
164#else
165 return -1;
166#endif
167}
168
169int roar_pinentry_send (struct roar_pinentry * pe, char * cmd,  char * args) {
170#ifdef _CAN_OPERATE
171 size_t len;
172
173 if ( pe == NULL )
174  return -1;
175
176 if ( cmd == NULL )
177  return -1;
178
179 len = strlen(cmd);
180
181 if ( write(pe->out, cmd, len) != (ssize_t)len )
182  return -1;
183
184 if ( args != NULL ) {
185  if ( write(pe->out, " ", 1) != 1 )
186   return -1;
187
188  len = strlen(args);
189
190  if ( write(pe->out, args, len) != (ssize_t)len )
191   return -1;
192 }
193
194 if ( write(pe->out, "\n", 1) != 1 )
195  return -1;
196
197 return 0;
198#else
199 return -1;
200#endif
201}
202
203
204#define MAX_LINE_SIZE 2048
205int roar_pinentry_recv (struct roar_pinentry * pe, char ** line, char ** opts) {
206#ifdef _CAN_OPERATE
207 char realbuf[MAX_LINE_SIZE];
208 char * tp;
209
210 if ( pe == NULL )
211  return -1;
212
213 if ( pe->fin == NULL )
214  return -1;
215
216 if ( fgets(realbuf, MAX_LINE_SIZE, pe->fin) == NULL )
217  return -1;
218
219 tp = realbuf + strlen(realbuf) - 1;
220
221 for (; *tp == '\r' || *tp == '\n'; tp--)
222  *tp = 0;
223
224 if ( (tp = strstr(realbuf, " ")) == NULL ) {
225  if ( line != NULL )
226   *line = roar_mm_strdup(realbuf);
227
228  if ( opts != NULL )
229   *opts = NULL;
230
231  if ( !strcmp(realbuf, "OK") ) {
232   return 0;
233  } else if ( !strcmp(realbuf, "ERR") ) {
234   return 1;
235  } else {
236   return -1;
237  }
238 } else {
239  *tp = 0;
240
241  if ( !strcmp(realbuf, "D") ) {
242   if ( opts != NULL )
243    *opts = roar_mm_strdup(tp+1);
244
245   return roar_pinentry_recv(pe, line, NULL);
246  }
247
248  if ( line != NULL )
249   *line = roar_mm_strdup(realbuf);
250
251  if ( opts != NULL )
252   *opts = NULL;
253
254  if ( !strcmp(realbuf, "OK") ) {
255   return 0;
256  } else if ( !strcmp(realbuf, "ERR") ) {
257   return 1;
258  } else {
259   return -1;
260  }
261 }
262
263 return -1;
264#else
265 return -1;
266#endif
267}
268
269int roar_pinentry_req  (struct roar_pinentry * pe, char * cmd,  char * args, char ** line, char ** opts) {
270#ifdef ROAR_SUPPORT_PASSWORD_API
271 if ( pe == NULL )
272  return -1;
273
274 if ( roar_pinentry_send(pe, cmd, args) != 0 )
275  return -1;
276
277 return roar_pinentry_recv(pe, line, opts);
278#else
279 return -1;
280#endif
281}
282
283int roar_pinentry_set_desc (struct roar_pinentry * pe, char * desc) {
284 return roar_pinentry_set(pe, "DESC", desc);
285}
286
287int roar_pinentry_set_prompt(struct roar_pinentry * pe, char * prompt) {
288 return roar_pinentry_set(pe, "PROMPT", prompt);
289}
290
291int roar_pinentry_set_yes  (struct roar_pinentry * pe, char * yes) {
292 return roar_pinentry_set(pe, "OK", yes);
293}
294
295int roar_pinentry_set_no   (struct roar_pinentry * pe, char * no) {
296 return roar_pinentry_set(pe, "CANCEL", no);
297}
298
299int roar_pinentry_set      (struct roar_pinentry * pe, char * obj, char * text) {
300#ifdef ROAR_SUPPORT_PASSWORD_API
301 char req[80] = "SET";
302
303 if ( pe == NULL )
304  return -1;
305
306 if ( obj == NULL )
307  return -1;
308
309 if ( strlen(obj) > (80-(1 /* \0 */ + 3 /* "SET" */)) )
310  return -1;
311
312 strncat(req, obj, 80-4);
313
314 return roar_pinentry_req(pe, req, text, NULL, NULL);
315#else
316 return -1;
317#endif
318}
319
320int roar_pinentry_getpin   (struct roar_pinentry * pe, char ** pw, char * desc, char * prompt) {
321#ifdef ROAR_SUPPORT_PASSWORD_API
322 if ( pe == NULL )
323  return -1;
324
325 if ( pw == NULL )
326  return -1;
327
328 if ( desc != NULL )
329  if ( roar_pinentry_set_desc(pe, desc) != 0 )
330   return -1;
331
332 if ( prompt != NULL )
333  if ( roar_pinentry_set_prompt(pe, prompt) != 0 )
334   return -1;
335
336 if ( roar_pinentry_req(pe, "GETPIN", NULL, NULL, pw) == -1 )
337  return -1;
338
339 return 0;
340#else
341 return -1;
342#endif
343}
344
345int roar_pinentry_confirm  (struct roar_pinentry * pe, char * desc, char * yes, char * no) {
346#ifdef ROAR_SUPPORT_PASSWORD_API
347 if ( pe == NULL )
348  return -1;
349
350 if ( desc != NULL )
351  if ( roar_pinentry_set_desc(pe, desc) != 0 )
352   return -1;
353
354 if ( yes != NULL )
355  if ( roar_pinentry_set_yes(pe, yes) != 0 )
356   return -1;
357
358 if ( no != NULL )
359  if ( roar_pinentry_set_no(pe, no) != 0 )
360   return -1;
361
362 return roar_pinentry_req(pe, "CONFIRM", NULL, NULL, NULL);
363#else
364 return -1;
365#endif
366}
367
368//ll
Note: See TracBrowser for help on using the repository browser.