source: roaraudio/libroar/pinentry.c @ 1234:a7b79e64107a

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

wrote the rest, hope it works *g*

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