[Forensics-changes] [dislocker] 01/02: Import Upstream version 0.7.1

Giovani Augusto Ferreira giovani at moszumanska.debian.org
Tue Aug 29 03:14:44 UTC 2017


This is an automated email from the git hooks/post-receive script.

giovani pushed a commit to branch debian
in repository dislocker.

commit 9449a386002338c73e1440f39d286b7fb3a11d27
Author: Giovani Augusto Ferreira <giovani at debian.org>
Date:   Tue Aug 29 00:14:05 2017 -0300

    Import Upstream version 0.7.1
---
 .travis.yml                 |   6 +-
 CHANGELOG.md                |  18 ++-
 CMakeLists.txt              |   4 +-
 INSTALL.md                  |  36 +++--
 README.md                   |  29 +++--
 cmake/FindFUSE.cmake        |  34 +++++
 cmake/FindPolarSSL.cmake    |  40 ++++--
 include/dislocker/config.h  |   2 +
 man/darwin/dislocker-file.1 |   8 +-
 man/darwin/dislocker-fuse.1 |  16 +--
 man/linux/dislocker-file.1  |   8 +-
 man/linux/dislocker-find.1  |   6 +-
 man/linux/dislocker-fuse.1  |  16 +--
 src/CMakeLists.txt          |  39 ++++--
 src/common.c                |  69 +++++++++-
 src/config.c                | 310 ++++++++++++++++++++++++++++++++++++++------
 src/dislocker-fuse.c        |  21 ++-
 src/dislocker.bb            |  32 +++++
 src/dislocker.c             |   8 +-
 src/dislocker.rb            |  11 +-
 src/mbed_install.sh         |   2 +-
 src/metadata/metadata.c     |   6 +
 22 files changed, 587 insertions(+), 134 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 6f81f1d..1ff8f5a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,11 +8,15 @@ os:
     - linux
     - osx
 
+env:
+    global:
+        - PATH="/usr/bin:/usr/local/bin:$PATH"
+
 before_install:
     - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq; fi
     - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get install -qq libfuse-dev libpolarssl-dev ruby-dev; fi
     - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi
-    - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install -v osxfuse; fi
+    - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install -v Caskroom/cask/osxfuse; fi
     - if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./src/mbed_install.sh; fi
 
 install:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d9c666..7b4e05b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+# v0.7.1
+This version is only used to update dislocker's brew file and the BitBake recipe
+for OSX's and BitBake's users to be able to download v0.7. If you're not an OSX
+nor a BitBake user, you can use either v0.7 or v0.7.1, this won't make any
+difference.
+
+# v0.7
+- Feature improvement:
+    - dislocker can now be run from /etc/fstab. This also means that the `-o`
+    option for the offset had to be changed. It is now `-O`;
+    - dislocker on FreeBSD can now read devices, not just partition dumps.
+
+- Compatiblity improvement:
+    - OSX support and dependencies have been updated;
+    - Thanks to Eric Johnson, from Leidos, a BitBake recipe is now available.
+
 # v0.6.1
 This version is only used to update dislocker's brew file for OSX users
 to be able to download v0.6. If you're not an OSX user, you can use either v0.6
@@ -5,7 +21,7 @@ or v0.6.1, this won't make any difference.
 
 # v0.6
 - Features improvement:
-    - Read/write on Windows 10 (v1511) encrypted volumes.
+    - Read/write on Windows 10 (v1511) encrypted volumes - AES-XTS 128/256.
 
 # v0.5.2
 Minor fixes for downstream packaging and larger distribution coverage.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f445e0d..de27389 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,10 +27,12 @@ find_program (GIT_EXE NAMES git PATHS /usr/bin /usr/local/bin)
 if(GIT_EXE)
 	execute_process (
 		COMMAND ${GIT_EXE} rev-parse --abbrev-ref HEAD
+		WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
 		OUTPUT_VARIABLE GIT_RELEASE_BRANCH
 	)
 	execute_process (
 		COMMAND ${GIT_EXE} log -n 1 --pretty=format:%t
+		WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
 		OUTPUT_VARIABLE GIT_RELEASE_COMMIT
 	)
 	string (STRIP "${GIT_RELEASE_BRANCH}" GIT_RELEASE_BRANCH)
@@ -40,7 +42,7 @@ endif()
 
 
 set (VERSION_MAJOR 0)
-set (VERSION_MINOR 6)
+set (VERSION_MINOR 7)
 set (VERSION_RELEASE 1)
 set (VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}")
 
diff --git a/INSTALL.md b/INSTALL.md
index f343c71..cca6c05 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -10,34 +10,38 @@ You need:
 - cmake (at least version 2.6);
 - make (or gmake, for FreeBSD);
 - Headers for FUSE;
-- Headers for PolarSSL/mbedTLS;
+- Headers for mbedTLS (previously known as PolarSSL);
 - A partition encrypted with BitLocker, from Windows Vista, 7 or 8.
 
 
 If you have Ruby headers, the library will compile with some Ruby bindings and
 another program - see the NOTE section below - will be available.
 
-For Debian-like:
+For Debian-like distos based on Debian Jessie or Ubuntu 14.04 or older:
 
-- aptitude install gcc cmake make libfuse-dev libpolarssl-dev ruby-dev
+- `aptitude install gcc cmake make libfuse-dev libpolarssl-dev ruby-dev`
+
+For Debian-like distos based on Debian Stretch or Ubuntu 16.04 or later:
+
+- `aptitude install gcc cmake make libfuse-dev libmbedtls-dev ruby-dev`
 
 For Fedora-like:
 
-- dnf install gcc cmake make fuse-devel mbedtls-devel ruby-devel rubypick
+- `dnf install gcc cmake make fuse-devel mbedtls-devel ruby-devel rubypick`
 
-Alternatively, running "dnf install dislocker fuse-dislocker" to use the
+Alternatively, running `dnf install dislocker fuse-dislocker` to use the
 already existing RPM packages in Fedora could be a clever idea.
 
 For RHEL-like (including CentOS Scientific Linux):
 
-- yum install gcc cmake make fuse-devel mbedtls-devel ruby-devel /usr/bin/ruby
+- `yum install gcc cmake make fuse-devel mbedtls-devel ruby-devel /usr/bin/ruby`
 
-Alternatively, running "yum install dislocker fuse-dislocker" to use the
+Alternatively, running `yum install dislocker fuse-dislocker` to use the
 already existing RPM packages in EPEL could be a clever idea.
 
 For FreeBSD:
 
-- pkg install cmake gmake fusefs-libs polarssl
+- `pkg install cmake gmake fusefs-libs mbedtls`
 
 For OSX: Follow the instructions in the next section.
 
@@ -49,21 +53,14 @@ Each OS type has its own section below, beware to follow yours:
 
 ## If you are on MacOSX...
 
-Just install Homebrew (http://brew.sh/) and run the following command:
+Just install Homebrew (http://brew.sh/) and run the following commands:
 ```
 brew update
+brew install Caskroom/cask/osxfuse
 brew install src/dislocker.rb
 ```
 This will install dislocker.
 
-You may have to follow the 'mbedTLS 2.0.0' section below. If so, you will have
-to install OSXfuse and cmake through Homebrew first:
-```
-brew install osxfuse cmake
-```
-And once you have followed the 'mbedTLS 2.0.0' section's instructions, you can
-follow the steps below, in the 'If you are NOT on MacOSX...' point (even if you
-are on MacOSX).
 
 ## If you're on FreeBSD...
 
@@ -128,7 +125,7 @@ You can then resume the installation where you have left it.
 
 # PORTABILITY
 
-Globally, this was successfuly tested on Linux x86/x86_64, MacOSX and FreeBSD.
+Globally, this was successfully tested on Linux x86/x86_64, MacOSX and FreeBSD.
 It won't work on Windows and may not work on other BSDs (not tested).
 
 For MacOSX, it has been tested against OSXFUSE 2.3.8 and 2.3.9.
@@ -146,7 +143,8 @@ Whether it works or not, feel free to send comments and feedbacks to
 
 Five binaries are built when compiling dislocker as described in the `INSTALL.md`
 file:
-1. `dislocker-bek`: for disecting a .bek file and printing information about it
+
+1. `dislocker-bek`: for dissecting a .bek file and printing information about it
 
 2. `dislocker-metadata`: for printing information about a BitLocker-encrypted volume
 
diff --git a/README.md b/README.md
index a899f80..598c58e 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,11 @@
 
 
 This software has been designed to read BitLocker encrypted partitions under a
-Linux system. The driver used to only read volumes encrypted under a Windows 7
-system but see now its capabilities extended to:
- - Windows Vista, 7, 8, 8.1 and 10 encrypted partitions;
- - BitLocker-To-Go encrypted partitions - that's USB/FAT32 partitions;
- - be able to write on the above partitions.
+Linux system. The driver has the capability to read/write on:
+ - Windows Vista, 7, 8, 8.1 and 10 encrypted partitions - that's AES-CBC,
+   AES-XTS, 128 or 256 bits, with or without the Elephant diffuser, encrypted
+   partitions;
+ - BitLocker-To-Go encrypted partitions - that's USB/FAT32 partitions.
 
 The core driver is composed of a library, with multiple binaries (see the NOTES
 section below) using this library. Two binaries are of interest when wanting to
@@ -30,7 +30,7 @@ create that file, depending on the size of the encrypted partition. But
 afterward, once the partition is decrypted, the access to the NTFS partition
 will be faster. Another thing to think about is the size on your disk this
 binary needs: the same size as the volume you're trying to decrypt.
-Nethertheless, once the partition is decrypted, you can mount your file as any
+Nevertheless, once the partition is decrypted, you can mount your file as any
 NTFS partition.
 
 
@@ -50,7 +50,8 @@ Once installed, see `dislocker(1)` for details on how to use it.
 
 There may be bugs, and I'll be happy to hear about it!
 
-Feel free to send comments and feedbacks to [dislocker __AT__ hsc __DOT__ fr]().
+Feel free to send comments and feedbacks to [dislocker __AT__ hsc __DOT__ fr](),
+or to open an [issue](https://github.com/Aorimn/dislocker/issues).
 
 
 
@@ -74,11 +75,23 @@ whether the volume is a standard BitLocker partition or a BitLocker-To-Go one.
 
 
 
+## A note on fstab
+
+BitLocker partitions can be mount-ed using the /etc/fstab file and dislocker's
+long options.
+The line below is an example line, which has to be adapted to each case:
+```
+/dev/sda2 /mnt/dislocker fuse.dislocker user-password=blah,nofail 0 0
+```
+
+
+
 ## Note
 
 Five binaries are built when compiling dislocker as described in the `INSTALL.md`
 file:
-1. `dislocker-bek`: for disecting a .bek file and printing information about it
+
+1. `dislocker-bek`: for dissecting a .bek file and printing information about it
 
 2. `dislocker-metadata`: for printing information about a BitLocker-encrypted volume
 
diff --git a/cmake/FindFUSE.cmake b/cmake/FindFUSE.cmake
new file mode 100644
index 0000000..4f7acbd
--- /dev/null
+++ b/cmake/FindFUSE.cmake
@@ -0,0 +1,34 @@
+# Find the FUSE includes and library
+#
+#  FUSE_INCLUDE_DIRSS - where to find fuse.h, etc.
+#  FUSE_LIBRARIES   - List of libraries when using FUSE.
+#  FUSE_FOUND       - True if FUSE lib is found.
+
+# check if already in cache, be silent
+IF (FUSE_INCLUDE_DIRS)
+        SET (FUSE_FIND_QUIETLY TRUE)
+ENDIF (FUSE_INCLUDE_DIRS)
+
+# find includes
+FIND_PATH (FUSE_INCLUDE_DIRS fuse.h
+        /usr/local/include/osxfuse
+        /usr/local/include
+        /usr/include
+)
+
+# find lib
+if (APPLE)
+    SET(FUSE_NAMES libosxfuse.dylib fuse)
+else (APPLE)
+    SET(FUSE_NAMES fuse)
+endif (APPLE)
+FIND_LIBRARY(FUSE_LIBRARIES
+        NAMES ${FUSE_NAMES}
+        PATHS /lib64 /lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib
+)
+
+include ("FindPackageHandleStandardArgs")
+find_package_handle_standard_args ("FUSE" DEFAULT_MSG
+    FUSE_INCLUDE_DIRS FUSE_LIBRARIES)
+
+mark_as_advanced (FUSE_INCLUDE_DIRS FUSE_LIBRARIES)
diff --git a/cmake/FindPolarSSL.cmake b/cmake/FindPolarSSL.cmake
index effd794..49eeedb 100644
--- a/cmake/FindPolarSSL.cmake
+++ b/cmake/FindPolarSSL.cmake
@@ -49,20 +49,32 @@ if( ${POLARSSL_LIBRARIES-NOTFOUND} )
   return()
 endif()
 
-execute_process(
-  COMMAND echo "#include <${POLARSSL_INC_FOLDER}/version.h>\n#include <stdio.h>\nint main(){printf(${POLARSSL_REAL_NAME}_VERSION_STRING);return 0;}"
-  OUTPUT_FILE a.c
-)
-execute_process(
-  COMMAND ${CMAKE_C_COMPILER} a.c -I${POLARSSL_INCLUDE_DIRS} ${POLARSSL_LIBRARIES}
-)
-execute_process(
-  COMMAND ./a.out
-  OUTPUT_VARIABLE POLARSSL_VERSION_STRING
-)
-execute_process(
-  COMMAND ${CMAKE_COMMAND} -E remove a.c a.out
-)
+if( NOT CMAKE_CROSSCOMPILING )
+  execute_process(
+    COMMAND echo "#include <${POLARSSL_INC_FOLDER}/version.h>\n#include <stdio.h>\nint main(){printf(${POLARSSL_REAL_NAME}_VERSION_STRING);return 0;}"
+    OUTPUT_FILE a.c
+  )
+  execute_process(
+    COMMAND ${CMAKE_C_COMPILER} a.c -I${POLARSSL_INCLUDE_DIRS} ${POLARSSL_LIBRARIES}
+  )
+  execute_process(
+    COMMAND ./a.out
+    OUTPUT_VARIABLE POLARSSL_VERSION_STRING
+  )
+  execute_process(
+    COMMAND ${CMAKE_COMMAND} -E remove a.c a.out
+  )
+else()
+  execute_process(
+    COMMAND grep -w "MBEDTLS_VERSION_STRING" ${POLARSSL_INCLUDE_DIRS}/${POLARSSL_INC_FOLDER}/version.h
+    COMMAND sed -e "s@\s\+@ @g"
+    COMMAND cut -d\  -f3
+    COMMAND sed -e "s@\"@@g"
+    OUTPUT_VARIABLE POLARSSL_VERSION_STRING
+  )
+endif()
+
+message("PolarSSL/mbedTLS version: " ${POLARSSL_VERSION_STRING})
 
 if( "${POLARSSL_VERSION_STRING}" STREQUAL "2.0.0" AND NOT "${POLARSSL_USED_LIBRARY}" STREQUAL "mbedcrypto" )
   message("*** WARNING *** Your mbedTLS version is 2.0.0, it's possible the `make' command doesn't work.\nPlease refer to the INSTALL.md's \"mbedTLS 2.0.0\" section if you have any problem.\n")
diff --git a/include/dislocker/config.h b/include/dislocker/config.h
index d43d26c..3fbb2da 100644
--- a/include/dislocker/config.h
+++ b/include/dislocker/config.h
@@ -77,6 +77,8 @@ typedef enum {
  */
 void dis_usage();
 int  dis_getopts(dis_context_t dis_ctx, int argc, char** argv);
+
+int  dis_getopt(dis_context_t dis_ctx, dis_opt_e opt_name, void** opt_value);
 int  dis_setopt(dis_context_t dis_ctx, dis_opt_e opt_name, const void* opt_value);
 void dis_free_args(dis_context_t dis_ctx);
 void dis_print_args(dis_context_t dis_ctx);
diff --git a/man/darwin/dislocker-file.1 b/man/darwin/dislocker-file.1
index 9292840..4fb94d1 100644
--- a/man/darwin/dislocker-file.1
+++ b/man/darwin/dislocker-file.1
@@ -4,7 +4,7 @@
 .SH NAME
 Dislocker file - Read BitLocker encrypted volumes under Linux, OSX and FreeBSD.
 .SH SYNOPSIS
-dislocker-file [-hqrsv] [-l \fILOG_FILE\fR] [-o \fIOFFSET\fR] [-V \fIVOLUME\fR \fIDECRYPTMETHOD\fR -F[\fIN\fR]] [--] \fINTFS_FILE\fR
+dislocker-file [-hqrsv] [-l \fILOG_FILE\fR] [-O \fIOFFSET\fR] [-V \fIVOLUME\fR \fIDECRYPTMETHOD\fR -F[\fIN\fR]] [--] \fINTFS_FILE\fR
 
 Where DECRYPTMETHOD = {-p[\fIRECOVERY_PASSWORD\fR] | -f \fIBEK_FILE\fR | -u[\fIUSER_PASSWORD\fR] | -k \fIFVEK_FILE\fR | -c}
 .SH DESCRIPTION
@@ -20,7 +20,7 @@ For program's options description, see dislocker-fuse(1). The only change in the
 .B NTFS_FILE
 the newly created file where NTFS data will be put to, once decrypted from the BitLocker encrypted volume.
 .SH EXAMPLES
-These are exemples you can run directly.
+These are examples you can run directly.
 
 Dislock the BitLocker encrypted volume:
 .IP
@@ -43,6 +43,6 @@ You may have to completely unmount the NTFS partition before halting the system.
 
 Note that these are \fBexamples\fR and, as such, you may need to modify the given command lines. For example, you may want to change the decryption method used in them.
 .SH AUTHOR
-This tool is developped by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
+This tool is developed by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
 .PP
-Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
\ No newline at end of file
+Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
diff --git a/man/darwin/dislocker-fuse.1 b/man/darwin/dislocker-fuse.1
index e422a2f..fbc49eb 100644
--- a/man/darwin/dislocker-fuse.1
+++ b/man/darwin/dislocker-fuse.1
@@ -4,7 +4,7 @@
 .SH NAME
 Dislocker fuse - Read/write BitLocker encrypted volumes under Linux, OSX and FreeBSD.
 .SH SYNOPSIS
-dislocker-fuse [-hqrsv] [-l \fILOG_FILE\fR] [-o \fIOFFSET\fR] [-V \fIVOLUME\fR \fIDECRYPTMETHOD\fR -F[\fIN\fR]] [-- \fIARGS\fR...]
+dislocker-fuse [-hqrsv] [-l \fILOG_FILE\fR] [-O \fIOFFSET\fR] [-V \fIVOLUME\fR \fIDECRYPTMETHOD\fR -F[\fIN\fR]] [-- \fIARGS\fR...]
 
 Where DECRYPTMETHOD = {-p[\fIRECOVERY_PASSWORD\fR] | -f \fIBEK_FILE\fR | -u[\fIUSER_PASSWORD\fR] | -k \fIFVEK_FILE\fR | -c}
 .SH DESCRIPTION
@@ -36,9 +36,9 @@ See the FVEK FILE section below to understand what is to be put into this \fIFVE
 .B -l, --logfile \fILOG_FILE\fR
 put messages into this file (stdout by default)
 .TP
-.B -o, --offset \fIOFFSET\fR
-BitLocker partition offset in base 10 (default is 0).
-Protip: in your shell, you probably can pass \fB-o $((\fI0xdeadbeef\fB))\fR if you have a 16-based number and are too lazy to convert it in another way.
+.B -O, --offset \fIOFFSET\fR
+BitLocker partition offset, in bytes, in base 10 (default is 0).
+Protip: in your shell, you probably can pass \fB-O $((\fI0xdeadbeef\fB))\fR if you have a 16-based number and are too lazy to convert it in another way.
 .TP
 .B -p, --recovery-password=[\fIRECOVERY_PASSWORD\fB]\fR
 decrypt volume using the recovery password method.
@@ -81,13 +81,13 @@ The FVEK file option expects a specific format from the file. The file is split
 The file is therefore 66 bytes long, not more nor less.
 Note that you may have to deal with endianness.
 .SH EXAMPLES
-These are exemples you can run directly.
+These are examples you can run directly.
 First, you may want to copy the BitLocker volume:
 .IP
 .B % dd if=/dev/sda2 of=encrypted.bitlocker
 .IP
 This will copy the entire volume located into \fB/dev/sda2\fR to \fBencrypted.bitlocker\fR.
-You're not forced to do this step, but this will ensure no write whatesoever is performed on the BitLocker volume.
+You're not forced to do this step, but this will ensure no write whatsoever is performed on the BitLocker volume.
 .P
 Then dislock it:
 .IP
@@ -110,6 +110,6 @@ It seems that you have to unmount the NTFS partition and the dislocker one befor
 .P
 Note that these are \fBexamples\fR and, as such, may need to be modified. For instance, you may want to change the decryption method used in them.
 .SH AUTHOR
-This tool is developped by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
+This tool is developed by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
 .PP
-Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
\ No newline at end of file
+Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
diff --git a/man/linux/dislocker-file.1 b/man/linux/dislocker-file.1
index 6ce5ba8..970fcbc 100644
--- a/man/linux/dislocker-file.1
+++ b/man/linux/dislocker-file.1
@@ -4,7 +4,7 @@
 .SH NAME
 Dislocker file - Read BitLocker encrypted volumes under Linux, OSX and FreeBSD.
 .SH SYNOPSIS
-dislocker-file [-hqrsv] [-l \fILOG_FILE\fR] [-o \fIOFFSET\fR] [-V \fIVOLUME\fR \fIDECRYPTMETHOD\fR -F[\fIN\fR]] [--] \fINTFS_FILE\fR
+dislocker-file [-hqrsv] [-l \fILOG_FILE\fR] [-O \fIOFFSET\fR] [-V \fIVOLUME\fR \fIDECRYPTMETHOD\fR -F[\fIN\fR]] [--] \fINTFS_FILE\fR
 
 Where DECRYPTMETHOD = {-p[\fIRECOVERY_PASSWORD\fR] | -f \fIBEK_FILE\fR | -u[\fIUSER_PASSWORD\fR] | -k \fIFVEK_FILE\fR | -c}
 .SH DESCRIPTION
@@ -20,7 +20,7 @@ For program's options description, see dislocker-fuse(1). The only change in the
 .B NTFS_FILE
 the newly created file where NTFS data will be put to, once decrypted from the BitLocker encrypted volume.
 .SH EXAMPLES
-These are exemples you can run directly.
+These are examples you can run directly.
 
 Dislock the BitLocker encrypted volume:
 .IP
@@ -40,6 +40,6 @@ You may have to unmount the NTFS partition before halting the system. In order t
 
 Note that these are \fBexamples\fR and, as such, you may need to modify the given command lines. For example, you may want to change the decryption method used in them.
 .SH AUTHOR
-This tool is developped by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
+This tool is developed by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
 .PP
-Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
\ No newline at end of file
+Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
diff --git a/man/linux/dislocker-find.1 b/man/linux/dislocker-find.1
index 8b6c9c3..079ce8f 100644
--- a/man/linux/dislocker-find.1
+++ b/man/linux/dislocker-find.1
@@ -20,7 +20,7 @@ print the help and exit
 .B files
 check for BitLocker-encrypted partitions among these files instead of trying to find them alone
 .SH RETURN VALUES
--1 means an error occured, other numbers are the number of BitLocker-encrypted volumes found. For example, 0 means no volume has been found, 42 means 42 volumes have been found.
+-1 means an error occurred, other numbers are the number of BitLocker-encrypted volumes found. For example, 0 means no volume has been found, 42 means 42 volumes have been found.
 .SH EXAMPLES
 No volume is found automatically, the program returns 0 volume found (the last line comes from the echo):
 .IP
@@ -39,6 +39,6 @@ Two volumes are found, the program returns this number (the last line comes from
 2
 .fi
 .SH AUTHOR
-This tool is developped by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
+This tool is developed by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
 .PP
-Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
\ No newline at end of file
+Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
diff --git a/man/linux/dislocker-fuse.1 b/man/linux/dislocker-fuse.1
index 579e7b3..aeabe1a 100644
--- a/man/linux/dislocker-fuse.1
+++ b/man/linux/dislocker-fuse.1
@@ -4,7 +4,7 @@
 .SH NAME
 Dislocker fuse - Read/write BitLocker encrypted volumes under Linux, OSX and FreeBSD.
 .SH SYNOPSIS
-dislocker-fuse [-hqrsv] [-l \fILOG_FILE\fR] [-o \fIOFFSET\fR] [-V \fIVOLUME\fR \fIDECRYPTMETHOD\fR -F[\fIN\fR]] [-- \fIARGS\fR...]
+dislocker-fuse [-hqrsv] [-l \fILOG_FILE\fR] [-O \fIOFFSET\fR] [-V \fIVOLUME\fR \fIDECRYPTMETHOD\fR -F[\fIN\fR]] [-- \fIARGS\fR...]
 
 Where DECRYPTMETHOD = {-p[\fIRECOVERY_PASSWORD\fR] | -f \fIBEK_FILE\fR | -u[\fIUSER_PASSWORD\fR] | -k \fIFVEK_FILE\fR | -c}
 .SH DESCRIPTION
@@ -36,9 +36,9 @@ See the FVEK FILE section below to understand what is to be put into this \fIFVE
 .B -l, --logfile \fILOG_FILE\fR
 put messages into this file (stdout by default)
 .TP
-.B -o, --offset \fIOFFSET\fR
-BitLocker partition offset in base 10 (default is 0).
-Protip: in your shell, you probably can pass \fB-o $((\fI0xdeadbeef\fB))\fR if you have a 16-based number and are too lazy to convert it in another way.
+.B -O, --offset \fIOFFSET\fR
+BitLocker partition offset, in bytes, in base 10 (default is 0).
+Protip: in your shell, you probably can pass \fB-O $((\fI0xdeadbeef\fB))\fR if you have a 16-based number and are too lazy to convert it in another way.
 .TP
 .B -p, --recovery-password=[\fIRECOVERY_PASSWORD\fB]\fR
 decrypt volume using the recovery password method.
@@ -81,13 +81,13 @@ The FVEK file option expects a specific format from the file. The file is split
 The file is therefore 66 bytes long, not more nor less.
 Note that you may have to deal with endianness.
 .SH EXAMPLES
-These are exemples you can run directly.
+These are examples you can run directly.
 First, you may want to copy the BitLocker volume:
 .IP
 .B % dd if=/dev/sda2 of=encrypted.bitlocker
 .IP
 This will copy the entire volume located into \fB/dev/sda2\fR to \fBencrypted.bitlocker\fR.
-You're not forced to do this step, but this will ensure no write whatesoever is performed on the BitLocker volume.
+You're not forced to do this step, but this will ensure no write whatsoever is performed on the BitLocker volume.
 .P
 Then dislock it:
 .IP
@@ -107,6 +107,6 @@ It seems that you have to unmount the NTFS partition and the dislocker one befor
 .P
 Note that these are \fBexamples\fR and, as such, may need to be modified. For instance, you may want to change the decryption method used in them.
 .SH AUTHOR
-This tool is developped by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
+This tool is developed by Romain Coltel on behalf of HSC (\fBhttp://www.hsc.fr/\fR)
 .PP
-Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
\ No newline at end of file
+Feel free to send bugs report to <dislocker __AT__ hsc __DOT__ fr>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 365903a..656b4e6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,6 +17,10 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 # USA.
 
+if("${CMAKE_SOURCE_DIR}" MATCHES "src/?$")
+	message(FATAL_ERROR "\nPlease execute cmake from the directory above, not the src/ directory.")
+	return()
+endif()
 
 add_definitions (-DPROGNAME="${PROJECT_NAME}")
 add_definitions (-DAUTHOR="${AUTHOR}")
@@ -34,7 +38,9 @@ else()
 	add_definitions (-D__ARCH_X86)
 endif()
 
-include_directories (SYSTEM /usr/local/include)
+if( NOT CMAKE_CROSSCOMPILING )
+	include_directories (SYSTEM /usr/local/include)
+endif()
 include_directories (${PROJECT_SOURCE_DIR}/include)
 
 set (LIB pthread)
@@ -54,7 +60,7 @@ set (SOURCES
 	)
 
 if(NOT DEFINED WARN_FLAGS)
-	set (WARN_FLAGS "-Wall -Werror -Wextra" CACHE STRING "" FORCE)
+	set (WARN_FLAGS "-Wall -Wextra" CACHE STRING "" FORCE)
 endif()
 if(NOT DEFINED HARDEN_FLAGS)
 	set (HARDEN_FLAGS "-fstack-protector -fstrict-aliasing -D_FORTIFY_SOURCE=2 -O1" CACHE STRING "" FORCE)
@@ -123,6 +129,12 @@ if(RUBY_FOUND  AND  RUBY_INCLUDE_DIRS  AND  RUBY_LIBRARIES)
 	set (SOURCES ${SOURCES} ruby.c)
 endif()
 
+find_package (FUSE)
+if(FUSE_FOUND  AND  FUSE_INCLUDE_DIRS  AND  FUSE_LIBRARIES)
+	include_directories (${FUSE_INCLUDE_DIRS})
+	set (LIB "${LIB} ${FUSE_LIBRARIES}")
+endif()
+
 # Places
 if(NOT DEFINED sharedir)
   set(sharedir ${CMAKE_INSTALL_PREFIX}/share)
@@ -149,7 +161,7 @@ if(NOT DEFINED bindir)
 endif()
 
 string (TOLOWER "${CMAKE_SYSTEM_NAME}" SYSNAME)
-set (DIS_MAN ../man/${SYSNAME})
+set (DIS_MAN ${PROJECT_SOURCE_DIR}/man/${SYSNAME})
 
 # RPATH handling
 if(POLICY CMP0042)
@@ -185,22 +197,24 @@ target_link_libraries (${BIN_FUSE} ${FUSE_LIB} ${PROJECT_NAME})
 set_target_properties (${BIN_FUSE} PROPERTIES COMPILE_DEFINITIONS FUSE_USE_VERSION=26)
 set_target_properties (${BIN_FUSE} PROPERTIES LINK_FLAGS "-pie -fPIE")
 add_custom_command (TARGET ${BIN_FUSE} POST_BUILD
-	COMMAND gzip -c ${DIS_MAN}/${BIN_FUSE}.1 > ${DIS_MAN}/${BIN_FUSE}.1.gz
+	COMMAND mkdir -p ${CMAKE_BINARY_DIR}/man/
+	COMMAND gzip -c ${DIS_MAN}/${BIN_FUSE}.1 > ${CMAKE_BINARY_DIR}/man/${BIN_FUSE}.1.gz
 )
-set (CLEAN_FILES ${CLEAN_FILES} ${DIS_MAN}/${BIN_FUSE}.1.gz)
+set (CLEAN_FILES ${CLEAN_FILES} ${CMAKE_BINARY_DIR}/man/${BIN_FUSE}.1.gz)
 install (TARGETS ${BIN_FUSE} RUNTIME DESTINATION "${bindir}")
-install (FILES ${DIS_MAN}/${BIN_FUSE}.1.gz DESTINATION "${mandir}/man1")
+install (FILES ${CMAKE_BINARY_DIR}/man/${BIN_FUSE}.1.gz DESTINATION "${mandir}/man1")
 
 set (BIN_FILE ${PROJECT_NAME}-file)
 add_executable (${BIN_FILE} ${BIN_FILE}.c)
 target_link_libraries (${BIN_FILE} ${PROJECT_NAME})
 set_target_properties (${BIN_FILE} PROPERTIES LINK_FLAGS "-pie -fPIE")
 add_custom_command (TARGET ${BIN_FILE} POST_BUILD
-	COMMAND gzip -c ${DIS_MAN}/${BIN_FILE}.1 > ${DIS_MAN}/${BIN_FILE}.1.gz
+	COMMAND mkdir -p ${CMAKE_BINARY_DIR}/man/
+	COMMAND gzip -c ${DIS_MAN}/${BIN_FILE}.1 > ${CMAKE_BINARY_DIR}/man/${BIN_FILE}.1.gz
 )
-set (CLEAN_FILES ${CLEAN_FILES} ${DIS_MAN}/${BIN_FILE}.1.gz)
+set (CLEAN_FILES ${CLEAN_FILES} ${CMAKE_BINARY_DIR}/man/${BIN_FILE}.1.gz)
 install (TARGETS ${BIN_FILE} RUNTIME DESTINATION "${bindir}")
-install (FILES ${DIS_MAN}/${BIN_FILE}.1.gz DESTINATION "${mandir}/man1")
+install (FILES ${CMAKE_BINARY_DIR}/man/${BIN_FILE}.1.gz DESTINATION "${mandir}/man1")
 
 set (BIN_METADATA ${PROJECT_NAME}-metadata)
 add_executable (${BIN_METADATA} ${BIN_METADATA}.c)
@@ -224,11 +238,12 @@ if(RUBY_FOUND)
 	)
 	set (CLEAN_FILES ${CLEAN_FILES} ${CMAKE_CURRENT_BINARY_DIR}/${BIN_FIND})
 	add_custom_command (TARGET ${BIN_FIND} POST_BUILD
-		COMMAND gzip -c ${DIS_MAN}/${BIN_FIND}.1 > ${DIS_MAN}/${BIN_FIND}.1.gz
+		COMMAND mkdir -p ${CMAKE_BINARY_DIR}/man/
+		COMMAND gzip -c ${DIS_MAN}/${BIN_FIND}.1 > ${CMAKE_BINARY_DIR}/man/${BIN_FIND}.1.gz
 	)
-	set (CLEAN_FILES ${CLEAN_FILES} ${DIS_MAN}/${BIN_FIND}.1.gz)
+	set (CLEAN_FILES ${CLEAN_FILES} ${CMAKE_BINARY_DIR}/man/${BIN_FIND}.1.gz)
 	install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${BIN_FIND} DESTINATION "${bindir}")
-	install (FILES ${DIS_MAN}/${BIN_FIND}.1.gz DESTINATION "${mandir}/man1")
+	install (FILES ${CMAKE_BINARY_DIR}/man/${BIN_FIND}.1.gz DESTINATION "${mandir}/man1")
 else()
 	set (BIN_FIND true)
 endif()
diff --git a/src/common.c b/src/common.c
index f9d9c09..49ad6bd 100644
--- a/src/common.c
+++ b/src/common.c
@@ -125,12 +125,79 @@ ssize_t dis_read(int fd, void* buf, size_t count)
 
 	dis_printf(L_DEBUG, "Reading %# " F_SIZE_T " bytes from #%d into %p\n", count, fd, buf);
 
+#ifdef __FREEBSD
+	/*
+	 * FreeBSD's devices are character devices which are to be accessed one
+	 * block at a time. Exactly what one block is remains a mystery atm, so we
+	 * assume it's a sector, and that a sector is 512-bytes long.
+	 * So we count the number of sectors the requested read is on, read them all
+	 * and copy to the user only the requested data.
+	 */
+	uint16_t sector_size = 512;
+	off_t offset = lseek(fd, 0, SEEK_CUR);
+	unsigned int sector_to_add = 0;
+	off_t new_offset = -1;
+	size_t old_count = count;
+	void* old_buf = buf;
+
+	if((offset % sector_size) != 0)
+		sector_to_add += 1;
+	if(((offset + (off_t)count) % sector_size) != 0)
+		sector_to_add += 1;
+
+	new_offset = (offset / sector_size) * sector_size;
+	count = ((count / sector_size) + sector_to_add) * sector_size;
+
+	if(lseek(fd, new_offset, SEEK_SET) != new_offset)
+	{
+		dis_printf(
+			L_ERROR,
+			"Cannot lseek(2) to boundary %#" F_OFF_T "\n",
+			new_offset
+		);
+		errno = EIO;
+		return -1;
+	}
+
+	buf = dis_malloc(count * sizeof(char));
+	if(buf == NULL)
+	{
+		dis_printf(
+			L_ERROR,
+			"Cannot malloc %" F_SIZE_T " bytes\n",
+			count * sizeof(char)
+		);
+		errno = EIO;
+		return -1;
+	}
+#endif
+
 	if((res = read(fd, buf, count)) < 0)
 	{
 		dis_errno = errno;
 		dis_printf(L_ERROR, DIS_XREAD_FAIL_STR " #%d: %s\n", fd, strerror(errno));
 	}
 
+#ifdef __FREEBSD
+	/* What is remaining is just to copy actual data */
+	memcpy(old_buf, (char*) buf + (offset - new_offset), old_count);
+	dis_free(buf);
+
+	if(lseek(fd, offset + (off_t)old_count, SEEK_SET) == -1)
+	{
+		dis_printf(
+			L_ERROR,
+			"Cannot lseek(2) for restore to %#" F_OFF_T "\n",
+			offset + (off_t)old_count
+		);
+		errno = EIO;
+		return -1;
+	}
+
+	/* Fake the return value */
+	res = (ssize_t) old_count;
+#endif
+
 	return res;
 }
 
@@ -175,7 +242,7 @@ off_t dis_lseek(int fd, off_t offset, int whence)
 {
 	off_t res = -1;
 
-	dis_printf(L_DEBUG, "Positionnong #%d at offset %lld from %d\n", fd, offset, whence);
+	dis_printf(L_DEBUG, "Positioning #%d at offset %lld from %d\n", fd, offset, whence);
 
 	if((res = lseek(fd, offset, whence)) < 0)
 	{
diff --git a/src/config.c b/src/config.c
index b7447a4..b9f61f2 100644
--- a/src/config.c
+++ b/src/config.c
@@ -22,6 +22,7 @@
  */
 
 
+#include <string.h>
 #include <getopt.h>
 
 #include "dislocker/common.h"
@@ -30,6 +31,129 @@
 
 
 
+
+
+/**
+ * Hide a commandline option, replacing the actual optarg by 'X's.
+ *
+ * @param opt The option to hide
+ */
+static void hide_opt(char* opt)
+{
+	if(!opt)
+		return;
+
+	size_t len = strlen(opt);
+
+	while(len)
+	{
+		opt[--len] = 'X';
+	}
+}
+
+
+/* These functions are wrappers around the appropriate dis_setopt call */
+static void setclearkey(dis_context_t dis_ctx, char* optarg)
+{
+	(void) optarg;
+	int true = TRUE;
+	dis_setopt(dis_ctx, DIS_OPT_USE_CLEAR_KEY, &true);
+}
+static void setbekfile(dis_context_t dis_ctx, char* optarg)
+{
+	int true = TRUE;
+	dis_setopt(dis_ctx, DIS_OPT_USE_BEK_FILE, &true);
+	dis_setopt(dis_ctx, DIS_OPT_SET_BEK_FILE_PATH, optarg);
+}
+static void setforceblock(dis_context_t dis_ctx, char* optarg)
+{
+	off_t force;
+	if(optarg)
+		force = (unsigned char) strtol(optarg, NULL, 10);
+	else
+		force = 1;
+	dis_setopt(dis_ctx, DIS_OPT_FORCE_BLOCK, &force);
+}
+static void setfvek(dis_context_t dis_ctx, char* optarg)
+{
+	int true = TRUE;
+	dis_setopt(dis_ctx, DIS_OPT_USE_FVEK_FILE, &true);
+	dis_setopt(dis_ctx, DIS_OPT_SET_FVEK_FILE_PATH, optarg);
+}
+static void setlogfile(dis_context_t dis_ctx, char* optarg)
+{
+	dis_setopt(dis_ctx, DIS_OPT_LOG_FILE_PATH, optarg);
+}
+static void setoffset(dis_context_t dis_ctx, char* optarg)
+{
+	off_t offset = (off_t) strtoll(optarg, NULL, 10);
+	dis_setopt(dis_ctx, DIS_OPT_VOLUME_OFFSET, &offset);
+}
+static void setrecoverypwd(dis_context_t dis_ctx, char* optarg)
+{
+	int true = TRUE;
+	dis_setopt(dis_ctx, DIS_OPT_USE_RECOVERY_PASSWORD, &true);
+	dis_setopt(dis_ctx, DIS_OPT_SET_RECOVERY_PASSWORD, optarg);
+	hide_opt(optarg);
+}
+static void setquiet(dis_context_t dis_ctx, char* optarg)
+{
+	(void) optarg;
+	DIS_LOGS l = L_QUIET;
+	dis_setopt(dis_ctx, DIS_OPT_VERBOSITY, &l);
+}
+static void setro(dis_context_t dis_ctx, char* optarg)
+{
+	(void) optarg;
+	int true = TRUE;
+	dis_setopt(dis_ctx, DIS_OPT_READ_ONLY, &true);
+}
+static void setstateok(dis_context_t dis_ctx, char* optarg)
+{
+	(void) optarg;
+	int true = TRUE;
+	dis_setopt(dis_ctx, DIS_OPT_DONT_CHECK_VOLUME_STATE, &true);
+}
+static void setuserpassword(dis_context_t dis_ctx, char* optarg)
+{
+	int true = TRUE;
+	dis_setopt(dis_ctx, DIS_OPT_USE_USER_PASSWORD, &true);
+	dis_setopt(dis_ctx, DIS_OPT_SET_USER_PASSWORD, optarg);
+	hide_opt(optarg);
+}
+static void setverbosity(dis_context_t dis_ctx, char* optarg)
+{
+	dis_ctx->cfg.verbosity = (DIS_LOGS)strtol(optarg, NULL, 10);
+}
+
+
+/* Structure used to define dislocker's options */
+struct _dis_options {
+	struct option opt;
+	void (*fn)(dis_context_t dis_ctx, char* optarg);
+};
+
+static struct _dis_options dis_opt[] = {
+	{ {"clearkey",          no_argument,       NULL, 'c'}, setclearkey },
+	{ {"bekfile",           required_argument, NULL, 'f'}, setbekfile },
+	{ {"force-block",       optional_argument, NULL, 'F'}, setforceblock },
+	{ {"help",              no_argument,       NULL, 'h'}, NULL },
+	{ {"fvek",              required_argument, NULL, 'k'}, setfvek },
+	{ {"logfile",           required_argument, NULL, 'l'}, setlogfile },
+	{ {"offset",            required_argument, NULL, 'O'}, setoffset },
+	{ {"options",           required_argument, NULL, 'o'}, NULL },
+	{ {"recovery-password", optional_argument, NULL, 'p'}, setrecoverypwd },
+	{ {"quiet",             no_argument,       NULL, 'q'}, setquiet },
+	{ {"readonly",          no_argument,       NULL, 'r'}, setro },
+	{ {"ro",                no_argument,       NULL, 'r'}, setro },
+	{ {"stateok",           no_argument,       NULL, 's'}, setstateok },
+	{ {"user-password",     optional_argument, NULL, 'u'}, setuserpassword },
+	{ {"verbosity",         no_argument,       NULL, 'v'}, setverbosity },
+	{ {"volume",            required_argument, NULL, 'V'}, NULL }
+};
+
+
+
 /**
  * Print program's usage
  */
@@ -41,7 +165,7 @@ PROGNAME " by " AUTHOR ", v" VERSION " (compiled for " __OS "/" __ARCH ")\n"
 "Compiled version: " VERSION_DBG "\n"
 #endif
 "\n"
-"Usage: " PROGNAME " [-hqrsv] [-l LOG_FILE] [-o OFFSET] [-V VOLUME DECRYPTMETHOD -F[N]] [-- ARGS...]\n"
+"Usage: " PROGNAME " [-hqrsv] [-l LOG_FILE] [-O OFFSET] [-V VOLUME DECRYPTMETHOD -F[N]] [-- ARGS...]\n"
 "    with DECRYPTMETHOD = -p[RECOVERY_PASSWORD]|-f BEK_FILE|-u[USER_PASSWORD]|-k FVEK_FILE|-c\n"
 "\n"
 "Options:\n"
@@ -53,7 +177,7 @@ PROGNAME " by " AUTHOR ", v" VERSION " (compiled for " __OS "/" __ARCH ")\n"
 "    -k, --fvek FVEK_FILE  decrypt volume using the FVEK directly\n"
 "    -l, --logfile LOG_FILE\n"
 "                          put messages into this file (stdout by default)\n"
-"    -o, --offset OFFSET   BitLocker partition offset (default is 0)\n"
+"    -O, --offset OFFSET   BitLocker partition offset, in bytes (default is 0)\n"
 "    -p, --recovery-password=[RECOVERY_PASSWORD]\n"
 "                          decrypt volume using the recovery password method\n"
 "    -q, --quiet           do NOT display anything\n"
@@ -74,20 +198,34 @@ PROGNAME " by " AUTHOR ", v" VERSION " (compiled for " __OS "/" __ARCH ")\n"
 
 
 /**
- * Hide a commandline option, replacing the actual optarg by 'X's.
+ * Parse the --options parameter's value
  *
- * @param opt The option to hide
+ * @param dis_ctx Dislocker's context
+ * @param optstr The value passed with the --options parameter
  */
-static void hide_opt(char* opt)
+static void parse_options(dis_context_t dis_ctx, char* optstr)
 {
-	if(!opt)
-		return;
+	char* tok = NULL;
+	size_t nb_options = sizeof(dis_opt)/sizeof(struct _dis_options);
+	size_t i;
+	size_t opt_len;
 
-	size_t len = strlen(opt);
-
-	while(len)
+	tok = strtok(optstr, ",");
+	while(tok != NULL)
 	{
-		opt[--len] = 'X';
+		for(i = 0; i < nb_options; i++)
+		{
+			opt_len = strlen(dis_opt[i].opt.name);
+			if(strncmp(dis_opt[i].opt.name, tok, opt_len) == 0)
+			{
+				if(tok[opt_len] == '=' && tok[opt_len] != '\0')
+					dis_opt[i].fn(dis_ctx, &tok[opt_len + 1]);
+				else
+					dis_opt[i].fn(dis_ctx, NULL);
+			}
+		}
+
+		tok = strtok(NULL, ",");
 	}
 }
 
@@ -98,7 +236,7 @@ static void hide_opt(char* opt)
  * @warning If -h/--help is encountered, the help is printed and the program
  * exits (using exit(EXIT_SUCCESS)).
  *
- * @param cfg The config pointer to dis_config_t structure
+ * @param dis_ctx Dislocker's context
  * @param argc Number of arguments given to the program
  * @param argv Arguments given to the program
  * @return Return the number of arguments which are still waiting to be studied.
@@ -109,32 +247,12 @@ int dis_getopts(dis_context_t dis_ctx, int argc, char** argv)
 	/** See man getopt_long(3) */
 	extern int optind;
 	int optchar = 0;
+	size_t nb_options = sizeof(dis_opt)/sizeof(struct _dis_options);
 
-	enum {
-		NO_OPT,   /* No option for this argument */
-		NEED_OPT, /* Need an option for this one */
-		MAY_OPT   /* User may provide an option  */
-	};
 
 	/* Options which could be passed as argument */
-	const char          short_opts[] = "cf:F::hk:l:o:p::qrsu::vV:";
-	const struct option long_opts[] = {
-		{"clearkey",          NO_OPT,   NULL, 'c'},
-		{"bekfile",           NEED_OPT, NULL, 'f'},
-		{"force-block",       MAY_OPT,  NULL, 'F'},
-		{"help",              NO_OPT,   NULL, 'h'},
-		{"fvek",              NEED_OPT, NULL, 'k'},
-		{"logfile",           NEED_OPT, NULL, 'l'},
-		{"offset",            NEED_OPT, NULL, 'o'},
-		{"recovery-password", MAY_OPT,  NULL, 'p'},
-		{"quiet",             NO_OPT,   NULL, 'q'},
-		{"readonly",          NO_OPT,   NULL, 'r'},
-		{"stateok",           NO_OPT,   NULL, 's'},
-		{"user-password",     MAY_OPT,  NULL, 'u'},
-		{"verbosity",         NO_OPT,   NULL, 'v'},
-		{"volume",            NEED_OPT, NULL, 'V'},
-		{0, 0, 0, 0}
-	};
+	const char short_opts[] = "cf:F::hk:l:O:o:p::qrsu::vV:";
+	struct option* long_opts;
 
 	if(!dis_ctx || !argv)
 		return -1;
@@ -143,7 +261,17 @@ int dis_getopts(dis_context_t dis_ctx, int argc, char** argv)
 	int true = TRUE;
 
 
-	while((optchar=getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1)
+	long_opts = malloc(nb_options * sizeof(struct option));
+	while(nb_options--)
+	{
+		long_opts[nb_options].name    = dis_opt[nb_options].opt.name;
+		long_opts[nb_options].has_arg = dis_opt[nb_options].opt.has_arg;
+		long_opts[nb_options].flag    = dis_opt[nb_options].opt.flag;
+		long_opts[nb_options].val     = dis_opt[nb_options].opt.val;
+	}
+
+
+	while((optchar = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1)
 	{
 		switch(optchar)
 		{
@@ -185,12 +313,17 @@ int dis_getopts(dis_context_t dis_ctx, int argc, char** argv)
 				dis_setopt(dis_ctx, DIS_OPT_LOG_FILE_PATH, optarg);
 				break;
 			}
-			case 'o':
+			case 'O':
 			{
 				off_t offset = (off_t) strtoll(optarg, NULL, 10);
 				dis_setopt(dis_ctx, DIS_OPT_VOLUME_OFFSET, &offset);
 				break;
 			}
+			case 'o':
+			{
+				parse_options(dis_ctx, optarg);
+				break;
+			}
 			case 'p':
 			{
 				dis_setopt(dis_ctx, DIS_OPT_USE_RECOVERY_PASSWORD, &true);
@@ -236,6 +369,7 @@ int dis_getopts(dis_context_t dis_ctx, int argc, char** argv)
 			default:
 			{
 				dis_usage();
+				free(long_opts);
 				dis_free_args(dis_ctx);
 				return -1;
 			}
@@ -246,6 +380,8 @@ int dis_getopts(dis_context_t dis_ctx, int argc, char** argv)
 	/* Check verbosity */
 	if(cfg->verbosity > L_DEBUG)
 		cfg->verbosity = L_DEBUG;
+	if(cfg->verbosity < L_CRITICAL)
+		cfg->verbosity = L_CRITICAL;
 
 	/* Check decryption method */
 	if(!cfg->decryption_mean)
@@ -257,11 +393,107 @@ int dis_getopts(dis_context_t dis_ctx, int argc, char** argv)
 	   cfg->force_block != 3)
 		cfg->force_block = 0;
 
+	free(long_opts);
 
 	return optind;
 }
 
 
+/**
+ * Get dislocker's option
+ *
+ * @param dis_ctx Dislocker's context
+ * @param opt_name The option's name to get
+ * @param opt_value The retrieved value of the option. This is stored in
+ *opt_value.
+ */
+int dis_getopt(dis_context_t dis_ctx, dis_opt_e opt_name, void** opt_value)
+{
+	if (!dis_ctx || !opt_value)
+		return FALSE;
+
+	dis_config_t* cfg = &dis_ctx->cfg;
+
+	switch(opt_name)
+	{
+		case DIS_OPT_VOLUME_PATH:
+			*opt_value = cfg->volume_path;
+			break;
+		case DIS_OPT_USE_CLEAR_KEY:
+			if(cfg->decryption_mean & DIS_USE_CLEAR_KEY)
+				*opt_value = (void*) TRUE;
+			else
+				*opt_value = (void*) FALSE;
+			break;
+		case DIS_OPT_USE_BEK_FILE:
+			if(cfg->decryption_mean & DIS_USE_BEKFILE)
+				*opt_value = (void*) TRUE;
+			else
+				*opt_value = (void*) FALSE;
+			break;
+		case DIS_OPT_SET_BEK_FILE_PATH:
+			*opt_value = cfg->bek_file;
+			break;
+		case DIS_OPT_USE_RECOVERY_PASSWORD:
+			if(cfg->decryption_mean & DIS_USE_RECOVERY_PASSWORD)
+				*opt_value = (void*) TRUE;
+			else
+				*opt_value = (void*) FALSE;
+			break;
+		case DIS_OPT_SET_RECOVERY_PASSWORD:
+			*opt_value = cfg->recovery_password;
+			break;
+		case DIS_OPT_USE_USER_PASSWORD:
+			if(cfg->decryption_mean & DIS_USE_USER_PASSWORD)
+				*opt_value = (void*) TRUE;
+			else
+				*opt_value = (void*) FALSE;
+			break;
+		case DIS_OPT_SET_USER_PASSWORD:
+			*opt_value = cfg->user_password;
+			break;
+		case DIS_OPT_USE_FVEK_FILE:
+			if(cfg->decryption_mean & DIS_USE_FVEKFILE)
+				*opt_value = (void*) TRUE;
+			else
+				*opt_value = (void*) FALSE;
+			break;
+		case DIS_OPT_SET_FVEK_FILE_PATH:
+			*opt_value = cfg->fvek_file;
+			break;
+		case DIS_OPT_VERBOSITY:
+			*opt_value = (void*) cfg->verbosity;
+			break;
+		case DIS_OPT_LOG_FILE_PATH:
+			*opt_value = cfg->log_file;
+			break;
+		case DIS_OPT_FORCE_BLOCK:
+			*opt_value = (void*) ((long) cfg->force_block);
+			break;
+		case DIS_OPT_VOLUME_OFFSET:
+			*opt_value = (void*) cfg->offset;
+			break;
+		case DIS_OPT_READ_ONLY:
+			if(cfg->flags & DIS_FLAG_READ_ONLY)
+				*opt_value = (void*) TRUE;
+			else
+				*opt_value = (void*) FALSE;
+			break;
+		case DIS_OPT_DONT_CHECK_VOLUME_STATE:
+			if(cfg->flags & DIS_FLAG_DONT_CHECK_VOLUME_STATE)
+				*opt_value = (void*) TRUE;
+			else
+				*opt_value = (void*) FALSE;
+			break;
+		case DIS_OPT_INITIALIZE_STATE:
+			*opt_value = (void*) cfg->init_stop_at;
+			break;
+	}
+
+	return TRUE;
+}
+
+
 static void set_decryption_mean(dis_config_t* cfg, int set, unsigned value)
 {
 	if(set == TRUE)
@@ -274,14 +506,14 @@ static void set_decryption_mean(dis_config_t* cfg, int set, unsigned value)
 /**
  * Modify dislocker's options one-by-one
  *
- * @param cfg Dislocker's config
+ * @param dis_ctx Dislocker's context
  * @param opt_name The option's name to change
  * @param opt_value The new value of the option. Note that this is a pointer. If
  * NULL, the default value -which is not necessarily usable- will be set.
  */
 int dis_setopt(dis_context_t dis_ctx, dis_opt_e opt_name, const void* opt_value)
 {
-	if (!dis_ctx || !opt_value)
+	if (!dis_ctx)
 		return FALSE;
 
 	dis_config_t* cfg = &dis_ctx->cfg;
diff --git a/src/dislocker-fuse.c b/src/dislocker-fuse.c
index c0ee979..801bb06 100644
--- a/src/dislocker-fuse.c
+++ b/src/dislocker-fuse.c
@@ -191,6 +191,8 @@ struct fuse_operations fs_oper = {
  */
 int main(int argc, char** argv)
 {
+	char* volume_path = NULL;
+
 	// Check parameters number
 	if(argc < 2)
 	{
@@ -201,11 +203,28 @@ int main(int argc, char** argv)
 	int param_idx = 0;
 	int ret       = EXIT_SUCCESS;
 
-
 	/* Get command line options */
 	dis_ctx = dis_new();
 	param_idx = dis_getopts(dis_ctx, argc, argv);
 
+	/*
+	 * Check we have a volume path given and if not, take the first non-argument
+	 * as the volume path
+	 */
+	dis_getopt(dis_ctx, DIS_OPT_VOLUME_PATH, (void**) &volume_path);
+	if(volume_path == NULL)
+	{
+		if(param_idx >= argc || param_idx <= 0)
+		{
+			dis_printf(L_CRITICAL, "Error, no volume path given. Abort.\n");
+			return EXIT_FAILURE;
+		}
+
+		dis_printf(L_DEBUG, "Setting the volume path to %s.\n", argv[param_idx]);
+		dis_setopt(dis_ctx, DIS_OPT_VOLUME_PATH, argv[param_idx]);
+		param_idx++;
+	}
+
 	/* Initialize dislocker */
 	if(dis_initialize(dis_ctx) != DIS_RET_SUCCESS)
 	{
diff --git a/src/dislocker.bb b/src/dislocker.bb
new file mode 100644
index 0000000..222c313
--- /dev/null
+++ b/src/dislocker.bb
@@ -0,0 +1,32 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/dislocker:"
+
+SUMMARY = "Read BitLocker encrypted partitions under a Linux system"
+DESCRIPTION = " \
+This software has been designed to read BitLocker encrypted partitions under a \
+Linux system. The driver has the capability to read/write on: \
+ - Windows Vista, 7, 8, 8.1 and 10 encrypted partitions - that's AES-CBC, \
+   AES-XTS, 128 or 256 bits, with or without the Elephant diffuser, encrypted \
+   partitions; \
+ - BitLocker-To-Go encrypted partitions - that's USB/FAT32 partitions. \
+"
+
+HOMEPAGE = "https://github.com/Aorimn/dislocker"
+BUGTRACKER = "https://github.com/Aorimn/dislocker/issues"
+
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=6aa0d8e41ad2e57bef0712adf0cf5cb5"
+
+SECTION = "e/utils"
+
+SRC_URI = "https://github.com/Aorimn/dislocker/archive/v${PV}.tar.gz"
+
+SRC_URI[md5sum] = "0683bd18472d5f9e13f718e4d80ed7c7"
+SRC_URI[sha256sum] = "9e36afb0b29714e325d1721332e913bbd357f089a53962fcb7ae62f2e3862d84"
+
+DEPENDS = "mbedtls fuse"
+RDEPENDS_${PN} += "mbedtls fuse"
+PROVIDES += "dislocker"
+RPROVIDES_${PN} = "dislocker"
+EXTRA_OECMAKE = " -DLIB_INSTALL_DIR=${baselib}"
+
+inherit cmake
diff --git a/src/dislocker.c b/src/dislocker.c
index 5037b07..fb4a26c 100644
--- a/src/dislocker.c
+++ b/src/dislocker.c
@@ -493,16 +493,16 @@ int enlock(dis_context_t dis_ctx, uint8_t* buffer, off_t offset, size_t size)
 		return -EFAULT;
 	}
 
-	if((size_t)offset + size >= (size_t)dis_ctx->io_data.volume_size)
+	if(offset + (off_t)size >= (off_t)dis_ctx->io_data.volume_size)
 	{
 		size_t nsize = (size_t)dis_ctx->io_data.volume_size
 		               - (size_t)offset;
 		dis_printf(
 			L_WARNING,
 			"Size modified as exceeding volume's end (offset=%#"
-			F_SIZE_T " + size=%#" F_SIZE_T " >= volume_size=%#"
-			F_SIZE_T ") ; new size: %#" F_SIZE_T "\n",
-			(size_t)offset, size, (size_t)dis_ctx->io_data.volume_size, nsize
+			F_OFF_T " + size=%#" F_OFF_T " >= volume_size=%#"
+			F_OFF_T ") ; new size: %#" F_SIZE_T "\n",
+			offset, (off_t)size, dis_ctx->io_data.volume_size, nsize
 		);
 		size = nsize;
 	}
diff --git a/src/dislocker.rb b/src/dislocker.rb
index 6dde81e..2f4aba5 100644
--- a/src/dislocker.rb
+++ b/src/dislocker.rb
@@ -6,13 +6,14 @@ require 'formula'
 
 class Dislocker < Formula
     homepage 'https://github.com/Aorimn/dislocker'
-    url 'https://github.com/Aorimn/dislocker/archive/v0.6.zip'
-    sha256 '9738fdaa224de5669fe98dbd2a2edfbb1f2d0021e63045140d693c401e673ce4'
-    version '0.6.0'
+    url 'https://github.com/Aorimn/dislocker/archive/v0.7.zip'
+    sha256 '807d7087e82b7ab5819a8ae1d5be6f074397c8f6a327b7b5798c1228e454424b'
+    version '0.7.0'
 
-    depends_on 'polarssl'
+    depends_on 'mbedtls'
     depends_on 'cmake'
-    depends_on :osxfuse
+#    This dependency is seperately installed, as a cask
+#    depends_on :osxfuse
 
     def install
         system 'cmake', *std_cmake_args
diff --git a/src/mbed_install.sh b/src/mbed_install.sh
index 54e2fa3..be7989d 100755
--- a/src/mbed_install.sh
+++ b/src/mbed_install.sh
@@ -2,7 +2,7 @@
 
 MBEDTLS_FOLDER=mbedtls-for-dislocker
 
-if brew info polarssl |head -1 |grep -q 2.0.0
+if brew info mbedtls |head -1 |grep -q 2.0.0
 then
 	git clone https://github.com/ARMmbed/mbedtls.git ${MBEDTLS_FOLDER}
 	cd ${MBEDTLS_FOLDER}
diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c
index 97ade34..abf5904 100644
--- a/src/metadata/metadata.c
+++ b/src/metadata/metadata.c
@@ -950,6 +950,9 @@ static int get_metadata_lazy_checked(
 			dis_free(*metadata);
 	}
 
+	if(current >= 3)
+		return FALSE;
+
 	return TRUE;
 }
 
@@ -1032,6 +1035,9 @@ static int get_eow_check_valid(
 		}
 	}
 
+	if(current == 2)
+		return FALSE;
+
 	return TRUE;
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/dislocker.git



More information about the forensics-changes mailing list