modules/pa/gpg.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- ParseInputFile
- VerifySignature
- PA_VerifySignature
- PA_Decrypt
- PA_ImportKey
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/wait.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <time.h>
11
12 #include "gpg.h"
13
14 extern int sd1[2];
15 extern int spawn_job (char *path, char *argv[],
16 int *in_fd, int *out_fd, int *err_fd);
17 extern time_t nfslock(char *path, char *namelock, int max_age, int notify);
18 extern int nfsunlock(char *path, char *namelock, int max_age, time_t birth);
19
20 void ParseInputFile(struct VerifySignObject *vSO) {
/* [<][>][^][v][top][bottom][index][help] */
21 FILE *fin, *fout;
22 char txt[LINE_LENGTH];
23 char keyRing[LINE_LENGTH];
24 char outputPath[LINE_LENGTH];
25 const char PGP_prefix[] = "-----BEGIN PGP ";
26 const char PGP_suffix[] = "-----END PGP ";
27 int found_prefix = 0, nMsgs = 0, outFileOpened = 0, clearTextBlock = 1;
28 char foutName[100];
29 struct VerifySignObject *vSOList = vSO;
30
31 strcpy(keyRing, vSO->keyRing);
32 strcpy(outputPath, vSO->outputPath);
33
34 if (!strcmp(vSOList->iSigFilename, "")) {
35 if ((fin = fopen(vSOList->iDocSigFilename, "r")) != NULL) {
36
37 while (fgets (txt, LINE_LENGTH - 1, fin) != NULL) {
38
39 /* Looking for PGP prefix */
40 if ((strstr(txt, PGP_prefix) != NULL) && !found_prefix) {
41 clearTextBlock = 0;
42 found_prefix = 1;
43 /* remember to delete those files */
44 sprintf(foutName, "/tmp/PAtmp.%d.%d", (int)getpid(), nMsgs);
45 if ((fout = fopen(foutName, "w")) == NULL ) {
46 vSOList->isValid = vSO_NO_OUT_FILES;
47 return;
48 }
49 outFileOpened = 1;
50 vSOList->next = malloc(sizeof(struct VerifySignObject));
51 vSOList = vSOList->next;
52 strcpy(vSOList->iDocSigFilename, foutName);
53 strcpy(vSOList->keyRing, keyRing);
54 strcpy(vSOList->outputPath, outputPath);
55 vSOList->next = NULL;
56 } else
57 if ((strstr(txt, PGP_suffix) != NULL ) && found_prefix) {
58 found_prefix = 0;
59 clearTextBlock = 1;
60 fputs(txt, fout);
61 fclose(fout);
62 outFileOpened = 0;
63 nMsgs++;
64 } else
65 if (clearTextBlock && !outFileOpened) {
66 sprintf(foutName, "/tmp/PAtmp.%d.%d", (int)getpid(), nMsgs);
67 if ((fout = fopen(foutName, "w")) == NULL ) {
68 vSOList->isValid = vSO_NO_OUT_FILES;
69 return;
70 }
71 outFileOpened = 1;
72 vSOList->next = malloc(sizeof(struct VerifySignObject));
73 vSOList = vSOList->next;
74 strcpy(vSOList->iDocSigFilename, foutName);
75 strcpy(vSOList->keyRing, keyRing);
76 strcpy(vSOList->outputPath, outputPath);
77 vSOList->next = NULL;
78 }
79 if (outFileOpened) {
80 fputs(txt, fout);
81 }
82 }
83 if (outFileOpened) {
84 fclose(fout);
85 }
86 fclose(fin);
87 } else {
88 vSOList->isValid = vSO_NO_IN_FILES;
89 }
90 }
91 }
92
93 void VerifySignature(struct VerifySignObject *vSO) {
/* [<][>][^][v][top][bottom][index][help] */
94 char *strArgs[10];
95 char Args0[100];
96 char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100],
97 Args6[100], Args7[100];
98 int gpg_pid;
99 int gpg_in_fd, out_fd, err_fd;
100 int status;
101 static int nMsgs = 0;
102 char txt[LINE_LENGTH];
103 char *keyStr;
104 struct VerifySignObject *pvSO = vSO->next, *ptmp;
105
106 while (pvSO != NULL) {
107 nMsgs++;
108 /* Copy the incoming object on the internal global object */
109 /* memmove( &verifySignObj, pvSO, sizeof(struct VerifySignObject) ); */
110
111 sprintf(pvSO->oStream, "%s/PAtmp.%ld.%ld.%d", pvSO->outputPath,
112 labs(gethostid()), getpid(), nMsgs);
113
114 strcpy(Args0, "--no-secmem-warning");
115 strcpy(Args1, "--keyring");
116 strcpy(Args2, pvSO->keyRing);
117 strcpy(Args3, "-o");
118 strcpy(Args4, pvSO->oStream);
119 strcpy(Args5, "-d");
120 if (!strcmp(pvSO->iSigFilename, "")) {
121 strcpy(Args6, pvSO->iDocSigFilename);
122 strArgs[6] = Args6;
123 strArgs[7] = (char *)0;
124 } else {
125 strcpy(Args6, pvSO->iSigFilename);
126 strcpy(Args7, pvSO->iDocSigFilename);
127 strArgs[6] = Args6;
128 strArgs[7] = Args7;
129 strArgs[8] = (char *)0;
130 }
131
132 strArgs[0] = Args0;
133 strArgs[1] = Args1;
134 strArgs[2] = Args2;
135 strArgs[3] = Args3;
136 strArgs[4] = Args4;
137 strArgs[5] = Args5;
138
139 gpg_in_fd = INPUT_FD;
140 out_fd = OUTPUT_FD;
141 err_fd = ERROR_FD;
142 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
143 &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
144 {
145 printf ("could not spawn gpg");
146 }
147
148 if (waitpid (gpg_pid, &status, 0) < 0)
149 {
150 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
151 printf ("could not reap gpg process");
152 }
153 if (WIFEXITED(status) == 0)
154 {
155 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
156 printf ("gpg failure\n");
157 }
158
159
160 /* Parsing gpg output */
161 pvSO->isValid = vSO_KO;
162 while (fgets (txt, LINE_LENGTH - 1, stdin) != NULL)
163 {
164 /* printf ( "GPG output : %s\n", txt ); */
165 if (strstr(txt, "Good signature") != NULL)
166 pvSO->isValid = vSO_IS_VALID;
167
168 if (strstr(txt, "CRC error") != NULL)
169 pvSO->isValid = vSO_CRC_ERROR;
170
171 if (strstr(txt, "public key not found") != NULL)
172 pvSO->isValid = vSO_NO_PUBLIC_KEY;
173
174 if (strstr(txt, "no valid OpenPGP data found") != NULL)
175 pvSO->isValid = vSO_NO_OPENPGP_DATA;
176
177 if ((keyStr = strstr(txt, "key ID")) != NULL) {
178 keyStr += 7;
179 sscanf(keyStr, "%8X\n", &pvSO->keyID);
180 }
181 }
182
183 unlink(pvSO->iDocSigFilename);
184 pvSO = pvSO->next;
185 }
186 if (sd1[0] != 0) close ( sd1[0] );
187 }
188
189
190 /* ------------------------------------------------- */
191 void PA_VerifySignature(struct VerifySignObject *vSO) {
/* [<][>][^][v][top][bottom][index][help] */
192
193 /* split input file if there are multiple signed messages */
194 ParseInputFile( vSO );
195
196 /* Verify each single PGP mesg */
197 VerifySignature( vSO );
198
199 }
200
201 /* ------------------------------------------------- */
202 void PA_Decrypt(struct ReadCryptedObject *rDO) {
/* [<][>][^][v][top][bottom][index][help] */
203
204 char *strArgs[9];
205 char clearTextExtension[4] = ".gpg";
206 char Args0[100] = "abracadabra";
207 char Args1[100];
208 char Args2[100];
209 char Args3[100];
210 char Args4[100];
211 char Args5[100];
212 char Args6[100];
213 int gpg_pid;
214 int gpg_in_fd, out_fd, err_fd;
215 int status;
216 char txt[LINE_LENGTH];
217
218
219 strcpy(Args0, "--no-tty");
220 strcpy(Args1, "--no-secmem-warning");
221 strcpy(Args2, "--keyring");
222 strcpy(Args3, rDO->keyRing);
223 strcpy(Args4, "--output");
224 strcpy(Args5, strcat(rDO->iFilename, clearTextExtension));
225 strcpy(Args6, rDO->iFilename);
226
227 strArgs[0] = Args0;
228 strArgs[1] = Args1;
229 strArgs[2] = Args2;
230 strArgs[3] = Args3;
231 strArgs[4] = Args4;
232 strArgs[5] = Args5;
233 strArgs[6] = Args6;
234 strArgs[7] = (char *) 0;
235
236 gpg_in_fd = INPUT_FD;
237 out_fd = OUTPUT_FD;
238 err_fd = ERROR_FD;
239 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
240 &gpg_in_fd, &out_fd, &err_fd) ) < 0 )
241 {
242 printf ("could not spawn gpg");
243 }
244
245 if (waitpid (gpg_pid, &status, 0) < 0)
246 {
247 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
248 printf ("could not reap gpg process");
249 }
250 if (WIFEXITED(status) == 0)
251 {
252 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
253 printf ("gpg failure");
254 }
255
256
257 /* Parsing gpg output */
258 while (fgets (txt, STRING_LENGTH - 1, stdin) != NULL)
259 {
260
261 }
262
263 if (sd1[0] != 0) close ( sd1[0] );
264 }
265
266
267 /* ------------------------------------------------- */
268 void PA_ImportKey(struct ImportKeyObject *iKO) {
/* [<][>][^][v][top][bottom][index][help] */
269
270 char *strArgs[9];
271 char Args0[100] = "abracadabra";
272 char Args1[100], Args2[100], Args3[100], Args4[100], Args5[100];
273 int gpg_pid;
274 int gpg_in_fd, out_fd, err_fd;
275 int status;
276 char txt[LINE_LENGTH];
277 char *keyStr, *pos;
278 const char lockFilename[] = ".PAlock";
279 char keyRingLockFile[1000], keyRingPath[1000];
280 time_t lockBirthDate;
281 FILE *mystdin;
282
283 iKO->rc = iKO_GENERALFAILURE;
284
285 strcpy(Args0, "--no-tty");
286 strcpy(Args1, "--no-secmem-warning");
287 strcpy(Args2, "--keyring");
288 strcpy(Args3, iKO->keyRing);
289 strcpy(Args4, "--import");
290 strcpy(Args5, iKO->iFilename);
291
292 strArgs[0] = Args0;
293 strArgs[1] = Args1;
294 strArgs[2] = Args2;
295 strArgs[3] = Args3;
296 strArgs[4] = Args4;
297 strArgs[5] = Args5;
298 strArgs[6] = (char *)0;
299
300 gpg_in_fd = INPUT_FD;
301 out_fd = OUTPUT_FD;
302 err_fd = ERROR_FD;
303
304 /* create lock file filenames for NFS */
305
306 strcpy(keyRingLockFile, iKO->keyRing);
307 if ((pos = strrchr(keyRingLockFile, '/')) != NULL) {
308 strcpy(pos + 1, lockFilename);
309 strcpy(keyRingPath, keyRingLockFile);
310 keyRingPath[pos - keyRingLockFile] = 0;
311 } else {
312 strcpy(keyRingLockFile, lockFilename);
313 strcpy(keyRingPath, "");
314 }
315
316 lockBirthDate = nfslock(keyRingPath, (char*)lockFilename, 0, 0);
317
318 if ( ( gpg_pid = spawn_job ("gpg", strArgs,
319 &gpg_in_fd, &out_fd, &err_fd) ) < 0 ) {
320 printf ("could not spawn gpg");
321 }
322
323 if (waitpid (gpg_pid, &status, 0) < 0)
324 {
325 fprintf (stderr, "Error reaping child\t%s\n", ERRSTRING);
326 printf ("could not reap gpg process");
327 }
328
329 nfsunlock(keyRingPath, (char*)lockFilename, 0, lockBirthDate);
330
331 if (WIFEXITED(status) == 0)
332 {
333 fprintf (stderr, "Bad child status: %d\t%s\n", status, ERRSTRING);
334 printf ("gpg failure");
335 }
336
337
338 /* Parsing gpg output */
339 /* while (read(0, txt, 1000) != 0)
340 fprintf(stderr, "child read %s\n", txt); */
341
342 mystdin = fdopen(0, "r");
343 iKO->rc = iKO_GENERALFAILURE;
344 while (fgets (txt, LINE_LENGTH - 1, mystdin) != NULL)
345 {
346 printf ( "GPG output : %s\n", txt );
347
348 if ((keyStr = strstr(txt, "imported")) != NULL) {
349 iKO->rc = iKO_OK;
350 }
351
352 if ((keyStr = strstr(txt, "CRC error")) != NULL) {
353 iKO->rc = iKO_CRC_ERROR;
354 }
355
356 if ((keyStr = strstr(txt, "no valid OpenPGP")) != NULL) {
357 iKO->rc = iKO_NO_OPENPGP_DATA;
358 }
359
360 if ((keyStr = strstr(txt, "unchanged")) != NULL) {
361 iKO->rc = iKO_UNCHANGED;
362 }
363
364 if ((keyStr = strstr(txt, "key")) != NULL) {
365 keyStr += 4;
366 sscanf(keyStr, "%8X\n", &iKO->keyID);
367 }
368 }
369
370 if (sd1[0] != 0) close ( sd1[0] );
371 }
372
373