...
|
...
|
@@ -296,6 +296,9 @@ static void pdfobj_flag(struct pdf_struct *pdf, struct pdf_obj *obj, enum pdf_fl
|
296
|
296
|
case MANY_FILTERS:
|
297
|
297
|
s = "more than 2 filters per obj";
|
298
|
298
|
break;
|
|
299
|
+ case DECRYPTABLE_PDF:
|
|
300
|
+ s = "decryptable PDF";
|
|
301
|
+ break;
|
299
|
302
|
}
|
300
|
303
|
cli_dbgmsg("cli_pdf: %s flagged in object %u %u\n", s, obj->id>>8, obj->id&0xff);
|
301
|
304
|
}
|
...
|
...
|
@@ -567,6 +570,8 @@ static int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
567
|
567
|
char *ascii_decoded = NULL;
|
568
|
568
|
int dump = 1;
|
569
|
569
|
|
|
570
|
+ cli_dbgmsg("pdf_extract_obj: obj %u %u\n", obj->id>>8, obj->id&0xff);
|
|
571
|
+
|
570
|
572
|
/* TODO: call bytecode hook here, allow override dumpability */
|
571
|
573
|
if ((!(obj->flags & (1 << OBJ_STREAM)) ||
|
572
|
574
|
(obj->flags & (1 << OBJ_HASFILTERS)))
|
...
|
...
|
@@ -585,7 +590,7 @@ static int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
585
|
585
|
}
|
586
|
586
|
if (!dump)
|
587
|
587
|
return CL_CLEAN;
|
588
|
|
- cli_dbgmsg("cli_pdf: dumping obj %u %u\n", obj->id>>8, obj->id);
|
|
588
|
+ cli_dbgmsg("cli_pdf: dumping obj %u %u\n", obj->id>>8, obj->id&0xff);
|
589
|
589
|
snprintf(fullname, sizeof(fullname), "%s"PATHSEP"pdf%02u", pdf->dir, pdf->files++);
|
590
|
590
|
fout = open(fullname,O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
|
591
|
591
|
if (fout < 0) {
|
...
|
...
|
@@ -907,6 +912,7 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
907
|
907
|
q2 = pdf_nextobject(q, bytesleft);
|
908
|
908
|
bytesleft -= q2 -q;
|
909
|
909
|
if (!q2 || bytesleft < 0) {
|
|
910
|
+ cli_dbgmsg("cli_pdf: %u %u obj: no dictionary\n", obj->id>>8, obj->id&0xff);
|
910
|
911
|
return;
|
911
|
912
|
}
|
912
|
913
|
q3 = memchr(q-1, '<', q2-q+1);
|
...
|
...
|
@@ -922,6 +928,7 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
|
922
|
922
|
q2 = pdf_nextobject(q, bytesleft);
|
923
|
923
|
bytesleft -= q2 -q;
|
924
|
924
|
if (!q2 || bytesleft < 0) {
|
|
925
|
+ cli_dbgmsg("cli_pdf: %u %u obj: broken dictionary\n", obj->id>>8, obj->id&0xff);
|
925
|
926
|
return;
|
926
|
927
|
}
|
927
|
928
|
q3 = memchr(q-1, '>', q2-q+1);
|
...
|
...
|
@@ -1262,7 +1269,7 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
|
1262
|
1262
|
password_empty = 1;
|
1263
|
1263
|
/* Algorithm 3.2a could be used to recover encryption key */
|
1264
|
1264
|
}
|
1265
|
|
- } else {
|
|
1265
|
+ } else if ((R >= 2) && (R <= 4)) {
|
1266
|
1266
|
/* 7.6.3.3 Algorithm 2 */
|
1267
|
1267
|
cli_md5_init(&md5);
|
1268
|
1268
|
/* empty password, password == padding */
|
...
|
...
|
@@ -1276,9 +1283,9 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
|
1276
|
1276
|
cli_md5_update(&md5, &v, 4);
|
1277
|
1277
|
}
|
1278
|
1278
|
cli_md5_final(result, &md5);
|
|
1279
|
+ if (length > 128)
|
|
1280
|
+ length = 128;
|
1279
|
1281
|
if (R >= 3) {
|
1280
|
|
- if (length > 128)
|
1281
|
|
- length = 128;
|
1282
|
1282
|
for (i=0;i<50;i++) {
|
1283
|
1283
|
cli_md5_init(&md5);
|
1284
|
1284
|
cli_md5_update(&md5, result, length/8);
|
...
|
...
|
@@ -1329,6 +1336,11 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
|
1329
|
1329
|
cli_dbgmsg("cli_pdf: invalid revision %d\n", R);
|
1330
|
1330
|
}
|
1331
|
1331
|
}
|
|
1332
|
+ else {
|
|
1333
|
+ /* Supported R is in {2,3,4,5} */
|
|
1334
|
+ cli_dbgmsg("cli_pdf: R value out of range\n");
|
|
1335
|
+ return;
|
|
1336
|
+ }
|
1332
|
1337
|
if (password_empty) {
|
1333
|
1338
|
cli_dbgmsg("cli_pdf: user password is empty\n");
|
1334
|
1339
|
/* The key we computed above is the key used to encrypt the streams.
|
...
|
...
|
@@ -1395,6 +1407,10 @@ static void pdf_handle_enc(struct pdf_struct *pdf)
|
1395
|
1395
|
cli_dbgmsg("cli_pdf: invalid R\n");
|
1396
|
1396
|
break;
|
1397
|
1397
|
}
|
|
1398
|
+ if ((R > 5) || (R < 2)) {
|
|
1399
|
+ cli_dbgmsg("cli_pdf: R value outside supported range [2..5]\n");
|
|
1400
|
+ break;
|
|
1401
|
+ }
|
1398
|
1402
|
|
1399
|
1403
|
if (R < 5)
|
1400
|
1404
|
oulen = 32;
|