static void aff_close(TSK_IMG_INFO * img_info) { IMG_AFF_INFO *aff_info = (IMG_AFF_INFO *) img_info; af_close(aff_info->af_file); tsk_img_free(aff_info); }
static void ewf_image_close(TSK_IMG_INFO * img_info) { int i; IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *) img_info; #if defined ( HAVE_LIBEWF_V2_API) libewf_handle_close(ewf_info->handle, NULL); libewf_handle_free(&(ewf_info->handle), NULL); #else libewf_close(ewf_info->handle); #endif // this stuff crashes if we used glob. v2 of the API has a free method. // not clear from the docs what we should do in v1... // @@@ Probably a memory leak in v1 unless libewf_close deals with it if (ewf_info->used_ewf_glob == 0) { for (i = 0; i < ewf_info->num_imgs; i++) { free(ewf_info->images[i]); } free(ewf_info->images); } else { libewf_error_t *error; libewf_glob_free( ewf_info->images, ewf_info->num_imgs, &error); } tsk_deinit_lock(&(ewf_info->read_lock)); tsk_img_free(img_info); }
/** * \internal * Free the memory and close the file handles for the disk image * * @param img_info Disk image to close */ static void raw_close(TSK_IMG_INFO * img_info) { IMG_RAW_INFO *raw_info = (IMG_RAW_INFO *) img_info; int i; for (i = 0; i < SPLIT_CACHE; i++) { if (raw_info->cache[i].fd != 0) #ifdef TSK_WIN32 CloseHandle(raw_info->cache[i].fd); #else close(raw_info->cache[i].fd); #endif } for (i = 0; i < raw_info->num_img; i++) { if (raw_info->images[i]) free(raw_info->images[i]); } if (raw_info->max_off) free(raw_info->max_off); if (raw_info->images) free(raw_info->images); if (raw_info->cptr) free(raw_info->cptr); tsk_img_free(raw_info); }
static void raw_close(TSK_IMG_INFO * img_info) { IMG_RAW_INFO *raw_info = (IMG_RAW_INFO *) img_info; #ifdef TSK_WIN32 CloseHandle(raw_info->fd); #else close(raw_info->fd); #endif tsk_img_free(raw_info); }
TSK_IMG_INFO * aff_open(const TSK_TCHAR * const images[], unsigned int a_ssize) { IMG_AFF_INFO *aff_info; TSK_IMG_INFO *img_info; int type; char *image; #ifdef TSK_WIN32 // convert wchar_t* image path to char* to conform to // the AFFLIB API UTF16 *utf16 = (UTF16 *)images[0]; size_t ilen = wcslen(utf16); size_t olen = ilen*4 + 1; UTF8 *utf8 = (UTF8 *) tsk_malloc(olen); image = (char *) utf8; if ( image == NULL ) return NULL; TSKConversionResult retval = tsk_UTF16toUTF8_lclorder( (const UTF16 **) &utf16, &utf16[ilen], &utf8, &utf8[olen], TSKlenientConversion ); *utf8 = '\0'; if (retval != TSKconversionOK) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNICODE); tsk_error_set_errstr("aff_open file: %" PRIttocTSK ": Error converting path to UTF-8 %d\n", images[0], retval); free(image); return NULL; } utf8 = (UTF8 *) image; while ( *utf8 ) { if ( *utf8 > 127 ) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNICODE); tsk_error_set_errstr("aff_open file: %" PRIttocTSK ": Non-Latin paths are not supported for AFF images\n", images[0]); free(image); return NULL; } utf8++; } #else image = (char *) tsk_malloc( strlen(images[0])+1 ); if ( image == NULL ) return NULL; strncpy(image, images[0], strlen(images[0])+1 ); #endif if ((aff_info = (IMG_AFF_INFO *) tsk_img_malloc(sizeof(IMG_AFF_INFO))) == NULL) { free(image); return NULL; } img_info = (TSK_IMG_INFO *) aff_info; img_info->read = aff_read; img_info->close = aff_close; img_info->imgstat = aff_imgstat; img_info->sector_size = 512; if (a_ssize) img_info->sector_size = a_ssize; type = af_identify_file_type(image, 1); if ((type == AF_IDENTIFY_ERR) || (type == AF_IDENTIFY_NOEXIST)) { if (tsk_verbose) { tsk_fprintf(stderr, "aff_open: Error determining type of file: %" PRIttocTSK "\n", images[0]); perror("aff_open"); } tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("aff_open file: %" PRIttocTSK ": Error checking type", images[0]); tsk_img_free(aff_info); free(image); return NULL; } else if (type == AF_IDENTIFY_AFF) { img_info->itype = TSK_IMG_TYPE_AFF_AFF; } else if (type == AF_IDENTIFY_AFD) { img_info->itype = TSK_IMG_TYPE_AFF_AFD; } else if (type == AF_IDENTIFY_AFM) { img_info->itype = TSK_IMG_TYPE_AFF_AFM; } else { img_info->itype = TSK_IMG_TYPE_AFF_ANY; } aff_info->af_file = af_open(image, O_RDONLY | O_BINARY, 0); if (!aff_info->af_file) { // @@@ Need to check here if the open failed because of an incorrect password. tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("aff_open file: %" PRIttocTSK ": Error opening - %s", images[0], strerror(errno)); tsk_img_free(aff_info); if (tsk_verbose) { tsk_fprintf(stderr, "Error opening AFF/AFD/AFM file\n"); perror("aff_open"); } free(image); return NULL; } // verify that a password was given and we can read encrypted data. if (af_cannot_decrypt(aff_info->af_file)) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_PASSWD); tsk_error_set_errstr("aff_open file: %" PRIttocTSK, images[0]); tsk_img_free(aff_info); if (tsk_verbose) { tsk_fprintf(stderr, "Error opening AFF/AFD/AFM file (incorrect password)\n"); } free(image); return NULL; } aff_info->type = type; img_info->size = af_imagesize(aff_info->af_file); af_seek(aff_info->af_file, 0, SEEK_SET); aff_info->seek_pos = 0; free(image); return img_info; }
TSK_IMG_INFO * ewf_open(int a_num_img, const TSK_TCHAR * const a_images[], unsigned int a_ssize) { #if defined( HAVE_LIBEWF_V2_API ) char error_string[TSK_EWF_ERROR_STRING_SIZE]; libewf_error_t *ewf_error = NULL; int result = 0; #elif !defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) uint8_t md5_hash[16]; #endif IMG_EWF_INFO *ewf_info = NULL; TSK_IMG_INFO *img_info = NULL; #if !defined( HAVE_LIBEWF_V2_API) if (tsk_verbose) libewf_set_notify_values(stderr, 1); #endif if ((ewf_info = (IMG_EWF_INFO *) tsk_img_malloc(sizeof(IMG_EWF_INFO))) == NULL) { return NULL; } img_info = (TSK_IMG_INFO *) ewf_info; // See if they specified only the first of the set... ewf_info->used_ewf_glob = 0; if (a_num_img == 1) { #if defined( HAVE_LIBEWF_V2_API) #ifdef TSK_WIN32 if (libewf_glob_wide(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images, &ewf_info->num_imgs, &ewf_error) == -1) { #else if (libewf_glob(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images, &ewf_info->num_imgs, &ewf_error) == -1) { #endif tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open: Not an E01 glob name (%s)", error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); return NULL; } #else //use v1 #ifdef TSK_WIN32 ewf_info->num_imgs = libewf_glob_wide(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images); #else ewf_info->num_imgs = libewf_glob(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images); #endif if (ewf_info->num_imgs <= 0) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); tsk_error_set_errstr("ewf_open: Not an E01 glob name"); tsk_img_free(ewf_info); return NULL; } #endif // end v1 ewf_info->used_ewf_glob = 1; if (tsk_verbose) tsk_fprintf(stderr, "ewf_open: found %d segment files via libewf_glob\n", ewf_info->num_imgs); } else { int i; ewf_info->num_imgs = a_num_img; if ((ewf_info->images = (TSK_TCHAR **) tsk_malloc(a_num_img * sizeof(TSK_TCHAR *))) == NULL) { tsk_img_free(ewf_info); return NULL; } for (i = 0; i < a_num_img; i++) { if ((ewf_info->images[i] = (TSK_TCHAR *) tsk_malloc((TSTRLEN(a_images[i]) + 1) * sizeof(TSK_TCHAR))) == NULL) { tsk_img_free(ewf_info); return NULL; } TSTRNCPY(ewf_info->images[i], a_images[i], TSTRLEN(a_images[i]) + 1); } } #if defined( HAVE_LIBEWF_V2_API ) // Check the file signature before we call the library open #if defined( TSK_WIN32 ) if (libewf_check_file_signature_wide(a_images[0], &ewf_error) != 1) #else if (libewf_check_file_signature(a_images[0], &ewf_error) != 1) #endif { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open: Not an EWF file (%s)", error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Not an EWF file\n"); } return (NULL); } if (libewf_handle_initialize(&(ewf_info->handle), &ewf_error) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error initializing handle (%s)", a_images[0], error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Unable to create EWF handle\n"); } return (NULL); } #if defined( TSK_WIN32 ) if (libewf_handle_open_wide(ewf_info->handle, (wchar_t * const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ, &ewf_error) != 1) #else if (libewf_handle_open(ewf_info->handle, (char *const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ, &ewf_error) != 1) #endif { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error opening (%s)", a_images[0], error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Error opening EWF file\n"); } return (NULL); } if (libewf_handle_get_media_size(ewf_info->handle, (size64_t *) & (img_info->size), &ewf_error) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error getting size of image (%s)", a_images[0], error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Error getting size of EWF file\n"); } return (NULL); } result = libewf_handle_get_utf8_hash_value_md5(ewf_info->handle, (uint8_t *) ewf_info->md5hash, 33, &ewf_error); if (result == -1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error getting MD5 of image (%s)", a_images[0], error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Error getting size of EWF file\n"); } return (NULL); } ewf_info->md5hash_isset = result; #else // V1 API // Check the file signature before we call the library open #if defined( TSK_WIN32 ) if (libewf_check_file_signature_wide(a_images[0]) != 1) #else if (libewf_check_file_signature(a_images[0]) != 1) #endif { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); tsk_error_set_errstr("ewf_open: Not an EWF file"); tsk_img_free(ewf_info); if (tsk_verbose) tsk_fprintf(stderr, "Not an EWF file\n"); return NULL; } #if defined( TSK_WIN32 ) ewf_info->handle = libewf_open_wide( (wchar_t * const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ); #else ewf_info->handle = libewf_open( (char *const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ); #endif if (ewf_info->handle == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error opening", ewf_info->images[0]); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Error opening EWF file\n"); } return (NULL); } #if defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) // 2007 version img_info->size = libewf_get_media_size(ewf_info->handle); ewf_info->md5hash_isset = libewf_get_stored_md5_hash(ewf_info->handle, ewf_info->md5hash, LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5); #else // libewf-20080322 version if (libewf_get_media_size(ewf_info->handle, (size64_t *) & (img_info->size)) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error getting size of image", ewf_info->images[0]); tsk_img_free(ewf_info); if (tsk_verbose) { tsk_fprintf(stderr, "Error getting size of EWF file\n"); } return (NULL); } if (libewf_get_md5_hash(ewf_info->handle, md5_hash, 16) == 1) { int md5_string_iterator = 0; int md5_hash_iterator = 0; for (md5_hash_iterator = 0; md5_hash_iterator < 16; md5_hash_iterator++) { int digit = md5_hash[md5_hash_iterator] / 16; if (digit <= 9) { ewf_info->md5hash[md5_string_iterator++] = '0' + (char) digit; } else { ewf_info->md5hash[md5_string_iterator++] = 'a' + (char) (digit - 10); } digit = md5_hash[md5_hash_iterator] % 16; if (digit <= 9) { ewf_info->md5hash[md5_string_iterator++] = '0' + (char) digit; } else { ewf_info->md5hash[md5_string_iterator++] = 'a' + (char) (digit - 10); } } ewf_info->md5hash_isset = 1; } #endif /* defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) */ #endif /* defined( HAVE_LIBEWF_V2_API ) */ if (a_ssize != 0) { img_info->sector_size = a_ssize; } else { img_info->sector_size = 512; } img_info->itype = TSK_IMG_TYPE_EWF_EWF; img_info->read = &ewf_image_read; img_info->close = &ewf_image_close; img_info->imgstat = &ewf_image_imgstat; // initialize the read lock tsk_init_lock(&(ewf_info->read_lock)); return (img_info); }
/** * \internal * Open the set of disk images as a set of split raw images * * @param a_num_img Number of images in set * @param a_images List of disk image paths (in sorted order) * @param a_ssize Size of device sector in bytes (or 0 for default) * * @return NULL on error */ TSK_IMG_INFO * raw_open(int a_num_img, const TSK_TCHAR * const a_images[], unsigned int a_ssize) { IMG_RAW_INFO *raw_info; TSK_IMG_INFO *img_info; int i; TSK_OFF_T first_seg_size; if ((raw_info = (IMG_RAW_INFO *) tsk_img_malloc(sizeof(IMG_RAW_INFO))) == NULL) return NULL; img_info = (TSK_IMG_INFO *) raw_info; img_info->itype = TSK_IMG_TYPE_RAW; img_info->read = raw_read; img_info->close = raw_close; img_info->imgstat = raw_imgstat; img_info->sector_size = 512; if (a_ssize) img_info->sector_size = a_ssize; raw_info->is_winobj = 0; #if defined(TSK_WIN32) || defined(__CYGWIN__) /* determine if this is the path to a Windows device object */ if ((a_images[0][0] == _TSK_T('\\')) && (a_images[0][1] == _TSK_T('\\')) && ((a_images[0][2] == _TSK_T('.')) || (a_images[0][2] == _TSK_T('?'))) && (a_images[0][3] == _TSK_T('\\'))) { raw_info->is_winobj = 1; } #endif /* Check that the first image file exists and is not a directory */ first_seg_size = get_size(a_images[0], raw_info->is_winobj); if (first_seg_size < -1) { tsk_img_free(raw_info); return NULL; } /* see if there are more of them... */ if ((a_num_img == 1) && (raw_info->is_winobj == 0)) { if ((raw_info->images = tsk_img_findFiles(a_images[0], &raw_info->num_img)) == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_STAT); tsk_error_set_errstr ("raw_open: could not find segment files starting at \"%" PRIttocTSK "\"", a_images[0]); tsk_img_free(raw_info); return NULL; } } else { raw_info->num_img = a_num_img; raw_info->images = (TSK_TCHAR **) tsk_malloc(sizeof(TSK_TCHAR *) * a_num_img); if (raw_info->images == NULL) { tsk_img_free(raw_info); return NULL; } for (i = 0; i < raw_info->num_img; i++) { size_t len = TSTRLEN(a_images[i]); raw_info->images[i] = (TSK_TCHAR *) tsk_malloc(sizeof(TSK_TCHAR) * (len + 1)); if (raw_info->images[i] == NULL) { int j; for (j = 0; j < i; j++) { free(raw_info->images[j]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } TSTRNCPY(raw_info->images[i], a_images[i], len + 1); } } /* sanity check: when we have multiple segments, the size of * each must be known */ if ((raw_info->num_img > 1) && (first_seg_size < 0)) { if (tsk_verbose) { tsk_fprintf(stderr, "raw_open: file size is unknown in a segmented raw image\n"); } for (i = 0; i < raw_info->num_img; i++) { free(raw_info->images[i]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } /* initialize the split cache */ raw_info->cptr = (int *) tsk_malloc(raw_info->num_img * sizeof(int)); if (raw_info->cptr == NULL) { for (i = 0; i < raw_info->num_img; i++) { free(raw_info->images[i]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } memset((void *) &raw_info->cache, 0, SPLIT_CACHE * sizeof(IMG_SPLIT_CACHE)); raw_info->next_slot = 0; /* initialize the offset table and re-use the first segment * size gathered above */ raw_info->max_off = (TSK_OFF_T *) tsk_malloc(raw_info->num_img * sizeof(TSK_OFF_T)); if (raw_info->max_off == NULL) { free(raw_info->cptr); for (i = 0; i < raw_info->num_img; i++) { free(raw_info->images[i]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } img_info->size = first_seg_size; raw_info->max_off[0] = img_info->size; raw_info->cptr[0] = -1; if (tsk_verbose) { tsk_fprintf(stderr, "raw_open: segment: 0 size: %" PRIuOFF " max offset: %" PRIuOFF " path: %" PRIttocTSK "\n", first_seg_size, raw_info->max_off[0], raw_info->images[0]); } /* get size info for each file - we do not open each one because that * could cause us to run out of file decsriptors when we only need a few. * The descriptors are opened as needed */ for (i = 1; i < raw_info->num_img; i++) { TSK_OFF_T size; raw_info->cptr[i] = -1; size = get_size(raw_info->images[i], raw_info->is_winobj); if (size < 0) { if (size == -1) { if (tsk_verbose) { tsk_fprintf(stderr, "raw_open: file size is unknown in a segmented raw image\n"); } } free(raw_info->cptr); for (i = 0; i < raw_info->num_img; i++) { free(raw_info->images[i]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } /* add the size of this image to the total and save the current max */ img_info->size += size; raw_info->max_off[i] = img_info->size; if (tsk_verbose) { tsk_fprintf(stderr, "raw_open: segment: %d size: %" PRIuOFF " max offset: %" PRIuOFF " path: %" PRIttocTSK "\n", i, size, raw_info->max_off[i], raw_info->images[i]); } } return img_info; }