Introduced checksum tag for relocated 64 kB superblock on overwriteable media.

This commit is contained in:
2009-08-17 17:22:31 +02:00
parent 07a67a59e7
commit 868005ed0e
6 changed files with 172 additions and 48 deletions

View File

@ -1097,6 +1097,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->checksum_idx_counter = 0;
target->checksum_ctx = NULL;
target->checksum_counter = 0;
target->checksum_rlsb_tag_pos = 0;
target->checksum_sb_tag_pos = 0;
target->checksum_tree_tag_pos = 0;
target->checksum_tag_pos = 0;
@ -1104,6 +1105,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->checksum_array_pos = 0;
target->checksum_range_start = 0;
target->checksum_range_size = 0;
target->opts_overwrite = 0;
#endif
@ -1265,7 +1267,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
/* check if we need to provide a copy of volume descriptors */
if (opts->overwrite) {
/*
* Get a copy of the volume descriptors to be written in a DVD+RW
* disc
@ -1318,6 +1319,28 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
vol->vol_desc_type[0] = 255;
memcpy(vol->std_identifier, "CD001", 5);
vol->vol_desc_version[0] = 1;
#ifdef Libisofs_with_checksumS
/* Write relocated superblock checksum tag */
if (target->md5_session_checksum) {
target->checksum_rlsb_tag_pos = voldesc_size / BLOCK_SIZE + 16 + 1;
if (target->checksum_rlsb_tag_pos < 32) {
ret = iso_md5_start(&(target->checksum_ctx));
if (ret < 0)
return ret;
target->opts_overwrite = (char *) opts->overwrite;
iso_md5_compute(target->checksum_ctx, target->opts_overwrite,
target->checksum_rlsb_tag_pos * 2048);
ret = iso_md5_write_tag(target, 4);
target->opts_overwrite = NULL; /* opts might not persist */
if (ret < 0)
goto target_cleanup;
}
}
#endif /* Libisofs_with_checksumS */
}
/*
@ -1333,6 +1356,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
#ifdef Libisofs_with_checksumS
if (target->md5_session_checksum) {
/* After any fake writes are done: Initialize image checksum context */
if (target->checksum_ctx != NULL)
iso_md5_end(&(target->checksum_ctx), target->image_md5);
ret = iso_md5_start(&(target->checksum_ctx));
if (ret < 0)
return ret;

View File

@ -454,6 +454,7 @@ struct ecma119_image
unsigned int checksum_idx_counter;
void *checksum_ctx;
off_t checksum_counter;
uint32_t checksum_rlsb_tag_pos;
uint32_t checksum_sb_tag_pos;
uint32_t checksum_tree_tag_pos;
uint32_t checksum_tag_pos;
@ -463,6 +464,15 @@ struct ecma119_image
uint32_t checksum_range_start;
uint32_t checksum_range_size;
char *opts_overwrite; /* Points to IsoWriteOpts->overwrite.
Use only underneath ecma119_image_new()
and if not NULL*/
/* ??? Is there a reason why we copy lots of items from IsoWriteOpts
rather than taking ownership of the IsoWriteOpts object which
is submitted with ecma119_image_new() ?
*/
#endif /* Libisofs_with_checksumS */
/* Buffer for communication between burn_source and writer thread */

View File

@ -5057,6 +5057,7 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
* 1= session tag
* 2= superblock tag
* 3= tree tag
* 4= relocated 64 kB superblock tag (at LBA 0 of overwriteable media)
* @param pos
* Returns the LBA where the tag supposes itself to be stored.
* If this does not match the data block LBA then the tag might be
@ -5071,7 +5072,13 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
* covered by parameter md5.
* @param next_tag
* Returns the predicted block address of the next tag.
* Valid only with return values 2 and 3 and if not 0.
* next_tag is valid only if not 0 and only with return values 2, 3, 4.
* With tag types 2 and 3, reading shall go on sequentially and the MD5
* computation shall continue up to that address.
* With tag type 4, reading shall resume either at LBA 32 for the first
* session or at the given address for the session which is to be loaded
* by default. In both cases the MD5 computation shall be re-started from
* scratch.
* @param md5
* Returns 16 byte of MD5 checksum.
* @param flag
@ -5081,12 +5088,13 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
* 1= session tag
* 2= superblock tag
* 3= tree tag
* 4= relocated superblock tag
* @return
* 0= not a checksum tag, return parameters are invalid
* 1= checksum tag found, return parameters arevalid
* 1= checksum tag found, return parameters are valid
* <0= error
* return parameters are valid with error ISO_MD5_AREA_CORRUPTED
* but not trustworthy because the tag seems corrupted.
* (return parameters are valid with error ISO_MD5_AREA_CORRUPTED
* but not trustworthy because the tag seems corrupted)
*
* @since 0.6.22
*/

View File

@ -659,6 +659,8 @@ int checksum_writer_create(Ecma119Image *target)
* 1= session tag (End checksumming.)
* 2= superblock tag (System Area and Volume Descriptors)
* 3= tree tag (ECMA-119 and Rock Ridge tree)
* 4= relocated superblock tag (at LBA 0 of overwriteable media)
* Write to target->opts_overwrite rather than to iso_write().
*/
int iso_md5_write_tag(Ecma119Image *t, int flag)
{
@ -668,27 +670,30 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
int res, mode, l, i, wres;
void *ctx = NULL;
char md5[16], tag_block[2048];
uint32_t size= 0, pos, next_pos = 0;
static char *tag_ids[4]= {"",
uint32_t size = 0, pos = 0, start;
static char *tag_ids[] = {"",
"libisofs_checksum_tag_v1",
"libisofs_sb_checksum_tag_v1",
"libisofs_tree_checksum_tag_v1"};
"libisofs_tree_checksum_tag_v1",
"libisofs_rlsb32_checksum_tag_v1"};
start = t->checksum_range_start;
memset(tag_block, 0, 2048);
mode = flag & 255;
if (mode == 1) {
res = iso_md5_end(&(t->checksum_ctx), md5);
size = t->checksum_range_size;
pos = t->checksum_tag_pos;
} else if (mode == 2 || mode == 3) {
} else if (mode >= 2 && mode <= 4) {
if (mode == 2) {
pos = t->checksum_sb_tag_pos;
next_pos = t->checksum_tree_tag_pos;
} else {
} else if (mode == 3) {
pos = t->checksum_tree_tag_pos;
next_pos = t->checksum_tag_pos;
} else if (mode == 4) {
pos = t->checksum_rlsb_tag_pos;
start = pos - (pos % 32);
}
size = pos - t->checksum_range_start;
size = pos - start;
res = iso_md5_clone(t->checksum_ctx, &ctx);
if (res < 0)
return res;
@ -699,13 +704,15 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
if (res > 0) {
sprintf(tag_block,
"%s pos=%u range_start=%u range_size=%u",
tag_ids[mode], pos,
t->checksum_range_start, size);
tag_ids[mode], pos, start, size);
l = strlen(tag_block);
if (mode == 2) {
sprintf(tag_block + l, " next=%u", t->checksum_tree_tag_pos);
} else if (mode == 3) {
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
} else if (mode == 4) {
sprintf(tag_block + l, " session_start=%u", t->ms_block);
}
strcat(tag_block + l, " md5=");
l = strlen(tag_block);
@ -726,10 +733,15 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
}
tag_block[l + 32] = '\n';
}
wres = iso_write(t, tag_block, 2048);
if (wres < 0) {
res = wres;
goto ex;
if (mode == 4) {
if (t->opts_overwrite != NULL)
memcpy(t->opts_overwrite + pos * 2048, tag_block, 2048);
} else {
wres = iso_write(t, tag_block, 2048);
if (wres < 0) {
res = wres;
goto ex;
}
}
res = ISO_SUCCESS;
ex:;

View File

@ -1567,12 +1567,13 @@ int iso_util_decode_md5_tag(char data[2048], int *tag_type, uint32_t *pos,
uint32_t *range_start, uint32_t *range_size,
uint32_t *next_tag, char md5[16], int flag)
{
static char *tag_magic[4] = {"",
"libisofs_checksum_tag_v1",
"libisofs_sb_checksum_tag_v1",
"libisofs_tree_checksum_tag_v1"};
static int magic_len[4]= {0, 24, 27, 29};
int ret, bin_count, i, mode, magic_first = 1, magic_last = 3, found = 0;
static char *tag_magic[] = {"",
"libisofs_checksum_tag_v1",
"libisofs_sb_checksum_tag_v1",
"libisofs_tree_checksum_tag_v1",
"libisofs_rlsb32_checksum_tag_v1"};
static int magic_len[]= {0, 24, 27, 29, 31};
int ret, bin_count, i, mode, magic_first = 1, magic_last = 4;
char *cpt, self_md5[16], tag_md5[16];
void *ctx = NULL;
@ -1614,6 +1615,13 @@ int iso_util_decode_md5_tag(char data[2048], int *tag_type, uint32_t *pos,
ret = iso_util_dec_to_uint32(cpt + 5, next_tag, 0);
if (ret <= 0)
return 0;
} else if (*tag_type == 4) {
cpt = strstr(cpt, "session_start=");
if (cpt == NULL)
return(0);
ret = iso_util_dec_to_uint32(cpt + 14, next_tag, 0);
if (ret <= 0)
return 0;
}
cpt = strstr(cpt, "md5=");
if (cpt == NULL)