source: roaraudio/libroar/pinentry.c @ 5895:2bcffab4cd73

Last change on this file since 5895:2bcffab4cd73 was 5895:2bcffab4cd73, checked in by phi, 11 years ago

Moved away from roar_libroar_get_path_static()

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