00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef lint
00034 static char copyright[] =
00035 "@(#) Copyright (c) 2002-2004\n\
00036 Netherlands Forensic Institute. All rights reserved.\n";
00037 #endif
00038
00039 #ifdef HAVE_CONFIG_H
00040 #include <config.h>
00041 #endif
00042
00043 #include <errno.h>
00044 #include <fcntl.h>
00045 #include <stdarg.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048 #include <unistd.h>
00049 #include <sys/stat.h>
00050
00051 #include "rdd.h"
00052 #include "writer.h"
00053
00054 #include "libewf.h"
00055
00056
00057
00058
00059
00060 static int ewf_write(RDD_WRITER *w, const unsigned char *buf, unsigned nbyte);
00061 static int ewf_close(RDD_WRITER *w);
00062 static int ewf_compare_address(RDD_WRITER *w, struct addrinfo *address, int *result);
00063
00064 static RDD_WRITE_OPS ewf_write_ops = {
00065 ewf_write,
00066 ewf_close,
00067 ewf_compare_address
00068 };
00069
00070 typedef struct _RDD_EWF_WRITER {
00071 char *path;
00072 libewf_handle_t * ewf_handle;
00073 RDD_HASH_CONTAINER * hashcontainer;
00074 int write_called;
00075 } RDD_EWF_WRITER;
00076
00077
00078
00079
00080
00081 static int
00082 path_exists(const char *path, struct stat *info)
00083 {
00084 return stat(path, info) != -1 || errno != ENOENT;
00085 }
00086
00087 static int
00088 compress_level(int compression_type)
00089 {
00090
00091 if(compression_type != 3){
00092 return compression_type;
00093 }
00094 return 0;
00095 }
00096
00097 static int
00098 compress_empty_block(int compression_type)
00099 {
00100 if(compression_type == 3){
00101 return 0x01;
00102 }
00103 return 0x00;
00104 }
00105
00106
00107
00108
00109 int
00110 rdd_open_ewf_writer(RDD_WRITER **self, const char *path,
00111 rdd_count_t splitlen, int compression_type, rdd_write_mode_t wmode, RDD_HASH_CONTAINER * hashcontainer)
00112 {
00113 RDD_WRITER *w = 0;
00114 RDD_EWF_WRITER *state = 0;
00115 struct stat statinfo;
00116 int rc = RDD_OK;
00117 char *pathcopy = 0;
00118 char *pathcopy_without_extension = 0;
00119 uint8_t flags = libewf_get_flags_write();
00120 const char * EWF_EXTENSION = ".E01";
00121 int8_t compression_level = LIBEWF_COMPRESSION_NONE;
00122 uint8_t empty_block_compression = 0;
00123
00124 int corrected_compression_type = compression_type -1;
00125
00126
00127 if (self == 0) {
00128 rc = RDD_BADARG;
00129 return rc;
00130 }
00131
00132 if (path == 0) {
00133 rc = RDD_BADARG;
00134 goto error;
00135 }
00136
00137 if(corrected_compression_type < 0 || corrected_compression_type > 3){
00138 rc = RDD_BADARG;
00139 goto error;
00140 }
00141
00142 if (hashcontainer == 0) {
00143 rc = RDD_BADARG;
00144 goto error;
00145 }
00146
00147 if (splitlen != 0 && splitlen < RDD_EWF_MIN_SPLITLEN) {
00148 rc = RDD_BADARG;
00149 goto error;
00150 }
00151
00152 compression_level = compress_level(corrected_compression_type);
00153 empty_block_compression = compress_empty_block(corrected_compression_type);
00154
00155 int pathsize_without_extension = strlen(path) + 1;
00156 int pathsize = pathsize_without_extension + strlen(EWF_EXTENSION);
00157 if ((pathcopy = malloc(pathsize)) == 0) {
00158 rc = RDD_NOMEM;
00159 goto error;
00160 }
00161
00162 if (snprintf(pathcopy, pathsize, "%s%s", path, EWF_EXTENSION) > pathsize - 1) {
00163
00164 rc = RDD_EOPEN;
00165 goto error;
00166 }
00167
00168 if (wmode == RDD_NO_OVERWRITE && path_exists(pathcopy, &statinfo)) {
00169 rc = RDD_EEXISTS;
00170 goto error;
00171 }
00172
00173 rc = rdd_new_writer(&w, &ewf_write_ops, sizeof(RDD_EWF_WRITER));
00174 if (rc != RDD_OK) {
00175 goto error;
00176 }
00177 state = (RDD_EWF_WRITER *) w->state;
00178
00179 state->write_called = 0;
00180 state->path = pathcopy;
00181
00182
00183
00184 state->hashcontainer = hashcontainer;
00185
00186 libewf_error_t *err = 0;
00187
00188 if (libewf_handle_initialize(&state->ewf_handle, &err) == -1)
00189 {
00190 libewf_error_free(&err);
00191 rc = RDD_EOPEN;
00192 goto error;
00193 }
00194
00195 if (state->ewf_handle == 0) {
00196 libewf_error_free(&err);
00197 rc = RDD_EOPEN;
00198 goto error;
00199 }
00200
00201 if ((pathcopy_without_extension = malloc(pathsize_without_extension)) == 0) {
00202 rc = RDD_NOMEM;
00203 goto error;
00204 }
00205 strcpy(pathcopy_without_extension, path);
00206 char * filenames[1];
00207 filenames[0] = pathcopy_without_extension;
00208
00209 if (libewf_handle_open(state->ewf_handle, filenames, 1, flags, &err) == -1)
00210 {
00211 libewf_error_free(&err);
00212 free(pathcopy_without_extension);
00213 rc = RDD_EOPEN;
00214 goto error;
00215 }
00216 free(pathcopy_without_extension);
00217
00218
00219 if (libewf_handle_set_format(state->ewf_handle, LIBEWF_FORMAT_ENCASE6, &err) == -1)
00220 {
00221 libewf_error_free(&err);
00222 rc = RDD_EOPEN;
00223 goto error;
00224 }
00225
00226 if (libewf_handle_set_media_type(state->ewf_handle, LIBEWF_MEDIA_TYPE_FIXED, &err) == -1)
00227 {
00228 libewf_error_free(&err);
00229 rc = RDD_EOPEN;
00230 goto error;
00231 }
00232
00233 if (libewf_handle_set_media_flags(state->ewf_handle, LIBEWF_MEDIA_FLAG_PHYSICAL, &err) == -1)
00234 {
00235 libewf_error_free(&err);
00236 rc = RDD_EOPEN;
00237 goto error;
00238 }
00239
00240 if (libewf_handle_set_compression_values(state->ewf_handle, compression_level, empty_block_compression, &err) == -1)
00241 {
00242 libewf_error_free(&err);
00243 rc = RDD_EOPEN;
00244 goto error;
00245 }
00246
00247 if (splitlen > 0) {
00248 if (libewf_handle_set_segment_file_size(state->ewf_handle, splitlen, &err) == -1)
00249 {
00250 libewf_error_free(&err);
00251 rc = RDD_EOPEN;
00252 goto error;
00253 }
00254 }
00255
00256 *self = w;
00257
00258 return RDD_OK;
00259
00260 error:
00261
00262
00263 *self = 0;
00264 if (pathcopy != 0) free(pathcopy);
00265 if (state != 0) {
00266 if (state->ewf_handle != 0) {
00267 libewf_handle_close(state->ewf_handle, &err);
00268 libewf_handle_free(&state->ewf_handle, &err);
00269 }
00270 free(state);
00271 }
00272
00273 if (w != 0) free(w);
00274 return rc;
00275 }
00276
00277 static int
00278 ewf_write(RDD_WRITER *w, const unsigned char *buf, unsigned nbyte)
00279 {
00280
00281
00282 RDD_EWF_WRITER *state = w->state;
00283
00284 libewf_error_t *err = 0;
00285
00286 if (libewf_handle_write_buffer(state->ewf_handle, (void *)buf, nbyte, &err) == -1)
00287 {
00288 libewf_error_free(&err);
00289 return RDD_EWRITE;
00290 }
00291 if (nbyte > 0) {
00292 state->write_called = 1;
00293 }
00294 return RDD_OK;
00295 }
00296
00297 static int
00298 ewf_close(RDD_WRITER *self)
00299 {
00300 int rc = RDD_OK;
00301
00302 libewf_error_t *err = 0;
00303
00304 if (self == 0) {
00305 return RDD_BADARG;
00306 }
00307 RDD_EWF_WRITER *state = self->state;
00308
00309 uint8_t hashValue[RDD_MAX_DIGEST_LENGTH];
00310 memset(hashValue, 0, RDD_MAX_DIGEST_LENGTH);
00311 int present = 0;
00312
00313
00314 if (rdd_hash_present(state->hashcontainer, RDD_MD5, &present) == RDD_OK) {
00315 if (present) {
00316 if (rdd_get_hash(state->hashcontainer, RDD_MD5, hashValue) == RDD_OK) {
00317 if (libewf_handle_set_md5_hash(state->ewf_handle, hashValue, MD5_DIGEST_LENGTH, &err) == -1) {
00318 libewf_error_free(&err);
00319 rc = RDD_ECLOSE;
00320 }
00321 }
00322 }
00323 } else {
00324 rc = RDD_ECLOSE;
00325 }
00326
00327 if (rdd_hash_present(state->hashcontainer, RDD_SHA1, &present) == RDD_OK) {
00328 if (present) {
00329 if (rdd_get_hash(state->hashcontainer, RDD_SHA1, hashValue) == RDD_OK) {
00330 if (libewf_handle_set_sha1_hash(state->ewf_handle, hashValue, SHA_DIGEST_LENGTH, &err) == -1) {
00331 libewf_error_free(&err);
00332 rc = RDD_ECLOSE;
00333 }
00334 } else {
00335 rc = RDD_ECLOSE;
00336 }
00337 }
00338 } else {
00339 rc = RDD_ECLOSE;
00340 }
00341
00342
00343
00344 if (libewf_handle_write_finalize(state->ewf_handle, &err) == -1)
00345 {
00346 libewf_error_free(&err);
00347 rc = RDD_ECLOSE;
00348 }
00349
00350 if (libewf_handle_close(state->ewf_handle, &err) == -1)
00351 {
00352 libewf_error_free(&err);
00353 rc = RDD_ECLOSE;
00354 }
00355
00356 if (libewf_handle_free(&state->ewf_handle, &err) == -1)
00357 {
00358 libewf_error_free(&err);
00359 rc = RDD_ECLOSE;
00360 }
00361
00362
00363 if (state->write_called) {
00364 struct stat statinfo;
00365 if (stat(state->path, &statinfo) < 0) {
00366 return RDD_ECLOSE;
00367 }
00368
00369 if (S_ISREG(statinfo.st_mode)
00370 && chmod(state->path, S_IRUSR|S_IRGRP|S_IROTH) < 0) {
00371
00372
00373
00374 }
00375 }
00376
00377 free(state->path);
00378 state->path = 0;
00379
00380 return rc;
00381 }
00382
00383 static int
00384 ewf_compare_address(RDD_WRITER *self, struct addrinfo *address, int *result)
00385 {
00386
00387 if (self == 0) {
00388 return RDD_BADARG;
00389 }
00390 if (result == 0) {
00391 return RDD_BADARG;
00392 }
00393
00394 *result = (address == 0);
00395 return RDD_OK;
00396 }