1 /***************************************************************************
2 begin : Sat Dec 01 2018
3 copyright : (C) 2018 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10
11 /* included from provider.c */
12
13
14
15
16
readFile(const char * fname,GWEN_BUFFER * dbuf)17 static int readFile(const char *fname, GWEN_BUFFER *dbuf)
18 {
19 FILE *f;
20
21 f=fopen(fname, "rb");
22 if (f) {
23 while (!feof(f)) {
24 uint32_t l;
25 ssize_t s;
26 char *p;
27
28 GWEN_Buffer_AllocRoom(dbuf, 1024);
29 l=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf);
30 p=GWEN_Buffer_GetPosPointer(dbuf);
31 s=fread(p, 1, l, f);
32 if (s==0)
33 break;
34 if (s==(ssize_t)-1) {
35 DBG_ERROR(AQPAYPAL_LOGDOMAIN,
36 "fread(%s): %s",
37 fname, strerror(errno));
38 fclose(f);
39 return GWEN_ERROR_IO;
40 }
41
42 GWEN_Buffer_IncrementPos(dbuf, s);
43 GWEN_Buffer_AdjustUsedBytes(dbuf);
44 }
45
46 fclose(f);
47 return 0;
48 }
49 else {
50 DBG_ERROR(AQPAYPAL_LOGDOMAIN,
51 "fopen(%s): %s",
52 fname, strerror(errno));
53 return GWEN_ERROR_IO;
54 }
55 }
56
57
58
writeToFile(FILE * f,const char * p,int len)59 static int writeToFile(FILE *f, const char *p, int len)
60 {
61 while (len>0) {
62 ssize_t l;
63 ssize_t s;
64
65 l=1024;
66 if (l>len)
67 l=len;
68 s=fwrite(p, 1, l, f);
69 if (s==(ssize_t)-1 || s==0) {
70 DBG_ERROR(AQPAYPAL_LOGDOMAIN,
71 "fwrite: %s",
72 strerror(errno));
73 return GWEN_ERROR_IO;
74 }
75 p+=s;
76 len-=s;
77 }
78
79 return 0;
80 }
81
82
83
writeFile(const char * fname,const char * p,int len)84 static int writeFile(const char *fname, const char *p, int len)
85 {
86 FILE *f;
87
88 f=fopen(fname, "wb");
89 if (f) {
90 int rv;
91
92 rv=writeToFile(f, p, len);
93 if (rv<0) {
94 DBG_ERROR(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
95 fclose(f);
96 return rv;
97 }
98 if (fclose(f)) {
99 DBG_ERROR(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
100 return rv;
101 }
102 }
103 else {
104 DBG_ERROR(AQPAYPAL_LOGDOMAIN, "fopen(%s): %s",
105 fname, strerror(errno));
106 return GWEN_ERROR_IO;
107 }
108
109 return 0;
110 }
111
112
113
114
APY_Provider_ReadUserApiSecrets(AB_PROVIDER * pro,const AB_USER * u,GWEN_BUFFER * secbuf)115 int APY_Provider_ReadUserApiSecrets(AB_PROVIDER *pro, const AB_USER *u, GWEN_BUFFER *secbuf)
116 {
117 APY_PROVIDER *xp;
118 int rv;
119 GWEN_BUFFER *pbuf;
120 GWEN_BUFFER *sbuf;
121 GWEN_BUFFER *tbuf;
122 const char *uid;
123 char text[512];
124 char pw[129];
125
126 assert(pro);
127 xp=GWEN_INHERIT_GETDATA(AB_PROVIDER, APY_PROVIDER, pro);
128 assert(xp);
129
130 uid=AB_User_GetUserId(u);
131 if (!(uid && *uid)) {
132 DBG_ERROR(AQPAYPAL_LOGDOMAIN, "No user id");
133 return GWEN_ERROR_INVALID;
134 }
135
136 pbuf=GWEN_Buffer_new(0, 256, 0, 1);
137 rv=AB_Provider_GetUserDataDir(pro, pbuf);
138 if (rv<0) {
139 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
140 GWEN_Buffer_free(pbuf);
141 return rv;
142 }
143
144 GWEN_Buffer_AppendString(pbuf, GWEN_DIR_SEPARATOR_S);
145 GWEN_Text_UnescapeToBufferTolerant(uid, pbuf);
146 GWEN_Buffer_AppendString(pbuf, ".sec");
147
148 sbuf=GWEN_Buffer_new(0, 256, 0, 1);
149 rv=readFile(GWEN_Buffer_GetStart(pbuf), sbuf);
150 if (rv<0) {
151 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
152 GWEN_Buffer_free(sbuf);
153 GWEN_Buffer_free(pbuf);
154 return rv;
155 }
156
157 snprintf(text, sizeof(text)-1,
158 I18N("Please enter the password for \n"
159 "Paypal user %s\n"
160 "<html>"
161 "Please enter the password for Paypal user <i>%s</i></br>"
162 "</html>"),
163 uid, uid);
164 text[sizeof(text)-1]=0;
165
166 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
167 GWEN_Buffer_AppendString(tbuf, "PASSWORD_");
168 GWEN_Text_UnescapeToBufferTolerant(GWEN_Buffer_GetStart(pbuf), tbuf);
169
170 rv=GWEN_Gui_GetPassword(0,
171 GWEN_Buffer_GetStart(tbuf),
172 I18N("Enter Password"),
173 text,
174 pw,
175 4,
176 sizeof(pw)-1,
177 GWEN_Gui_PasswordMethod_Text, NULL,
178 0);
179 if (rv<0) {
180 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
181 GWEN_Buffer_free(tbuf);
182 GWEN_Buffer_free(sbuf);
183 GWEN_Buffer_free(pbuf);
184 return rv;
185 }
186
187 rv=GWEN_SmallTresor_Decrypt((const uint8_t *) GWEN_Buffer_GetStart(sbuf),
188 GWEN_Buffer_GetUsedBytes(sbuf),
189 pw,
190 secbuf,
191 AQPAYPAL_PASSWORD_ITERATIONS,
192 AQPAYPAL_CRYPT_ITERATIONS);
193 /* overwrite password ASAP */
194 memset(pw, 0, sizeof(pw));
195 GWEN_Buffer_free(tbuf);
196 GWEN_Buffer_free(sbuf);
197 GWEN_Buffer_free(pbuf);
198 if (rv<0) {
199 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
200 return rv;
201 }
202
203 return 0;
204 }
205
206
207
APY_Provider_WriteUserApiSecrets(AB_PROVIDER * pro,const AB_USER * u,const char * sec)208 int APY_Provider_WriteUserApiSecrets(AB_PROVIDER *pro, const AB_USER *u, const char *sec)
209 {
210 APY_PROVIDER *xp;
211 int rv;
212 GWEN_BUFFER *pbuf;
213 GWEN_BUFFER *sbuf;
214 GWEN_BUFFER *tbuf;
215 const char *uid;
216 char text[512];
217 char pw[129];
218
219 assert(pro);
220 xp=GWEN_INHERIT_GETDATA(AB_PROVIDER, APY_PROVIDER, pro);
221 assert(xp);
222
223 uid=AB_User_GetUserId(u);
224 if (!(uid && *uid)) {
225 DBG_ERROR(AQPAYPAL_LOGDOMAIN, "No user id");
226 return GWEN_ERROR_INVALID;
227 }
228
229 pbuf=GWEN_Buffer_new(0, 256, 0, 1);
230 rv=AB_Provider_GetUserDataDir(pro, pbuf);
231 if (rv<0) {
232 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
233 GWEN_Buffer_free(pbuf);
234 return rv;
235 }
236
237 /* make sure the data dir exists */
238 DBG_INFO(0, "Looking for [%s]", GWEN_Buffer_GetStart(pbuf));
239 rv=GWEN_Directory_GetPath(GWEN_Buffer_GetStart(pbuf), 0);
240 if (rv<0) {
241 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
242 GWEN_Buffer_free(pbuf);
243 return rv;
244 }
245
246 GWEN_Buffer_AppendString(pbuf, GWEN_DIR_SEPARATOR_S);
247 GWEN_Text_UnescapeToBufferTolerant(uid, pbuf);
248 GWEN_Buffer_AppendString(pbuf, ".sec");
249
250 snprintf(text, sizeof(text)-1,
251 I18N("Please enter the password for \n"
252 "Paypal user %s\n"
253 "<html>"
254 "Please enter the password for Paypal user <i>%s</i></br>"
255 "</html>"),
256 uid, uid);
257 text[sizeof(text)-1]=0;
258
259 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
260 GWEN_Buffer_AppendString(tbuf, "PASSWORD_");
261 GWEN_Text_UnescapeToBufferTolerant(GWEN_Buffer_GetStart(pbuf), tbuf);
262
263 rv=GWEN_Gui_GetPassword(GWEN_GUI_INPUT_FLAGS_CONFIRM,
264 GWEN_Buffer_GetStart(tbuf),
265 I18N("Enter Password"),
266 text,
267 pw,
268 4,
269 sizeof(pw)-1,
270 GWEN_Gui_PasswordMethod_Text, NULL,
271 0);
272 if (rv<0) {
273 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
274 GWEN_Buffer_free(tbuf);
275 GWEN_Buffer_free(pbuf);
276 return rv;
277 }
278 GWEN_Buffer_free(tbuf);
279
280 sbuf=GWEN_Buffer_new(0, 256, 0, 1);
281 rv=GWEN_SmallTresor_Encrypt((const uint8_t *) sec,
282 strlen(sec),
283 pw,
284 sbuf,
285 AQPAYPAL_PASSWORD_ITERATIONS,
286 AQPAYPAL_CRYPT_ITERATIONS);
287 /* overwrite password ASAP */
288 memset(pw, 0, sizeof(pw));
289 if (rv<0) {
290 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
291 GWEN_Buffer_free(sbuf);
292 GWEN_Buffer_free(pbuf);
293 return rv;
294 }
295
296 /* write file */
297 rv=writeFile(GWEN_Buffer_GetStart(pbuf),
298 GWEN_Buffer_GetStart(sbuf),
299 GWEN_Buffer_GetUsedBytes(sbuf));
300 if (rv<0) {
301 DBG_INFO(AQPAYPAL_LOGDOMAIN, "here (%d)", rv);
302 GWEN_Buffer_free(sbuf);
303 GWEN_Buffer_free(pbuf);
304 return rv;
305 }
306
307 GWEN_Buffer_free(sbuf);
308 GWEN_Buffer_free(pbuf);
309
310 return 0;
311 }
312
313