File: mm_open.c

package info (click to toggle)
sleuthkit 4.11.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 18,388 kB
  • sloc: ansic: 143,074; cpp: 33,286; java: 32,933; sh: 4,342; xml: 2,197; makefile: 436; python: 270
file content (236 lines) | stat: -rw-r--r-- 7,521 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
 * The Sleuth Kit
 *
 * Brian Carrier [carrier <at> sleuthkit [dot] org]
 * Copyright (c) 2003-2011 Brian Carrier.  All rights reserved
 *
 * tsk_vs_open - wrapper function for specific partition type
 *
 * This software is distributed under the Common Public License 1.0
 */

/**
 * \file mm_open.c
 * Contains general code to open volume systems.
 */

#include "tsk_vs_i.h"
#include "tsk/util/detect_encryption.h"


/**
 * \ingroup vslib
 *
 * Open a disk image and process the media management system
 * data.  This calls VS specific code to determine the type and
 * collect data. 
 *
 * @param img_info The opened disk image.
 * @param offset Byte offset in the disk image to start analyzing from.
 * @param type Type of volume system (including auto detect)
 *
 * @return NULL on error. 
 */
TSK_VS_INFO *
tsk_vs_open(TSK_IMG_INFO * img_info, TSK_DADDR_T offset,
    TSK_VS_TYPE_ENUM type)
{
    if (img_info == NULL) {
        /* Opening the image file(s) failed, if attempted. */
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_IMG_NOFILE);
        tsk_error_set_errstr("mm_open");
        return NULL;
    }

    /* Autodetect mode 
     * We need to try all of them in case there are multiple 
     * installations
     *
     * NOte that errors that are encountered during the testing process
     * will not be reported
     */
    if (type == TSK_VS_TYPE_DETECT) {
        TSK_VS_INFO *vs, *vs_set = NULL;
        char *set = NULL;

        if ((vs = tsk_vs_dos_open(img_info, offset, 1)) != NULL) {
            set = "DOS";
            vs_set = vs;
        }
        else {
            tsk_error_reset();
        }
        if ((vs = tsk_vs_bsd_open(img_info, offset)) != NULL) {
            // if (set == NULL) {
            // In this case, BSD takes priority because BSD partitions start off with
            // the DOS magic value in the first sector with the boot code.
            set = "BSD";
            vs_set = vs;
            /*
               }
               else {
               vs_set->close(vs_set);
               vs->close(vs);
               tsk_error_reset();
               tsk_error_set_errno(TSK_ERR_VS_UNKTYPE);
               tsk_error_set_errstr(
               "BSD or %s at %" PRIuDADDR, set, offset);
               tsk_errstr2[0] = '\0';
               return NULL;
               }
             */
        }
        else {
            tsk_error_reset();
        }
        if ((vs = tsk_vs_gpt_open(img_info, offset)) != NULL) {

            if ((set != NULL) && (strcmp(set, "DOS") == 0) && (vs->is_backup)) {
                /* In this case we've found a DOS partition and a backup GPT partition.
                 * The DOS partition takes priority in this case (and are already in set and vs_set) */
                vs->close(vs);
                if (tsk_verbose)
                    tsk_fprintf(stderr,
                        "mm_open: Ignoring secondary GPT Partition\n");
            }
            else {
                if (set != NULL) {

                    /* GPT drives have a DOS Safety partition table.
                     * Test to see if we can ignore one */
                    if (strcmp(set, "DOS") == 0) {
                        TSK_VS_PART_INFO *tmp_set;
                        for (tmp_set = vs_set->part_list; tmp_set;
                            tmp_set = tmp_set->next) {
                            if ((tmp_set->desc)
                                && (strncmp(tmp_set->desc, "GPT Safety",
                                    10) == 0)
                                && (tmp_set->start <= 63)) {

                                if (tsk_verbose)
                                    tsk_fprintf(stderr,
                                        "mm_open: Ignoring DOS Safety GPT Partition\n");
                                set = NULL;
                                vs_set = NULL;
                                break;
                            }
                        }
                    }

                    if (set != NULL) {
                        vs_set->close(vs_set);
                        vs->close(vs);
                        tsk_error_reset();
                        tsk_error_set_errno(TSK_ERR_VS_UNKTYPE);
                        tsk_error_set_errstr("GPT or %s at %" PRIuDADDR, set,
                            offset);
                        return NULL;
                    }
                }
                set = "GPT";
                vs_set = vs;
            }
        }
        else {
            tsk_error_reset();
        }

        if ((vs = tsk_vs_sun_open(img_info, offset)) != NULL) {
            if (set == NULL) {
                set = "Sun";
                vs_set = vs;
            }
            else {
                vs_set->close(vs_set);
                vs->close(vs);
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_VS_UNKTYPE);
                tsk_error_set_errstr("Sun or %s at %" PRIuDADDR, set,
                    offset);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }

        if ((vs = tsk_vs_mac_open(img_info, offset)) != NULL) {
            if (set == NULL) {
                set = "Mac";
                vs_set = vs;
            }
            else {
                vs_set->close(vs_set);
                vs->close(vs);
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_VS_UNKTYPE);
                tsk_error_set_errstr("Mac or %s at %" PRIuDADDR, set,
                    offset);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }

        if (vs_set == NULL) {
            tsk_error_reset();

            // Check whether the volume system appears to be encrypted.
            // Note that detectDiskEncryption does not do an entropy calculation - high entropy 
            // files will be reported by tsk_fs_open_img().
            encryption_detected_result* result = detectDiskEncryption(img_info, offset);
            if (result != NULL) {
                if (result->encryptionType == ENCRYPTION_DETECTED_SIGNATURE) {
                    tsk_error_set_errno(TSK_ERR_VS_ENCRYPTED);
                    tsk_error_set_errstr("%s", result->desc);
                }
                free(result);
                result = NULL;
            }
            else {
                tsk_error_set_errno(TSK_ERR_VS_UNKTYPE);
            }
            return NULL;
        }

        return vs_set;
    }
    else {

        switch (type) {
        case TSK_VS_TYPE_DOS:
            return tsk_vs_dos_open(img_info, offset, 0);
        case TSK_VS_TYPE_MAC:
            return tsk_vs_mac_open(img_info, offset);
        case TSK_VS_TYPE_BSD:
            return tsk_vs_bsd_open(img_info, offset);
        case TSK_VS_TYPE_SUN:
            return tsk_vs_sun_open(img_info, offset);
        case TSK_VS_TYPE_GPT:
            return tsk_vs_gpt_open(img_info, offset);
        case TSK_VS_TYPE_APFS: // Not supported yet
        case TSK_VS_TYPE_UNSUPP:
        default:
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_VS_UNSUPTYPE);
            tsk_error_set_errstr("%d", type);
            return NULL;
        }
    }
}

/**
 * \ingroup vslib
 * Closes an open volume system 
 * @param a_vs Pointer to the open volume system structure.
 */
void
tsk_vs_close(TSK_VS_INFO * a_vs)
{
    if (a_vs == NULL) {
        return;
    }
    a_vs->close((TSK_VS_INFO *) a_vs);
}