1 /*
2  * The Sleuth Kit - Add on for Expert Witness Compression Format (EWF) image support
3  *
4  * Copyright (c) 2006, 2011 Joachim Metz <jbmetz@users.sourceforge.net>
5  *
6  * This software is distributed under the Common Public License 1.0
7  *
8  * Based on raw image support of the Sleuth Kit from
9  * Brian Carrier.
10  */
11 
12 /** \file ewf.c
13  * Internal code for TSK to interface with libewf.
14  */
15 
16 #include "tsk_img_i.h"
17 
18 #if HAVE_LIBEWF
19 #include "ewf.h"
20 #include <cctype>
21 
22 using std::string;
23 
24 #define TSK_EWF_ERROR_STRING_SIZE 512
25 
26 
27 #if defined( HAVE_LIBEWF_V2_API )
28 /**
29  * Get error string from libewf and make buffer empty if that didn't work.
30  * @returns 1 if error message was not set
31  */
32 static uint8_t
getError(libewf_error_t * ewf_error,char error_string[TSK_EWF_ERROR_STRING_SIZE])33 getError(libewf_error_t * ewf_error,
34     char error_string[TSK_EWF_ERROR_STRING_SIZE])
35 {
36     int retval;
37     error_string[0] = '\0';
38     retval = libewf_error_backtrace_sprint(ewf_error,
39         error_string, TSK_EWF_ERROR_STRING_SIZE);
40     return retval <= 0;
41 }
42 #endif
43 
44 static ssize_t
ewf_image_read(TSK_IMG_INFO * img_info,TSK_OFF_T offset,char * buf,size_t len)45 ewf_image_read(TSK_IMG_INFO * img_info, TSK_OFF_T offset, char *buf,
46     size_t len)
47 {
48 #if defined( HAVE_LIBEWF_V2_API )
49     char error_string[TSK_EWF_ERROR_STRING_SIZE];
50     libewf_error_t *ewf_error = NULL;
51 #endif
52 
53     ssize_t cnt;
54     IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *) img_info;
55 
56     if (tsk_verbose)
57         tsk_fprintf(stderr,
58             "ewf_image_read: byte offset: %" PRIdOFF " len: %" PRIuSIZE
59             "\n", offset, len);
60 
61     if (offset > img_info->size) {
62         tsk_error_reset();
63         tsk_error_set_errno(TSK_ERR_IMG_READ_OFF);
64         tsk_error_set_errstr("ewf_image_read - %" PRIdOFF, offset);
65         return -1;
66     }
67 
68     tsk_take_lock(&(ewf_info->read_lock));
69 #if defined( HAVE_LIBEWF_V2_API )
70     cnt = libewf_handle_read_random(ewf_info->handle,
71         buf, len, offset, &ewf_error);
72     if (cnt < 0) {
73         char *errmsg = NULL;
74         tsk_error_reset();
75         tsk_error_set_errno(TSK_ERR_IMG_READ);
76         if (getError(ewf_error, error_string))
77             errmsg = strerror(errno);
78         else
79             errmsg = error_string;
80 
81         libewf_error_free(&ewf_error);
82         tsk_error_set_errstr("ewf_image_read - offset: %" PRIdOFF
83             " - len: %" PRIuSIZE " - %s", offset, len, errmsg);
84         tsk_release_lock(&(ewf_info->read_lock));
85         return -1;
86     }
87 #else
88     cnt = libewf_read_random(ewf_info->handle, buf, len, offset);
89     if (cnt < 0) {
90         tsk_error_reset();
91         tsk_error_set_errno(TSK_ERR_IMG_READ);
92         tsk_error_set_errstr("ewf_image_read - offset: %" PRIdOFF
93             " - len: %" PRIuSIZE " - %s", offset, len, strerror(errno));
94         tsk_release_lock(&(ewf_info->read_lock));
95         return -1;
96     }
97 #endif
98     tsk_release_lock(&(ewf_info->read_lock));
99 
100     return cnt;
101 }
102 
103 static void
ewf_image_imgstat(TSK_IMG_INFO * img_info,FILE * hFile)104 ewf_image_imgstat(TSK_IMG_INFO * img_info, FILE * hFile)
105 {
106     IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *) img_info;
107 
108     tsk_fprintf(hFile, "IMAGE FILE INFORMATION\n");
109     tsk_fprintf(hFile, "--------------------------------------------\n");
110     tsk_fprintf(hFile, "Image Type:\t\tewf\n");
111     tsk_fprintf(hFile, "\nSize of data in bytes:\t%" PRIdOFF "\n",
112         img_info->size);
113     tsk_fprintf(hFile, "Sector size:\t%d\n", img_info->sector_size);
114 
115     if (ewf_info->md5hash_isset == 1) {
116         tsk_fprintf(hFile, "MD5 hash of data:\t%s\n", ewf_info->md5hash);
117     }
118     return;
119 }
120 
121 static void
ewf_image_close(TSK_IMG_INFO * img_info)122 ewf_image_close(TSK_IMG_INFO * img_info)
123 {
124     IMG_EWF_INFO *ewf_info = (IMG_EWF_INFO *) img_info;
125 
126 #if defined ( HAVE_LIBEWF_V2_API)
127     libewf_handle_close(ewf_info->handle, NULL);
128     libewf_handle_free(&(ewf_info->handle), NULL);
129 
130 #else
131     libewf_close(ewf_info->handle);
132 #endif
133 
134     // this stuff crashes if we used glob. v2 of the API has a free method.
135     // not clear from the docs what we should do in v1...
136     // @@@ Probably a memory leak in v1 unless libewf_close deals with it
137     if (ewf_info->used_ewf_glob == 0) {
138         int i;
139         for (i = 0; i < ewf_info->img_info.num_img; i++) {
140             free(ewf_info->img_info.images[i]);
141         }
142         free(ewf_info->img_info.images);
143     }
144     else {
145 #ifdef TSK_WIN32
146         libewf_glob_wide_free( ewf_info->img_info.images, ewf_info->img_info.num_img, NULL);
147 #else
148         libewf_glob_free( ewf_info->img_info.images, ewf_info->img_info.num_img, NULL);
149 #endif
150     }
151 
152     tsk_deinit_lock(&(ewf_info->read_lock));
153     tsk_img_free(ewf_info);
154 }
155 
156 /* Tests if the image file header against the
157  * header (magic) signature specified.
158  * Returns a 0 on no match and a 1 on a match, and -1 on error.
159  */
160 #if 0
161 static int
162 img_file_header_signature_ncmp(const char *filename,
163     const char *file_header_signature, int size_of_signature)
164 {
165     int match;
166     ssize_t read_count = 0;
167     char header[512];
168     int fd;
169 
170     if ((filename == NULL) || (file_header_signature == NULL)) {
171         return 0;
172     }
173     if (size_of_signature <= 0) {
174         return 0;
175     }
176 
177     if ((fd = open(filename, O_RDONLY | O_BINARY)) < 0) {
178         tsk_error_reset();
179         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
180         tsk_error_set_errstr("ewf magic testing: %s", filename);
181         return -1;
182     }
183     read_count = read(fd, header, 512);
184 
185     if (read_count != 512) {
186         tsk_error_reset();
187         tsk_error_set_errno(TSK_ERR_IMG_READ);
188         tsk_error_set_errstr("ewf magic testing: %s", filename);
189         return -1;
190     }
191     close(fd);
192 
193     match = strncmp(file_header_signature, header, size_of_signature) == 0;
194 
195     return match;
196 }
197 #endif
198 
199 
200 
201 TSK_IMG_INFO *
ewf_open(int a_num_img,const TSK_TCHAR * const a_images[],unsigned int a_ssize)202 ewf_open(int a_num_img,
203     const TSK_TCHAR * const a_images[], unsigned int a_ssize)
204 {
205     int is_error;
206 #if defined( HAVE_LIBEWF_V2_API )
207     char error_string[TSK_EWF_ERROR_STRING_SIZE];
208 
209     libewf_error_t *ewf_error = NULL;
210     int result = 0;
211 #elif !defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 )
212     uint8_t md5_hash[16];
213 #endif
214 
215     IMG_EWF_INFO *ewf_info = NULL;
216     TSK_IMG_INFO *img_info = NULL;
217 
218 #if !defined( HAVE_LIBEWF_V2_API)
219     if (tsk_verbose)
220         libewf_set_notify_values(stderr, 1);
221 #endif
222 
223     if ((ewf_info =
224             (IMG_EWF_INFO *) tsk_img_malloc(sizeof(IMG_EWF_INFO))) ==
225         NULL) {
226         return NULL;
227     }
228     img_info = (TSK_IMG_INFO *) ewf_info;
229 
230     // See if they specified only the first of the set...
231     ewf_info->used_ewf_glob = 0;
232     if (a_num_img == 1) {
233 #if defined( HAVE_LIBEWF_V2_API)
234 #ifdef TSK_WIN32
235         is_error = (libewf_glob_wide(a_images[0], TSTRLEN(a_images[0]),
236                 LIBEWF_FORMAT_UNKNOWN, &ewf_info->img_info.images,
237                 &ewf_info->img_info.num_img, &ewf_error) == -1);
238 #else
239         is_error = (libewf_glob(a_images[0], TSTRLEN(a_images[0]),
240                 LIBEWF_FORMAT_UNKNOWN, &ewf_info->img_info.images,
241                 &ewf_info->img_info.num_img, &ewf_error) == -1);
242 #endif
243         if (is_error){
244             tsk_error_reset();
245             tsk_error_set_errno(TSK_ERR_IMG_MAGIC);
246 
247             getError(ewf_error, error_string);
248             tsk_error_set_errstr("ewf_open: Not an E01 glob name (%s)",
249                 error_string);
250             libewf_error_free(&ewf_error);
251             tsk_img_free(ewf_info);
252             return NULL;
253         }
254 
255 #else                           //use v1
256 
257 #ifdef TSK_WIN32
258         ewf_info->img_info.num_img =
259             libewf_glob_wide(a_images[0], TSTRLEN(a_images[0]),
260             LIBEWF_FORMAT_UNKNOWN, &ewf_info->img_info.images);
261 #else
262         ewf_info->img_info.num_img =
263             libewf_glob(a_images[0], TSTRLEN(a_images[0]),
264             LIBEWF_FORMAT_UNKNOWN, &ewf_info->img_info.images);
265 #endif
266         if (ewf_info->img_info.num_img <= 0) {
267             tsk_error_reset();
268             tsk_error_set_errno(TSK_ERR_IMG_MAGIC);
269             tsk_error_set_errstr("ewf_open: Not an E01 glob name");
270 
271             tsk_img_free(ewf_info);
272             return NULL;
273         }
274 #endif                          // end v1
275 
276         ewf_info->used_ewf_glob = 1;
277         if (tsk_verbose)
278             tsk_fprintf(stderr,
279                 "ewf_open: found %d segment files via libewf_glob\n",
280                 ewf_info->img_info.num_img);
281     }
282     else {
283         int i;
284         ewf_info->img_info.num_img = a_num_img;
285         if ((ewf_info->img_info.images =
286                 (TSK_TCHAR **) tsk_malloc(a_num_img *
287                     sizeof(TSK_TCHAR *))) == NULL) {
288             tsk_img_free(ewf_info);
289             return NULL;
290         }
291         for (i = 0; i < a_num_img; i++) {
292             if ((ewf_info->img_info.images[i] =
293                     (TSK_TCHAR *) tsk_malloc((TSTRLEN(a_images[i]) +
294                             1) * sizeof(TSK_TCHAR))) == NULL) {
295                 tsk_img_free(ewf_info);
296                 return NULL;
297             }
298             TSTRNCPY(ewf_info->img_info.images[i], a_images[i],
299                 TSTRLEN(a_images[i]) + 1);
300         }
301     }
302 
303 
304 #if defined( HAVE_LIBEWF_V2_API )
305 
306     // Check the file signature before we call the library open
307 #if defined( TSK_WIN32 )
308     is_error = (libewf_check_file_signature_wide(a_images[0], &ewf_error) != 1);
309 #else
310     is_error = (libewf_check_file_signature(a_images[0], &ewf_error) != 1);
311 #endif
312     if (is_error)
313     {
314         tsk_error_reset();
315         tsk_error_set_errno(TSK_ERR_IMG_MAGIC);
316 
317         getError(ewf_error, error_string);
318         tsk_error_set_errstr("ewf_open: Not an EWF file (%s)",
319             error_string);
320         libewf_error_free(&ewf_error);
321 
322         tsk_img_free(ewf_info);
323 
324         if (tsk_verbose != 0) {
325             tsk_fprintf(stderr, "Not an EWF file\n");
326         }
327         return (NULL);
328     }
329 
330     if (libewf_handle_initialize(&(ewf_info->handle), &ewf_error) != 1) {
331         tsk_error_reset();
332         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
333 
334         getError(ewf_error, error_string);
335         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
336             ": Error initializing handle (%s)", a_images[0], error_string);
337         libewf_error_free(&ewf_error);
338 
339         tsk_img_free(ewf_info);
340 
341         if (tsk_verbose != 0) {
342             tsk_fprintf(stderr, "Unable to create EWF handle\n");
343         }
344         return (NULL);
345     }
346 #if defined( TSK_WIN32 )
347     is_error = (libewf_handle_open_wide(ewf_info->handle,
348             (wchar_t * const *) ewf_info->img_info.images,
349             ewf_info->img_info.num_img, LIBEWF_OPEN_READ, &ewf_error) != 1);
350 #else
351     is_error = (libewf_handle_open(ewf_info->handle,
352             (char *const *) ewf_info->img_info.images,
353             ewf_info->img_info.num_img, LIBEWF_OPEN_READ, &ewf_error) != 1);
354 #endif
355     if (is_error)
356     {
357         tsk_error_reset();
358         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
359 
360         getError(ewf_error, error_string);
361         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
362             ": Error opening (%s)", a_images[0], error_string);
363         libewf_error_free(&ewf_error);
364 
365         tsk_img_free(ewf_info);
366 
367         if (tsk_verbose != 0) {
368             tsk_fprintf(stderr, "Error opening EWF file\n");
369         }
370         return (NULL);
371     }
372     if (libewf_handle_get_media_size(ewf_info->handle,
373             (size64_t *) & (img_info->size), &ewf_error) != 1) {
374         tsk_error_reset();
375         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
376 
377         getError(ewf_error, error_string);
378         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
379             ": Error getting size of image (%s)", a_images[0],
380             error_string);
381         libewf_error_free(&ewf_error);
382 
383         tsk_img_free(ewf_info);
384 
385         if (tsk_verbose != 0) {
386             tsk_fprintf(stderr, "Error getting size of EWF file\n");
387         }
388         return (NULL);
389     }
390     result = libewf_handle_get_utf8_hash_value_md5(ewf_info->handle,
391         (uint8_t *) ewf_info->md5hash, 33, &ewf_error);
392 
393     if (result == -1) {
394         tsk_error_reset();
395         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
396 
397         getError(ewf_error, error_string);
398         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
399             ": Error getting MD5 of image (%s)", a_images[0],
400             error_string);
401         libewf_error_free(&ewf_error);
402 
403         tsk_img_free(ewf_info);
404 
405         if (tsk_verbose != 0) {
406             tsk_fprintf(stderr, "Error getting MD5 of EWF file\n");
407         }
408         return (NULL);
409     }
410     ewf_info->md5hash_isset = result;
411 
412     result = libewf_handle_get_utf8_hash_value_sha1(ewf_info->handle,
413         (uint8_t *)ewf_info->sha1hash, 41, &ewf_error);
414 
415     if (result == -1) {
416         tsk_error_reset();
417         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
418 
419         getError(ewf_error, error_string);
420         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
421             ": Error getting SHA1 of image (%s)", a_images[0],
422             error_string);
423         libewf_error_free(&ewf_error);
424 
425         tsk_img_free(ewf_info);
426 
427         if (tsk_verbose != 0) {
428             tsk_fprintf(stderr, "Error getting SHA1 of EWF file\n");
429         }
430         return NULL;
431     }
432     ewf_info->sha1hash_isset = result;
433 
434 
435 #else                           // V1 API
436 
437     // Check the file signature before we call the library open
438 #if defined( TSK_WIN32 )
439     is_error = (libewf_check_file_signature_wide(a_images[0]) != 1);
440 #else
441     is_error = (libewf_check_file_signature(a_images[0]) != 1);
442 #endif
443     if (is_error)
444     {
445         tsk_error_reset();
446         tsk_error_set_errno(TSK_ERR_IMG_MAGIC);
447         tsk_error_set_errstr("ewf_open: Not an EWF file");
448         tsk_img_free(ewf_info);
449         if (tsk_verbose)
450             tsk_fprintf(stderr, "Not an EWF file\n");
451 
452         return NULL;
453     }
454 
455 #if defined( TSK_WIN32 )
456     ewf_info->handle = libewf_open_wide(
457         (wchar_t * const *) ewf_info->img_info.images, ewf_info->img_info.num_img,
458         LIBEWF_OPEN_READ);
459 #else
460     ewf_info->handle = libewf_open(
461         (char *const *) ewf_info->img_info.images, ewf_info->img_info.num_img,
462         LIBEWF_OPEN_READ);
463 #endif
464     if (ewf_info->handle == NULL) {
465         tsk_error_reset();
466         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
467         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
468             ": Error opening", ewf_info->img_info.images[0]);
469         tsk_img_free(ewf_info);
470 
471         if (tsk_verbose != 0) {
472             tsk_fprintf(stderr, "Error opening EWF file\n");
473         }
474         return (NULL);
475     }
476 #if defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 )
477     // 2007 version
478     img_info->size = libewf_get_media_size(ewf_info->handle);
479 
480     ewf_info->md5hash_isset = libewf_get_stored_md5_hash(ewf_info->handle,
481         ewf_info->md5hash, LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5);
482 #else
483     // libewf-20080322 version
484     if (libewf_get_media_size(ewf_info->handle,
485             (size64_t *) & (img_info->size)) != 1) {
486         tsk_error_reset();
487         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
488         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
489             ": Error getting size of image", ewf_info->img_info.images[0]);
490         tsk_img_free(ewf_info);
491         if (tsk_verbose) {
492             tsk_fprintf(stderr, "Error getting size of EWF file\n");
493         }
494         return (NULL);
495     }
496     if (libewf_get_md5_hash(ewf_info->handle, md5_hash, 16) == 1) {
497         int md5_string_iterator = 0;
498         int md5_hash_iterator = 0;
499 
500         for (md5_hash_iterator = 0;
501             md5_hash_iterator < 16; md5_hash_iterator++) {
502             int digit = md5_hash[md5_hash_iterator] / 16;
503 
504             if (digit <= 9) {
505                 ewf_info->md5hash[md5_string_iterator++] =
506                     '0' + (char) digit;
507             }
508             else {
509                 ewf_info->md5hash[md5_string_iterator++] =
510                     'a' + (char) (digit - 10);
511             }
512             digit = md5_hash[md5_hash_iterator] % 16;
513 
514             if (digit <= 9) {
515                 ewf_info->md5hash[md5_string_iterator++] =
516                     '0' + (char) digit;
517             }
518             else {
519                 ewf_info->md5hash[md5_string_iterator++] =
520                     'a' + (char) (digit - 10);
521             }
522         }
523         ewf_info->md5hash_isset = 1;
524     }
525 #endif                          /* defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) */
526 #endif                          /* defined( HAVE_LIBEWF_V2_API ) */
527 
528     // use what they gave us
529     if (a_ssize != 0) {
530         img_info->sector_size = a_ssize;
531     }
532     else {
533         uint32_t bytes_per_sector = 512;
534         // see if the size is stored in the E01 file
535         if (-1 == libewf_handle_get_bytes_per_sector(ewf_info->handle,
536             &bytes_per_sector, NULL)) {
537             if (tsk_verbose)
538                 tsk_fprintf(stderr,
539                     "ewf_image_read: error getting sector size from E01\n");
540             img_info->sector_size = 512;
541         }
542         else {
543             // if E01 had size of 0 or non-512 then consider it junk and ignore
544             if ((bytes_per_sector == 0) || (bytes_per_sector % 512)) {
545                 if (tsk_verbose)
546                     tsk_fprintf(stderr,
547                         "ewf_image_read: Ignoring sector size in E01 (%d)\n",
548                         bytes_per_sector);
549                 bytes_per_sector = 512;
550             }
551             else {
552                 if (tsk_verbose)
553                     tsk_fprintf(stderr,
554                         "ewf_image_read: Using E01 sector size (%d)\n",
555                         bytes_per_sector);
556             }
557             img_info->sector_size = bytes_per_sector;
558         }
559     }
560     img_info->itype = TSK_IMG_TYPE_EWF_EWF;
561     img_info->read = &ewf_image_read;
562     img_info->close = &ewf_image_close;
563     img_info->imgstat = &ewf_image_imgstat;
564 
565     // initialize the read lock
566     tsk_init_lock(&(ewf_info->read_lock));
567 
568     return (img_info);
569 }
570 
571 
572 
is_blank(const char * str)573 static int is_blank(const char* str) {
574     while (*str != '\0') {
575         if (!isspace((unsigned char)*str)) {
576             return 0;
577         }
578         str++;
579     }
580     return 1;
581 }
582 
583 /**
584 * Reads from libewf what is left in the buffer after the addition of the key and new line
585  * @param handle
586   * @param result_buffer Buffer to read results into
587   * @param buffer_size Size of buffer
588 
589   * @param identifier Name of value to get from E01
590   * @param key Display name of the value (with a space at end)
591 */
read_libewf_header_value(libewf_handle_t * handle,char * result_buffer,const size_t buffer_size,const uint8_t * identifier,const char * key)592 static char* read_libewf_header_value(libewf_handle_t *handle, char* result_buffer, const size_t buffer_size, const uint8_t *identifier,  const char* key) {
593     result_buffer[0] = '\0';
594     size_t identifier_length = strlen((char *)identifier);
595     strcpy(result_buffer, key);
596     size_t key_len = strlen(key);
597 
598     //buffer_size - key_len - 1 for the new line at the end
599     int result = libewf_handle_get_utf8_header_value(handle, identifier, identifier_length, (uint8_t *)(result_buffer + key_len), buffer_size - key_len - 1, NULL);
600     if (result != -1 && !is_blank(result_buffer + key_len)) {
601         strcat(result_buffer, "\n");
602     }
603     else {
604         //if blank or error, return nothing!
605         result_buffer[0] = '\0';
606     }
607 
608     return result_buffer;
609 }
610 
libewf_read_description(libewf_handle_t * handle,char * result_buffer,const size_t buffer_size)611 static char* libewf_read_description(libewf_handle_t *handle, char* result_buffer, const size_t buffer_size) {
612     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "description", "Description: ");
613 }
614 
libewf_read_case_number(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)615 static char* libewf_read_case_number(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
616     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "case_number", "Case Number: ");
617 }
618 
libewf_read_evidence_number(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)619 static char* libewf_read_evidence_number(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
620     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "evidence_number", "Evidence Number: ");
621 }
622 
libewf_read_examiner_name(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)623 static char* libewf_read_examiner_name(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
624     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "examiner_name", "Examiner Name: ");
625 }
626 
libewf_read_notes(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)627 static char* libewf_read_notes(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
628     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "notes", "Notes: ");
629 }
630 
libewf_read_model(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)631 static char* libewf_read_model(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
632     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "model", "Model: ");
633 }
634 
libewf_read_serial_number(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)635 static char* libewf_read_serial_number(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
636     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "serial_number", "Serial Number: ");
637 }
638 
libewf_read_device_label(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)639 static char* libewf_read_device_label(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
640     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "device_label", "Device Label:");
641 }
642 
libewf_read_version(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)643 static char* libewf_read_version(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
644     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "version", "Version: ");
645 }
646 
libewf_read_platform(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)647 static char* libewf_read_platform(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
648     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "platform", "Platform: ");
649 }
650 
libewf_read_acquired_date(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)651 static char* libewf_read_acquired_date(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
652     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "acquiry_date", "Acquired Date: ");
653 }
654 
libewf_read_system_date(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)655 static char* libewf_read_system_date(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
656     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "system_date", "System Date: ");
657 }
658 
libewf_read_acquiry_operating_system(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)659 static char* libewf_read_acquiry_operating_system(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
660     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "acquiry_operating_system", "Acquiry Operating System: ");
661 }
662 
libewf_read_acquiry_software_version(libewf_handle_t * handle,char * result_buffer,size_t buffer_size)663 static char* libewf_read_acquiry_software_version(libewf_handle_t *handle, char* result_buffer, size_t buffer_size) {
664     return read_libewf_header_value(handle, result_buffer, buffer_size, (uint8_t *) "acquiry_software_version", "Acquiry Software Version: ");
665 }
666 
667 
668 
669 /**
670  * Return text with name/value pairs from the E01 image.
671  */
ewf_get_details(IMG_EWF_INFO * ewf_info)672 std::string ewf_get_details(IMG_EWF_INFO *ewf_info) {
673     //Need 1MB for libewf read and extra 100 bytes for header name and formatting
674     const size_t buffer_size = 1024100;
675 
676     char* result = (char*)tsk_malloc(buffer_size);
677     if (result == NULL) {
678         return NULL;
679     }
680 
681     string collectionDetails = "";
682     //Populate all of the libewf header values for the acquisition details column
683     collectionDetails.append(libewf_read_description(ewf_info->handle, result, buffer_size));
684     collectionDetails.append(libewf_read_case_number(ewf_info->handle, result, buffer_size));
685     collectionDetails.append(libewf_read_evidence_number(ewf_info->handle, result, buffer_size));
686     collectionDetails.append(libewf_read_examiner_name(ewf_info->handle, result, buffer_size));
687     collectionDetails.append(libewf_read_notes(ewf_info->handle, result, buffer_size));
688     collectionDetails.append(libewf_read_model(ewf_info->handle, result, buffer_size));
689     collectionDetails.append(libewf_read_serial_number(ewf_info->handle, result, buffer_size));
690     collectionDetails.append(libewf_read_device_label(ewf_info->handle, result, buffer_size));
691     collectionDetails.append(libewf_read_version(ewf_info->handle, result, buffer_size));
692     collectionDetails.append(libewf_read_platform(ewf_info->handle, result, buffer_size));
693     collectionDetails.append(libewf_read_acquired_date(ewf_info->handle, result, buffer_size));
694     collectionDetails.append(libewf_read_system_date(ewf_info->handle, result, buffer_size));
695     collectionDetails.append(libewf_read_acquiry_operating_system(ewf_info->handle, result, buffer_size));
696     collectionDetails.append(libewf_read_acquiry_software_version(ewf_info->handle, result, buffer_size));
697     free(result);
698     return collectionDetails;
699 }
700 #endif                          /* HAVE_LIBEWF */
701