-
Notifications
You must be signed in to change notification settings - Fork 749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update RAR5 code to report encryption #2096
base: master
Are you sure you want to change the base?
Changes from 4 commits
c1f02ae
fa5408e
6d2511e
4f6513f
34ae0d4
cf73ac0
968471d
8dce364
81717b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -352,6 +352,11 @@ struct rar5 { | |
/* The header of currently processed RARv5 block. Used in main | ||
* decompression logic loop. */ | ||
struct compressed_block_header last_block_hdr; | ||
|
||
/* | ||
* Custom field to denote that this archive contains encrypted entries | ||
*/ | ||
int has_encrypted_entries; | ||
}; | ||
|
||
/* Forward function declarations. */ | ||
|
@@ -1590,6 +1595,7 @@ static int process_head_file_extra(struct archive_read* a, | |
if(!read_var_sized(a, &extra_field_id, &var_size)) | ||
return ARCHIVE_EOF; | ||
|
||
extra_field_size -= var_size; | ||
extra_data_size -= var_size; | ||
if(ARCHIVE_OK != consume(a, var_size)) { | ||
return ARCHIVE_EOF; | ||
|
@@ -1617,12 +1623,18 @@ static int process_head_file_extra(struct archive_read* a, | |
&extra_data_size); | ||
break; | ||
case EX_CRYPT: | ||
/* Mark the entry as encrypted */ | ||
archive_entry_set_is_data_encrypted(e, 1); | ||
rar->has_encrypted_entries = 1; | ||
/* fallthrough */ | ||
case EX_SUBDATA: | ||
/* fallthrough */ | ||
default: | ||
/* Skip unsupported entry. */ | ||
return consume(a, extra_data_size); | ||
extra_data_size -= extra_field_size; | ||
if (ARCHIVE_OK != consume(a, extra_field_size)) { | ||
return ARCHIVE_EOF; | ||
} | ||
} | ||
} | ||
|
||
|
@@ -2266,6 +2278,9 @@ static int process_base_block(struct archive_read* a, | |
ret = process_head_file(a, rar, entry, header_flags); | ||
return ret; | ||
case HEAD_CRYPT: | ||
archive_entry_set_is_metadata_encrypted(entry, 1); | ||
archive_entry_set_is_data_encrypted(entry, 1); | ||
rar->has_encrypted_entries = 1; | ||
archive_set_error(&a->archive, | ||
ARCHIVE_ERRNO_FILE_FORMAT, | ||
"Encryption is not supported"); | ||
|
@@ -2410,6 +2425,14 @@ static int rar5_read_header(struct archive_read *a, | |
struct rar5* rar = get_context(a); | ||
int ret; | ||
|
||
/* | ||
* It should be sufficient to call archive_read_next_header() for | ||
* a reader to determine if an entry is encrypted or not. | ||
*/ | ||
if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { | ||
rar->has_encrypted_entries = 0; | ||
} | ||
Comment on lines
+2448
to
+2450
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is something I didn't necessarily like doing, but I copied from other places. Encryption might not necessarily be detected when reading the first header (e.g. if the Nth entry is the first encrypted one), however there's not much difference in practice between perpetually returning |
||
|
||
if(rar->header_initialized == 0) { | ||
init_header(a); | ||
if ((ret = try_skip_sfx(a)) < ARCHIVE_WARN) | ||
|
@@ -4059,6 +4082,10 @@ static int rar5_read_data(struct archive_read *a, const void **buff, | |
if (size) | ||
*size = 0; | ||
|
||
if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { | ||
rar->has_encrypted_entries = 0; | ||
} | ||
dunhor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if(rar->file.dir > 0) { | ||
/* Don't process any data if this file entry was declared | ||
* as a directory. This is needed, because entries marked as | ||
|
@@ -4110,11 +4137,14 @@ static int rar5_read_data(struct archive_read *a, const void **buff, | |
static int rar5_read_data_skip(struct archive_read *a) { | ||
struct rar5* rar = get_context(a); | ||
|
||
if(rar->main.solid) { | ||
if(rar->main.solid && (rar->has_encrypted_entries <= 0)) { | ||
/* In solid archives, instead of skipping the data, we need to | ||
* extract it, and dispose the result. The side effect of this | ||
* operation will be setting up the initial window buffer state | ||
* needed to be able to extract the selected file. */ | ||
* needed to be able to extract the selected file. Note that | ||
* this is only possible when no entries are encrypted. If any | ||
* entries are encrypted, then we need to just skip the data; | ||
* we'll fail any later attempts to read data from the archive. */ | ||
|
||
int ret; | ||
|
||
|
@@ -4189,14 +4219,19 @@ static int rar5_cleanup(struct archive_read *a) { | |
|
||
static int rar5_capabilities(struct archive_read * a) { | ||
(void) a; | ||
return 0; | ||
return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | ||
| ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA); | ||
} | ||
|
||
static int rar5_has_encrypted_entries(struct archive_read *_a) { | ||
(void) _a; | ||
if (_a && _a->format) { | ||
struct rar5 *rar = (struct rar5 *)_a->format->data; | ||
if (rar) { | ||
return rar->has_encrypted_entries; | ||
} | ||
} | ||
|
||
/* Unsupported for now. */ | ||
return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED; | ||
return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; | ||
} | ||
|
||
static int rar5_init(struct rar5* rar) { | ||
|
@@ -4205,6 +4240,12 @@ static int rar5_init(struct rar5* rar) { | |
if(CDE_OK != cdeque_init(&rar->cstate.filters, 8192)) | ||
return ARCHIVE_FATAL; | ||
|
||
/* | ||
* Until enough data has been read, we cannot tell about | ||
* any encrypted entries yet. | ||
*/ | ||
rar->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; | ||
|
||
return ARCHIVE_OK; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
begin 0744 test_read_format_rar4_encrypted.rar | ||
M4F%R(1H'`,^0<P``#0`````````J8W0@D"H`$@```!(````"56Y:[F17=E@= | ||
M,`4`(````&$N='AT`/#\3!M4:&ES(&ES(&9R;VT@82YT>'1?CG0DE#(`(``` | ||
M`!(````"A13ZJ6=7=E@=,P4`(````&(N='ATO@(;FGDJBE4`L'*@-,GY]@T0 | ||
M?ZC1UGSKU*2VR-1K@HH>GZZP#?C:ML=$"NKDN\=T()`J`!(````2`````C4] | ||
MFI1N5W98'3`%`"````!C+G1X=`"P/D@M5&AI<R!I<R!F<F]M(&,N='AT[<IT | ||
M))0R`"`````2`````B7ANB9-9'98'3,%`"````!D+G1X=*_B?1/SI5-2`/#[ | ||
I88]V^#_)1V@;4"TVC,!XR=.I1:KVB0/<OAC@C&97VP3UZ<0]>P!`!P`` | ||
` | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
begin 0744 test_read_format_rar4_encrypted_filenames.rar | ||
M4F%R(1H'`,Z9<X``#0```````````````````'0+AC,H,+6'0#)>8VT<XO:* | ||
M5M'"E1[V+ZKT=VW!$Y2=W$,@Y24Z^"L_;GVG\*4]&"6BQ#?@6TX38EQ\8\4- | ||
M<S5U7JMAF.'L3LOOCM6]\Q60C51S.)^'6MOG_R<DW8EG(```````````(B,( | ||
M]O5[61NCM'\Q9[&<E5D6F6`?WI`#-.(]J?W^C9!U-5O^2='P+5K(ED[:I4T= | ||
M0/ZHVQ[F8HPBZ<+WA.*T5<R$K+8&/OR_\BN8V5VVM]"5F:$4Y:\JR,),%],1 | ||
MR;Z>``````````#*B0$)1EIB[[O98],X0DT>H`N+&*.NNPK!]1XJ#(AF_TF6 | ||
M0FE3!L0.1T+=I<'X[Z0:F23U_[6S.I:ZNQ.\@HZ\]&0L/P:SA$:,Y<^4.A!\ | ||
MSBD7NK5[VE/9$9K/N2`[7]T``````````.\$Z3?>_Z.3*>6<12%741?6_./A | ||
M!:XA!P"B0PS55>+%J)-H$0T!//>$']'-U?_"O=N?_:SNE<^54Z3/[8,M^F?6 | ||
M36)XOUNLS4@\\N@1J#Z/V?J<_XS>CNA21,<Q;<;C[@``````````\)]%=^L\ | ||
*)-I(DJO^>177HP`` | ||
` | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
begin 0744 test_read_format_rar4_solid_encrypted.dat | ||
M4F%R(1H'`#O0<P@`#0`````````A873$E#(`,````!(````"56Y:[F17=E@= | ||
M,P4`(````&$N='AT````````````\/Q,&]Q,RV`3V)H10_&#G@'FZ'@$+I%W | ||
MXP?A#XMQ>A-D/\9QH!R+,]AV(8F*MQD3.<V`SC96=-24,@`0````$@````*% | ||
M%/JI9U=V6!TS!0`@````8BYT>'2/%M7(05"L]0"P<J`TBK7M!JH)_:_8K\\K | ||
M,U_X>\,C=-24,@`0````$@````(U/9J4;E=V6!TS!0`@````8RYT>'1ILB:< | ||
M@2)@M@"P/D@MD'UA]R2N^_G@1!L-H?V>K-TV=-24,@`0````$@````(EX;HF | ||
M361V6!TS!0`@````9"YT>'2C+AKDKML%S0#P^V&/?J,L#@>!52=M.=PPCAJF | ||
(IL0]>P!`!P`` | ||
` | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
begin 0744 test_read_format_rar4_solid_encrypted_filenames.rar | ||
M4F%R(1H'`#K9<X@`#0```````````````````,L":IWIGA+/YV2@]#O3Z\&O | ||
MM'G1)=DT/G2[DW184@7Z`)NZR=<IA_-5+=&`P_B)U/,]<+8]C:YI<X@;OT`3 | ||
M]?.U#K0BV:I"0AYHE-->?V[74Q\@?])NR\68105J4BRL3O.E$I*!91X?$@/< | ||
M5C[G2D$``````````!NS=YISD[7`_=#)$A.9/&9<3`&D$(L]$^-&%;!SH,%> | ||
M!NZ:W\)5XCJI<"H7+BND(033Q/J9/18(=/`A%WI]@(`:H>AE`M3T)R8']S%P | ||
MHYCV```````````&TB\_##3K6#@Q+J)RDEJ0$CI"]*R1)8!Q.3B[,7O5NM,] | ||
ME::7;E__N2:-%4-;/D+DA:J@P.L0*I/__*OX77=\L4-&F^""&L'VP9/DK-;$ | ||
MLP``````````1D.3Y0+"D$@9F(IYV&*B<`A2J2$)(C=_X_QEMWE*VK9ITH*U | ||
MAJ@<<Z%4#?(I"H:5J08&7^WM`<#3=A9D#':;X2IVK.%[ZZ#58(4W0Q[RT-X` | ||
7`````````/"?17?K/"3:2)*K_GD5UZ,` | ||
` | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
begin 0744 test_read_format_rar5_encrypted.rar | ||
M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@``U_S(>'P(#"Q($$B!5;EKN@```!6$N | ||
M='AT"@,"?"&$HX)\V@%4:&ES(&ES(&9R;VT@82YT>'1Z07&S4`(#/#`$$B`8 | ||
M1:,"@`,`!6(N='AT,`$``P_'1%[A@/BUG]8K0S<(O%?-^C3?!JM=!=23!W</ | ||
M'8Z`4^HU9QUP\2U+:YP:G`H#`G)EF*:"?-H!8[I4LM`0I4E?M+K3P&FH.QN\ | ||
MNS@GUX>3>',O?)/BTBC$`-[^IL`[?FQGU`50`-SXC7SQ9A\"`PL2!!(@-3V: | ||
ME(````5C+G1X=`H#`CY(Z:Z"?-H!5&AI<R!I<R!F<F]M(&,N='AT[/WP75(" | ||
M`SR@``22`"##WV,2@`,`!60N='AT,`$``P_'1%[A@/BUG]8K0S<(O%?-\\W6 | ||
MLQRT6Z=\K#98CK,.:8-,U$CI%>O6K'>WHPH#`GO%*?2/?-H!VVER]/96CJ;] | ||
?&67IE;,VA30W]2J@TR>'LO7!`C+8JEX==U91`P4$```` | ||
` | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
begin 0744 test_read_format_rar5_encrypted_filenames.rar | ||
M4F%R(1H'`0"N(]*0(00```$/:`NPT*?(O:'>=*=Q,C2;&;<*@A@[)[D`X\II | ||
M)1#LA,>A'D8M?0XU3L36UDKMZ3EWQ[HCXZ3<%!O*=.Y,W/S<QCA?O/:*,^Z5 | ||
M=M6S3*Y6;+35C`9`*4W]<':72F3'&:K>,FBUJV)T^1MW,X0)C4P7W(`"$#-N | ||
MQ\V%/Z&YJ=4A7#WA+9.5'__1CF)4F:?SV[[N1U^16P.+TQ5X.'"@NQ"=6K3Z | ||
M>:;.1CVE<%%M1-OQ3L0FZ[KI2TSW`.2SF20<ZT/,=/(WK4+9"\+J&$')_3V, | ||
MFW%?=^[MI.6[JA/>0V5WTB3-QIV<3Q'?++X$0]?XV(?ER,71CAXBNL1KT5A* | ||
M8*&+T@6]A_)*KA]%V3S,0B;S(LW1V.AH.U6U0N\-%!@J9Q-FJ%^'O)(JR5+2 | ||
MS$5JO/XA3W4MSJ[R27%P_4$GAWSW!SS(4IA_-)Z:[:?V5D!F@TGG9L0!1TF[ | ||
M:AH<9G0.['%7-\:>"&(8Y#Z#62;U.:,3+=<$E6S8C02I[/<OZ>G>-3P1Y<'J | ||
MW_FJ/]VJ-Q7IA64<?`;GTW<H]@=YS0)S*\?SKXQ$H.Y!<ZK`[1[?Z(\(_\]> | ||
MU:_TK/EHMM;PWJ?3`Y9S6&%6L@T0-U<&4E[+_F>Z%+KFW'&W>`,.=]#SI;A[ | ||
MYA);NM6`5K01J]@IT6O8W#!].A$%_5M\E]S0&<D`"T,:H7>.TOPBCL9$C"GU | ||
M2<W)Q\9ABJLH57<$#;&%<^N#-N[5KE?`56,WSHG<GU4!!.+@ZU+5N\;J[7J- | ||
M**R#V\19<I;O[I%?-002U,8R$.^M/P8W]?26N+VB5-\B#7;SV;_L#%4PQ36P | ||
MBTTF>G&8E))@.H01Q:@1Q^.YVYIG(?#2:S604D\'CWU.!:-E`=;4VFS+KULL | ||
KJ<2G@G$-MF5V72TYY!]U(UB473O?`U'=W'#D\4A%S-_F?/@]S)MU>.[V1``` | ||
` | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
begin 0744 test_read_format_rar5_solid_encrypted.rar | ||
M4F%R(1H'`0`@MOH1"@$%!@0%`0&`@`!A#\6>4@(#/+``!)(`(%5N6NZ`0P`% | ||
M82YT>'0P`0`!#X`.^EM!19`,=C!0B-G+#?0([51UI],+OH^T\:=V\5`OX@\X | ||
M+B?>=W@0'[TD"@,"?"&$HX)\V@$UI92M^>J?V-L?2@`2L023@_#?H\C>K?GG | ||
MDT*27O`>\]$\(4^12SZAD2GI6I(?@NS\ETUG4@(#/)``!)(`(#W[M6/`0P`% | ||
M8BYT>'0P`0`##X`.^EM!19`,=C!0B-G+#?09'G;UMT5!4+;8`6WM=*[?X@\X | ||
M+B?>=W@0'[TD"@,"<F68IH)\V@$C,XZR45`RX*-59&X3Y'+)'7P<"E("`SR0 | ||
M``22`"#_)YR&P$,`!6,N='AT,`$``P^`#OI;0460#'8P4(C9RPWT6V3<1-F, | ||
M1I0"0-:R/5=BUN(/."XGWG=X$!^])`H#`CY(Z:Z"?-H!BBA?J'.;?7%L12A& | ||
M0%6=`D>/[#]2`@,\D``$D@`@>Q=TP\!#``5D+G1X=#`!``,/@`[Z6T%%D`QV | ||
M,%"(V<L-]&ES:(+U/SMVI#;?U9:@A&OB#S@N)]YW>!`?O20*`P)[Q2GTCWS: | ||
9`3G@<$3$LKSYCC7DX.K9`[`==U91`P4$```` | ||
` | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
begin 0744 test_read_format_rar5_solid_encrypted_filenames.rar | ||
M4F%R(1H'`0";0=T:(00```$/AC5`PSS2$L"IUF$&I":C])K[3<7Y3A09X<`H | ||
M`7''7U?%(MHPZ3W;#Z7PZEC<2`T4N9L0A@JE?=;1"4#J%N#6H+4KYITU<*=Q | ||
MG$W?R7^W[#&LN^@M8(VSG.,@!1JFX359D^5#S[,ZW]V]CJ'J?-Z!KX^]Y1FB | ||
M8I%5/(^2-8V^KY:K1^?K`DVW*MUL>Q9_6`W#,2ST:17"'W'YF2?)NH%5V"_F | ||
M7;[0VI^.\JJ-T,_(\\5#ZX1HVQJ7KU0UCF#FGD-?NRMKA;X<,[/[*94^27X, | ||
M#)I<:BO^_-I%B&A1U>S)9__""\/M>Q5AIY'*]EPTNJW+.J57[$X\U:;W">Z; | ||
M8P\Z0[ZQOI*B*?BJ?B5+(/Z4.4AJ@;()1YUV4+XY#!76WZV]LZ+;GZ_Q#LLP | ||
MP`7??+NV**I(A-9N^7HX\V!+YJ3%;R<PA5#T<.1"/TKRXC6SM=>%MD?Q5&H@ | ||
M>$VAME3"U$312+@SF+8F2RR0)T"DG^4N,^P46&+TZKQ7KS`4@-:J%_["UP"( | ||
MK=]N^!UJUO2#6Q*`-`-)^?\/`;^4(@FVLVJ?!D,:O)A6@!TNA%.U^"0-?9H< | ||
M:0&(UWV=+&[82L>'L4XYO20"@)^<WC4/BKMBFP0G&/3,!*[Y+,F),*X7V7]H | ||
M3&`4SIL,>I']_<2C]D;_,]/)_1?N1+M@PTDL;'[J1L=5\,-?J5Q`$3>_9<2< | ||
MS^)#MZ*AE=5@5[O(<]*(EIA62$U`5B18?#W;BB.*0A3O%<OI.7X`?QB-FRV] | ||
M89*8RNH'P\"9I,0X&F;$<0Z70E(,^KF&PZ5WR-O%K;G`"/=E<\4-*H%FZ]O3 | ||
8G%A)/>[(IVC3ME2PY5F>9$/U'$VW1-BZ | ||
` | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't actually encounter any errors specific to this code-path, however it made me felt uneasy - e.g. skipping an earlier unsupported field may cause us to skip identifying an encryption field.