1 /*
2  * The Sleuth Kit
3  *
4  * Brian Carrier [carrier <at> sleuthkit [dot] org]
5  * Copyright (c) 2007-2011 Brian Carrier.  All Rights reserved
6  *
7  * This software is distributed under the Common Public License 1.0
8  */
9 
10 /** \file tsk_base.h
11  * Contains the type and function definitions that are needed
12  * by external programs to use the TSK library.
13  * Note that this file is not meant to be directly included.
14  * It is included by both libtsk.h and tsk_base_i.h.
15  */
16 
17 
18 /**
19  * \defgroup baselib C Base TSK Library Functions
20  * \defgroup baselib_cpp C++ Base TSK Library Classes
21  */
22 
23 #ifndef _TSK_BASE_H
24 #define _TSK_BASE_H
25 
26 // standard C header files
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 
31 /** Version of code in number form.
32  * Upper byte is A, next is B, and next byte is C in version A.B.C.
33  * Lowest byte is 0xff, except in beta releases, in which case it
34  * increments from 1.  Nightly snapshots will have upper byte as
35  * 0xff and next bytes with year, month, and date, respectively.
36  * Note that you will not be able to differentiate between snapshots
37  * from the trunk or branches with this method...
38  * For example, 3.1.2 would be stored as 0x030102FF.
39  * 3.1.2b1 would be 0x03010201.  Snapshot from Jan 2, 2003 would be
40  * 0xFF030102.
41  * See TSK_VERSION_STR for string form. */
42 #define TSK_VERSION_NUM 0x040700ff
43 
44 /** Version of code in string form. See TSK_VERSION_NUM for
45  * integer form. */
46 #define TSK_VERSION_STR "4.7.0"
47 
48 
49 /* include the TSK-specific header file that we created in autoconf
50  * On Win32 (Visual Studio) though, we will not have this file...
51  */
52 #if !defined(_MSC_VER)
53 #include "tsk/tsk_incs.h"
54 #endif
55 
56 // get some other TSK / OS settings
57 #include "tsk_os.h"
58 
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
62 
63 #define TSK_ERROR_STRING_MAX_LENGTH 1024
64 
65     typedef struct {
66         uint32_t t_errno;
67         char errstr[TSK_ERROR_STRING_MAX_LENGTH + 1];
68         char errstr2[TSK_ERROR_STRING_MAX_LENGTH + 1];
69         char errstr_print[TSK_ERROR_STRING_MAX_LENGTH + 1];
70     } TSK_ERROR_INFO;
71 
72     /* The core function here is to retrieve the per-thread error structure. Other functions to follow
73      * are for convenience of performing common operations. */
74     extern TSK_ERROR_INFO *tsk_error_get_info();
75 
76     extern uint32_t tsk_error_get_errno();
77     extern void tsk_error_set_errno(uint32_t t_errno);
78 
79 #ifdef __GNUC__
80 #define TSK_ERROR_FORMAT_ATTRIBUTE(n,m) __attribute__((format (printf, n, m)))
81 #else
82 #define TSK_ERROR_FORMAT_ATTRIBUTE(n,m)
83 #endif
84 
85     extern char *tsk_error_get_errstr();
86     extern void tsk_error_set_errstr(const char *format,
87         ...) TSK_ERROR_FORMAT_ATTRIBUTE(1, 2);
88     extern void tsk_error_vset_errstr(const char *format, va_list args);
89     extern char *tsk_error_get_errstr2();
90     extern void tsk_error_set_errstr2(const char *format,
91         ...) TSK_ERROR_FORMAT_ATTRIBUTE(1, 2);
92     extern void tsk_error_vset_errstr2(const char *format, va_list args);
93     extern void tsk_error_errstr2_concat(const char *format,
94         ...) TSK_ERROR_FORMAT_ATTRIBUTE(1, 2);
95 
96     /** Return a human-readable form of tsk_error_get_errno **/
97     extern const char *tsk_error_get();
98 
99     extern void tsk_error_print(FILE *);
100     extern void tsk_error_reset();
101 
102 
103 #ifdef TSK_MULTITHREAD_LIB
104 #ifdef TSK_WIN32
105     void *tsk_error_win32_get_per_thread_(unsigned struct_size);
106     typedef struct {
107         CRITICAL_SECTION critical_section;
108     } tsk_lock_t;
109 
110     // non-windows
111 #else
112 /* Note that there is an assumption that TSK_MULTITHREADED_LIB was
113  * set only if we have pthreads. If we add a check for HAVE_PTHREAD
114  * here, it causes problems when you try to include the library in
115  * a tool because they do not have tsk_config.h included.
116  */
117 #include <pthread.h>
118     typedef struct {
119         pthread_mutex_t mutex;
120     } tsk_lock_t;
121 
122 #endif
123 
124     // single threaded lib
125 #else
126     typedef struct {
127         void *dummy;
128     } tsk_lock_t;
129 #endif
130 
131 /**
132  * Return values for some TSK functions that need to differentiate between errors and corrupt data.
133  */
134     typedef enum {
135         TSK_OK,                 ///< Ok -- success
136         TSK_ERR,                ///< System error -- should abort
137         TSK_COR,                ///< Data is corrupt, can still process another set of data
138         TSK_STOP                ///< Stop further processing, not an error though.
139     } TSK_RETVAL_ENUM;
140 
141 
142     typedef struct TSK_LIST TSK_LIST;
143     /**
144     * Linked list structure that holds a 'key' and optional 'length'.
145     * Note that the data is stored in reverse sort order so that inserts
146     * are faster.  Also note that the length is a negative number. A key of
147     * '6' and a len of '2' means that the run contains 6 and 5.
148     */
149     struct TSK_LIST {
150         TSK_LIST *next;         ///< Pointer to next entry in list
151         uint64_t key;           ///< Largest value in this run
152         uint64_t len;           ///< Length of run (negative number, stored as positive)
153     };
154     extern uint8_t tsk_list_find(TSK_LIST * list, uint64_t key);
155     extern uint8_t tsk_list_add(TSK_LIST ** list, uint64_t key);
156     extern void tsk_list_free(TSK_LIST * list);
157 
158 
159     // note that the stack code is in this file and not internal for convenience to users
160     /**
161      * Basic stack structure to push and pop (used for finding loops in recursion).
162      */
163     typedef struct {
164         uint64_t *vals;         ///< Array that contains the values in the stack
165         size_t top;             ///< Index to the top stack entry
166         size_t len;             ///< Number of entries in the stack
167     } TSK_STACK;
168 
169     extern uint8_t tsk_stack_push(TSK_STACK * stack, uint64_t key);
170     extern void tsk_stack_pop(TSK_STACK * stack);
171     extern uint8_t tsk_stack_find(TSK_STACK * stack, uint64_t key);
172     extern void tsk_stack_free(TSK_STACK * stack);
173     extern TSK_STACK *tsk_stack_create();
174 
175 
176     // print internal UTF-8 strings to local platform Unicode format
177     extern void tsk_fprintf(FILE * fd, const char *msg, ...);
178     extern void tsk_printf(const char *msg, ...);
179 
180     // print path removing special characters
181     extern int tsk_print_sanitized(FILE * fd, const char *str);
182 
183 
184 /** \name printf macros if system does not define them */
185 //@{
186 #ifndef PRIx64
187 #define PRIx64 "llx"
188 #endif
189 
190 #ifndef PRIX64
191 #define PRIX64 "llX"
192 #endif
193 
194 #ifndef PRIu64
195 #define PRIu64 "llu"
196 #endif
197 
198 #ifndef PRId64
199 #define PRId64 "lld"
200 #endif
201 
202 #ifndef PRIo64
203 #define PRIo64 "llo"
204 #endif
205 
206 #ifndef PRIx32
207 #define PRIx32 "x"
208 #endif
209 
210 #ifndef PRIX32
211 #define PRIX32 "X"
212 #endif
213 
214 #ifndef PRIu32
215 #define PRIu32 "u"
216 #endif
217 
218 #ifndef PRId32
219 #define PRId32 "d"
220 #endif
221 
222 #ifndef PRIx16
223 #define PRIx16 "hx"
224 #endif
225 
226 #ifndef PRIX16
227 #define PRIX16 "hX"
228 #endif
229 
230 #ifndef PRIu16
231 #define PRIu16 "hu"
232 #endif
233 
234 #ifndef PRIu8
235 #define PRIu8 "hhu"
236 #endif
237 
238 #ifndef PRIx8
239 #define PRIx8 "hhx"
240 #endif
241 //@}
242 
243 
244 
245 /** @name  Internal integer types and printf macros*/
246 //@{
247     typedef uint64_t TSK_INUM_T;        ///< Data type used to internally store metadata / inode addresses
248 #define PRIuINUM	PRIu64
249 #define PRIxINUM	PRIx64
250 
251     typedef uint32_t TSK_UID_T; ///< Data type used to internally store User IDs
252 #define PRIuUID	    PRIu32
253 #define PRIxUID	    PRIx32
254 
255     typedef uint32_t TSK_GID_T; ///< Data type used to internally store Group IDs
256 #define PRIuGID	    PRIu32
257 #define PRIxGID	    PRIx32
258 
259     typedef uint64_t TSK_DADDR_T;       ///< Data type used to internally store sector and block addresses
260 #define PRIuDADDR   PRIu64
261 #define PRIxDADDR   PRIx64
262 
263     typedef int64_t TSK_OFF_T;  ///< Data type used to internally store volume, file, etc. sizes and offsets
264 #define PRIxOFF		PRIx64
265 #define PRIdOFF		PRId64
266 
267     typedef uint32_t TSK_PNUM_T;        ///< Data type used to internally store partition addresses
268 #define PRIuPNUM	PRIu32
269 #define PRIxPNUM	PRIx32
270 //@}
271 
272 
273     extern void tsk_version_print(FILE *);
274     extern const char *tsk_version_get_str();
275 
276 
277 /*********** RETURN VALUES ************/
278 
279 /**
280  * Values that callback functions can return to calling walk function.
281  */
282     typedef enum {
283         TSK_WALK_CONT = 0x0,    ///< Walk function should continue to next object
284         TSK_WALK_STOP = 0x1,    ///< Walk function should stop processing units and return OK
285         TSK_WALK_ERROR = 0x2   ///< Walk function should stop processing units and return error
286     } TSK_WALK_RET_ENUM;
287 
288 
289 /************ ERROR HANDLING *************/
290     //TODO: make this per-thread?
291     extern int tsk_verbose;     ///< Set to 1 to have verbose debug messages printed to stderr
292 
293 
294 #define TSK_ERR_AUX	0x01000000
295 #define TSK_ERR_IMG	0x02000000
296 #define TSK_ERR_VS	0x04000000
297 #define TSK_ERR_FS	0x08000000
298 #define TSK_ERR_HDB	0x10000000
299 #define TSK_ERR_AUTO 0x20000000
300 #define TSK_ERR_MASK	0x00ffffff
301 
302 #define TSK_ERR_AUX_MALLOC	(TSK_ERR_AUX | 0)
303 #define TSK_ERR_AUX_GENERIC (TSK_ERR_AUX | 2)
304 #define TSK_ERR_AUX_MAX		2
305 
306 #define TSK_ERR_IMG_NOFILE	(TSK_ERR_IMG | 0)
307 #define TSK_ERR_IMG_OFFSET	(TSK_ERR_IMG | 1)
308 #define TSK_ERR_IMG_UNKTYPE	(TSK_ERR_IMG | 2)
309 #define TSK_ERR_IMG_UNSUPTYPE 	(TSK_ERR_IMG | 3)
310 #define TSK_ERR_IMG_OPEN 	(TSK_ERR_IMG | 4)
311 #define TSK_ERR_IMG_STAT	(TSK_ERR_IMG | 5)
312 #define TSK_ERR_IMG_SEEK	(TSK_ERR_IMG | 6)
313 #define TSK_ERR_IMG_READ	(TSK_ERR_IMG | 7)
314 #define TSK_ERR_IMG_READ_OFF	(TSK_ERR_IMG | 8)
315 #define TSK_ERR_IMG_ARG	    (TSK_ERR_IMG | 9)
316 #define TSK_ERR_IMG_MAGIC	(TSK_ERR_IMG | 10)
317 #define TSK_ERR_IMG_WRITE	(TSK_ERR_IMG | 11)
318 #define TSK_ERR_IMG_CONVERT	(TSK_ERR_IMG | 12)
319 #define TSK_ERR_IMG_PASSWD	(TSK_ERR_IMG | 13)
320 #define TSK_ERR_IMG_MAX		14
321 
322 #define TSK_ERR_VS_UNKTYPE	(TSK_ERR_VS | 0)
323 #define TSK_ERR_VS_UNSUPTYPE	(TSK_ERR_VS | 1)
324 #define TSK_ERR_VS_READ		(TSK_ERR_VS | 2)
325 #define TSK_ERR_VS_MAGIC	(TSK_ERR_VS | 3)
326 #define TSK_ERR_VS_WALK_RNG	(TSK_ERR_VS | 4)
327 #define TSK_ERR_VS_BUF		(TSK_ERR_VS | 5)
328 #define TSK_ERR_VS_BLK_NUM	(TSK_ERR_VS | 6)
329 #define TSK_ERR_VS_ARG	    (TSK_ERR_VS | 7)
330 #define TSK_ERR_VS_MAX		8
331 
332 #define TSK_ERR_FS_UNKTYPE	(TSK_ERR_FS | 0)
333 #define TSK_ERR_FS_UNSUPTYPE	(TSK_ERR_FS | 1)
334 #define TSK_ERR_FS_UNSUPFUNC		(TSK_ERR_FS | 2)
335 #define TSK_ERR_FS_WALK_RNG	(TSK_ERR_FS | 3)
336 #define TSK_ERR_FS_READ		(TSK_ERR_FS | 4)
337 #define TSK_ERR_FS_READ_OFF	(TSK_ERR_FS | 5)
338 #define TSK_ERR_FS_ARG		(TSK_ERR_FS | 6)
339 #define TSK_ERR_FS_BLK_NUM	(TSK_ERR_FS | 7)
340 #define TSK_ERR_FS_INODE_NUM	(TSK_ERR_FS | 8)
341 #define TSK_ERR_FS_INODE_COR	(TSK_ERR_FS | 9)
342 #define TSK_ERR_FS_MAGIC	(TSK_ERR_FS | 10)
343 #define TSK_ERR_FS_FWALK	(TSK_ERR_FS | 11)
344 #define TSK_ERR_FS_WRITE	(TSK_ERR_FS | 12)
345 #define TSK_ERR_FS_UNICODE	(TSK_ERR_FS | 13)
346 #define TSK_ERR_FS_RECOVER	(TSK_ERR_FS | 14)
347 #define TSK_ERR_FS_GENFS	(TSK_ERR_FS | 15)
348 #define TSK_ERR_FS_CORRUPT	(TSK_ERR_FS | 16)
349 #define TSK_ERR_FS_ATTR_NOTFOUND (TSK_ERR_FS | 17)
350 #define TSK_ERR_FS_MAX		18
351 
352 
353 #define TSK_ERR_HDB_UNKTYPE     (TSK_ERR_HDB | 0)
354 #define TSK_ERR_HDB_UNSUPTYPE   (TSK_ERR_HDB | 1)
355 #define TSK_ERR_HDB_READDB	(TSK_ERR_HDB | 2)
356 #define TSK_ERR_HDB_READIDX	(TSK_ERR_HDB | 3)
357 #define TSK_ERR_HDB_ARG		(TSK_ERR_HDB | 4)
358 #define TSK_ERR_HDB_WRITE	(TSK_ERR_HDB | 5)
359 #define TSK_ERR_HDB_CREATE	(TSK_ERR_HDB | 6)
360 #define TSK_ERR_HDB_DELETE      (TSK_ERR_HDB | 7)
361 #define TSK_ERR_HDB_MISSING     (TSK_ERR_HDB | 8)
362 #define TSK_ERR_HDB_PROC        (TSK_ERR_HDB | 9)
363 #define TSK_ERR_HDB_OPEN        (TSK_ERR_HDB | 10)
364 #define TSK_ERR_HDB_CORRUPT     (TSK_ERR_HDB | 11)
365 #define TSK_ERR_HDB_UNSUPFUNC     (TSK_ERR_HDB | 11)
366 #define TSK_ERR_HDB_MAX		13
367 
368 #define TSK_ERR_AUTO_DB (TSK_ERR_AUTO | 0)
369 #define TSK_ERR_AUTO_CORRUPT (TSK_ERR_AUTO | 1)
370 #define TSK_ERR_AUTO_UNICODE (TSK_ERR_AUTO | 2)
371 #define TSK_ERR_AUTO_NOTOPEN (TSK_ERR_AUTO | 3)
372 #define TSK_ERR_AUTO_MAX 4
373 //@}
374 
375 
376 /** \name Endian Ordering Functions */
377 //@{
378     /**
379      * Flag that identifies the endian ordering of the data being read.
380      */
381     typedef enum {
382         TSK_UNKNOWN_ENDIAN = 0x00, ///< Endianness is unknown
383         TSK_LIT_ENDIAN = 0x01,  ///< Data is in little endian
384         TSK_BIG_ENDIAN = 0x02   ///< Data is in big endian
385     } TSK_ENDIAN_ENUM;
386 
387 //@}
388 
389 
390 
391     extern TSK_OFF_T tsk_parse_offset(const TSK_TCHAR *);
392     extern int tsk_parse_pnum(const TSK_TCHAR * a_pnum_str,
393         TSK_PNUM_T * a_pnum);
394 
395 
396 
397 /** \name MD5 and SHA-1 hashing */
398 //@{
399 
400 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
401 rights reserved.
402 
403 License to copy and use this software is granted provided that it
404 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
405 Algorithm" in all material mentioning or referencing this software
406 or this function.
407 
408 License is also granted to make and use derivative works provided
409 that such works are identified as "derived from the RSA Data
410 Security, Inc. MD5 Message-Digest Algorithm" in all material
411 mentioning or referencing the derived work.
412 
413 RSA Data Security, Inc. makes no representations concerning either
414 the merchantability of this software or the suitability of this
415 software for any particular purpose. It is provided "as is"
416 without express or implied warranty of any kind.
417 
418 These notices must be retained in any copies of any part of this
419 documentation and/or software.
420  */
421 
422 
423 /* POINTER defines a generic pointer type */
424     typedef unsigned char *POINTER;
425 
426 /* UINT2 defines a two byte word */
427 //typedef unsigned short int UINT2;
428     typedef uint16_t UINT2;
429 
430 /* UINT4 defines a four byte word */
431     typedef uint32_t UINT4;
432 
433 /* Added for sha1 */
434 /* BYTE defines a unsigned character */
435     typedef uint8_t BYTE;
436 
437 #ifndef TRUE
438 #define FALSE 0
439 #define TRUE  ( !FALSE )
440 #endif                          /* TRUE */
441 
442 
443 
444 /* MD5 context. */
445 #define TSK_MD5_DIGEST_LENGTH 16
446     typedef struct {
447         UINT4 state[4];         /* state (ABCD) */
448         UINT4 count[2];         /* number of bits, modulo 2^64 (lsb first) */
449         unsigned char buffer[64];       /* input buffer */
450     } TSK_MD5_CTX;
451 
452     void TSK_MD5_Init(TSK_MD5_CTX *);
453     void TSK_MD5_Update(TSK_MD5_CTX *, unsigned char *, unsigned int);
454     void TSK_MD5_Final(unsigned char[16], TSK_MD5_CTX *);
455 
456 
457 
458 /* sha.h */
459 
460 /* The structure for storing SHS info */
461 #define TSK_SHA_DIGEST_LENGTH 32
462     typedef struct {
463         UINT4 digest[5];        /* Message digest */
464         UINT4 countLo, countHi; /* 64-bit bit count */
465         UINT4 data[16];         /* SHS data buffer */
466         int Endianness;
467     } TSK_SHA_CTX;
468 
469 /* Message digest functions */
470 
471     void TSK_SHA_Init(TSK_SHA_CTX *);
472     void TSK_SHA_Update(TSK_SHA_CTX *, BYTE * buffer, int count);
473     void TSK_SHA_Final(BYTE * output, TSK_SHA_CTX *);
474 
475 /* Flags for which type of hash(es) to run */
476 	typedef enum{
477 		TSK_BASE_HASH_INVALID_ID = 0,
478 		TSK_BASE_HASH_MD5 = 0x01,
479 		TSK_BASE_HASH_SHA1 = 0x02
480 		//TSK_BASE_HASH_SHA256 = 0x04,
481 	} TSK_BASE_HASH_ENUM;
482 
483 
484 //@}
485 
486 #ifdef __cplusplus
487 }
488 #endif
489 #ifdef __cplusplus
490 #if 0
491 class TskStack {
492   private:
493     TSK_STACK * m_stack;
494 
495   public:
496     /**
497     * Create a TSK_STACK structure. See tsk_stack_create() for details.
498     * @returns Pointer to structure or NULL on error
499     */
500     TskStack() {
501         m_stack = tsk_stack_create();
502     };
503    /**
504    * Free an allocated TSK_STACK structure. See tsk_stack_free() for details.
505    */
506     ~TskStack() {
507         tsk_stack_free(m_stack);
508     };
509     /**
510     * Pop a value from the top of the stack. See tsk_stack_pop() for details.
511     */
512     void pop() {
513         tsk_stack_pop(m_stack);
514     };
515     /**
516     * Push a value to the top of TSK_STACK. See tsk_stack_push() for details.
517     * @param a_val Value to push on
518     * @returns 1 on error
519     */
520     uint8_t push(uint64_t a_val) {
521         return tsk_stack_push(m_stack, a_val);
522     };
523     /**
524     * Search a TSK_STACK for a given value. See tsk_stack_find() for details.
525     * @param a_val Value to search for
526     * @returns 1 if found and 0 if not
527     */
528     uint8_t find(uint64_t a_val) {
529         return tsk_stack_find(m_stack, a_val);
530     };
531      /**
532     * Return Number of entries in the stack
533     * @returns number of entries in the stack
534     */
535     size_t length() {
536         if (m_stack != NULL)
537             return m_stack->len;
538         else
539             return 0;
540     };
541 };
542 #endif
543 
544 /**
545  * \ingroup baselib_cpp
546  * Allows access to most recent error message and code in the thread.
547  */
548 class TskError {
549   public:
550     /**
551     * Return the string with the current error message.  The string does not end with a
552     * newline. See tsk_error_get() for details.
553     *
554     * @returns String with error message or NULL if there is no error
555     */
get()556     static const char *get() {
557         return tsk_error_get();
558     };
559 
560    /**
561    * Print the current error message to a file. See tsk_error_print() for details.
562    *
563    * @param a_hFile File to print message to
564    */
print(FILE * a_hFile)565     static void print(FILE * a_hFile) {
566         tsk_error_print(a_hFile);
567     };
568 
569     /**
570     * Clear the error number and error message. See tsk_error_reset() for details.
571     */
reset()572     static void reset() {
573         tsk_error_reset();
574     };
575 };
576 
577 #endif
578 #endif
579