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) {
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) {
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) {
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) {
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) {
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 |