├── AUTHORS ├── COPYING ├── ChangeLog ├── Makefile.am ├── Makefile.in ├── README ├── THANKS ├── TODO ├── aclocal.m4 ├── compile ├── config.h.in ├── configure ├── configure.in ├── install-sh ├── metfs.c ├── mstring.c ├── mstring.h ├── readpassphrase.c └── readpassphrase.h /AUTHORS: -------------------------------------------------------------------------------- 1 | Metin KAYA 2 | 3 | Feel free to ask questions about MetFS to the author Metin KAYA . 4 | 5 | EnderUNIX Software Development Team @ Istanbul/TURKIYE 6 | http://kayameti.blogspot.com.tr/ 7 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | copyright (c) 2008 , Metin KAYA 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary 6 | forms, with or without modification, are 7 | permitted provided that the following 8 | conditions are met: 9 | 10 | 1. Redistributions of source code must 11 | retain the above copyright notice, 12 | this list of conditions and the 13 | following disclaimer. 14 | 15 | 2. Redistributions in binary form must 16 | reproduce the above copyright notice, 17 | this list of conditions and the 18 | following disclaimer in the 19 | documentation and/or other materials 20 | provided with the distribution. 21 | 22 | 3. Neither the name of the EnderUNIX Team 23 | nor the names of its contributors may 24 | be used to endorse or promote products 25 | derived from this software without 26 | specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 29 | HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 30 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 31 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 | OF MERCHANTABILITY AND FITNESS FOR A 33 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 34 | EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 35 | LIABLE FOR ANY DIRECT, INDIRECT, 36 | INCIDENTAL, SPECIAL, EXEMPLARY, OR 37 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 38 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 40 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED 41 | AND ON ANY THEORY OF LIABILITY, WHETHER IN 42 | CONTRACT, STRICT LIABILITY, OR TORT 43 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 44 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 46 | DAMAGE. 47 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | - 1st stable release of metfs: 2008.04.11 2 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Metin KAYA 3 | # 4 | # April 2008, Istanbul/TURKIYE 5 | # http://www.enderunix.org/metfs/ 6 | # 7 | # $Id: Makefile.am,v 1.4 2008/04/13 06:22:39 mk Exp $ 8 | # 9 | 10 | pkgdata_DATA = \ 11 | README\ 12 | COPYING\ 13 | AUTHORS\ 14 | ChangeLog\ 15 | TODO\ 16 | THANKS 17 | 18 | EXTRA_DIST = $(pkgdata_DATA) 19 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | # 2 | # Metin KAYA 3 | # 4 | # April 2008, Istanbul/TURKIYE 5 | # http://www.enderunix.org/metfs/ 6 | # 7 | # $Id: Makefile.in,v 1.1 2008/04/11 10:57:48 mk Exp $ 8 | # 9 | 10 | CC = @CC@ 11 | DEFS = @DEFS@ 12 | CFLAGS = @CFLAGS@ 13 | CPPFLAGS = @CPPFLAGS@ 14 | LDFLAGS = @LDFLAGS@ 15 | LIBS = @LIBS@ 16 | OBJS = @libexecdir@ 17 | STRIP = strip 18 | 19 | all: 20 | $(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) -c -o metfs.o metfs.c 21 | $(CC) -Wall -W -g -c -o readpassphrase.o readpassphrase.c 22 | $(CC) -Wall -W -g -c -o mstring.o mstring.c 23 | libtool --tag=CC --mode=link $(CC) $(CPPFLAGS) $(DEFS) $(LDFLAGS) $(LIBS) $(OBJS) -o metfs 24 | 25 | strip: 26 | $(STRIP) metfs 27 | 28 | install: 29 | cp -f metfs /usr/local/bin/metfs 30 | 31 | uninstall: 32 | rm -f /usr/local/bin/metfs 33 | 34 | clean: 35 | rm -rf .libs metfs *.o core.* *~ 36 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | $Id: README,v 1.13 2008/04/16 04:26:12 mk Exp $ 2 | 3 | MetFS is a filesystem software in userspace that is FUSE based, encrypted, dynamic sized (increase when new data added, decrease when data removed), single file when it's unmounted and very fast. In order to install MetFS, please refer to INSTALL. For licensing information see COPYING. 4 | 5 | MetFS 's been written in C language for performance reasons; proved to be running on Linux and FreeBSD. 6 | 7 | Features 8 | 9 | * MetFS partitions are visible only to the user who mounted them. No other users (including root) can view the filesystem contents. 10 | * MetFS partition looks like a single file when it's unmounted. 11 | * Clear version of the user password is never written to disk. 12 | * RC4 stream cipher is used. 13 | * MD5 hash algorithm is preferred. 14 | * Clear data never stored in anywhere. 15 | * Writing 1.6 GB sized data in ext3 filesystem is just 16 seconds faster than MetFS. 16 | * Faster and more secure string functions of OpenBSD and D.J.B are used. 17 | 18 | Read TODO list for our incoming features. 19 | 20 | .mfs is official file extension of MetFS. 21 | 22 | MetFS depends on FUSE, libgcrypt, and libtar. Thus, these packages must be installed in order to install MetFS. 23 | 24 | At first, install FUSE: 25 | 1st way: Issue 'yum -y install fuse-devel' or 'pkg_add -r fusefs-libs' in Red Hat or FreeBSD respectively. 26 | 2nd way: Download the source code of FUSE from http://sourceforge.net/project/showfiles.php?group_id=121684&package_id=132802. Then: 27 | # tar -zxvf fuse-2.7.2.tar.gz 28 | # cd fuse-2.7.2 29 | # ./configure 30 | # make && make install 31 | 32 | Secondly, install libgcrypt: 33 | 1st way: Issue 'yum -y install libgcrypt-devel' or 'pkg_add -r libgcrypt' in Red Hat or FreeBSD respectively. 34 | 2nd way: 35 | # wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.0.tar.bz2 36 | # tar -jxvf libgcrypt-1.4.0.tar.bz2 37 | # cd libgcrypt-1.4.0 38 | # ./configure 39 | # make && make install 40 | 41 | Finally, install libtar: 42 | # wget ftp://ftp.feep.net/pub/software/libtar/libtar-1.2.11.tar.gz 43 | # tar -zxvf libtar-1.2.11.tar.gz 44 | # cd libtar-1.2.11 45 | # ./configure 46 | # make && make install 47 | 48 | NOTE: On FreeBSD systems, also the 'libtool' package must be installed via 'pkg_add -r libtool' command. 49 | 50 | Now, MetFS can be installed smoothly: 51 | # wget http://www.EnderUNIX.org/metfs/metfs-1.0.tar.gz /* Please check for new versions. */ 52 | # tar -zxvf metfs-1.0.tar.gz 53 | # cd metfs-1.0 54 | # ./configure 55 | # make && make install strip 56 | 57 | By default, all FUSE based filesystems are visible only to the user who mounted them. 58 | No other users (including root) can view the filesystem contents 59 | (although, root makes "su normal_user"; root cannot access the MetFS partition of a non-privileged user). 60 | In order to enable this feature, please add the group "fuse" to the non-privileged user's group in the "/etc/group" file. 61 | 62 | 63 | Sample Usage 64 | ------------ 65 | 66 | $ metfs ~metin/mount ~metin/enc 67 | Enter your metfs file name (if you don't have, just hit ENTER): /* For the first time, just hit ENTER. */ 68 | New MetFS Password: /* Type your password. It won't be echoed. */ 69 | Verify MetFS Password: /* Retype your password. */ 70 | Enter the file name that will contain your encrypted data [max. 1024 characters]: ~metin/test.mfs 71 | $ cp ~metin/my_secret_file ~metin/mount /* Copy your secret files to the MetFS partition. */ 72 | $ fusermount -u ~metin/mount/ /* Then unmount your MetFS partition via fusermount. */ 73 | $ file ~metin/test.mfs 74 | /home/metin/test.mfs: data 75 | $ metfs ~metin/mount ~metin/enc 76 | Enter your metfs file name (if you don't have, just hit ENTER): /home/metin/test.mfs /* give full path of the file */ 77 | Enter MetFS Password: 78 | Password OK... 79 | $ ls ~metin/mount /* See your files. */ 80 | my_secret_file 81 | $ fusermount -u ~metin/mount/ 82 | 83 | 84 | Please feel free to ask questions about MetFS to the author Metin KAYA . 85 | 86 | EnderUNIX Software Development Team @ Istanbul/TURKIYE 87 | http://kayameti.blogspot.com.tr/ 88 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | - My advisor: H. Turgut UYAR 2 | - Murat BALABAN for his help in cryptography 3 | - Author of FUSE: Miklos SZEREDI 4 | - EnderUNIX Software Development Team @ Istanbul/TURKIYE for their valuable friendships 5 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | $Id: TODO,v 1.6 2008/04/16 04:27:44 mk Exp $ 2 | 3 | - Make METFS stable on FreeBSD. 4 | - Make all options available as a command parameter. 5 | - Don't extract/create all files included .mfs file. 6 | Append and extract only the needed file. 7 | - Implement an interface in JAVA. 8 | -------------------------------------------------------------------------------- /aclocal.m4: -------------------------------------------------------------------------------- 1 | # generated automatically by aclocal 1.10 -*- Autoconf -*- 2 | 3 | # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 4 | # 2005, 2006 Free Software Foundation, Inc. 5 | # This file is free software; the Free Software Foundation 6 | # gives unlimited permission to copy and/or distribute it, 7 | # with or without modifications, as long as this notice is preserved. 8 | 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 11 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 12 | # PARTICULAR PURPOSE. 13 | 14 | # AM_AUX_DIR_EXPAND -*- Autoconf -*- 15 | 16 | # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. 17 | # 18 | # This file is free software; the Free Software Foundation 19 | # gives unlimited permission to copy and/or distribute it, 20 | # with or without modifications, as long as this notice is preserved. 21 | 22 | # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets 23 | # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to 24 | # `$srcdir', `$srcdir/..', or `$srcdir/../..'. 25 | # 26 | # Of course, Automake must honor this variable whenever it calls a 27 | # tool from the auxiliary directory. The problem is that $srcdir (and 28 | # therefore $ac_aux_dir as well) can be either absolute or relative, 29 | # depending on how configure is run. This is pretty annoying, since 30 | # it makes $ac_aux_dir quite unusable in subdirectories: in the top 31 | # source directory, any form will work fine, but in subdirectories a 32 | # relative path needs to be adjusted first. 33 | # 34 | # $ac_aux_dir/missing 35 | # fails when called from a subdirectory if $ac_aux_dir is relative 36 | # $top_srcdir/$ac_aux_dir/missing 37 | # fails if $ac_aux_dir is absolute, 38 | # fails when called from a subdirectory in a VPATH build with 39 | # a relative $ac_aux_dir 40 | # 41 | # The reason of the latter failure is that $top_srcdir and $ac_aux_dir 42 | # are both prefixed by $srcdir. In an in-source build this is usually 43 | # harmless because $srcdir is `.', but things will broke when you 44 | # start a VPATH build or use an absolute $srcdir. 45 | # 46 | # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, 47 | # iff we strip the leading $srcdir from $ac_aux_dir. That would be: 48 | # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` 49 | # and then we would define $MISSING as 50 | # MISSING="\${SHELL} $am_aux_dir/missing" 51 | # This will work as long as MISSING is not called from configure, because 52 | # unfortunately $(top_srcdir) has no meaning in configure. 53 | # However there are other variables, like CC, which are often used in 54 | # configure, and could therefore not use this "fixed" $ac_aux_dir. 55 | # 56 | # Another solution, used here, is to always expand $ac_aux_dir to an 57 | # absolute PATH. The drawback is that using absolute paths prevent a 58 | # configured tree to be moved without reconfiguration. 59 | 60 | AC_DEFUN([AM_AUX_DIR_EXPAND], 61 | [dnl Rely on autoconf to set up CDPATH properly. 62 | AC_PREREQ([2.50])dnl 63 | # expand $ac_aux_dir to an absolute path 64 | am_aux_dir=`cd $ac_aux_dir && pwd` 65 | ]) 66 | 67 | # AM_CONDITIONAL -*- Autoconf -*- 68 | 69 | # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 70 | # Free Software Foundation, Inc. 71 | # 72 | # This file is free software; the Free Software Foundation 73 | # gives unlimited permission to copy and/or distribute it, 74 | # with or without modifications, as long as this notice is preserved. 75 | 76 | # serial 8 77 | 78 | # AM_CONDITIONAL(NAME, SHELL-CONDITION) 79 | # ------------------------------------- 80 | # Define a conditional. 81 | AC_DEFUN([AM_CONDITIONAL], 82 | [AC_PREREQ(2.52)dnl 83 | ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], 84 | [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl 85 | AC_SUBST([$1_TRUE])dnl 86 | AC_SUBST([$1_FALSE])dnl 87 | _AM_SUBST_NOTMAKE([$1_TRUE])dnl 88 | _AM_SUBST_NOTMAKE([$1_FALSE])dnl 89 | if $2; then 90 | $1_TRUE= 91 | $1_FALSE='#' 92 | else 93 | $1_TRUE='#' 94 | $1_FALSE= 95 | fi 96 | AC_CONFIG_COMMANDS_PRE( 97 | [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then 98 | AC_MSG_ERROR([[conditional "$1" was never defined. 99 | Usually this means the macro was only invoked conditionally.]]) 100 | fi])]) 101 | 102 | # Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005 103 | # Free Software Foundation, Inc. 104 | # 105 | # This file is free software; the Free Software Foundation 106 | # gives unlimited permission to copy and/or distribute it, 107 | # with or without modifications, as long as this notice is preserved. 108 | 109 | # serial 5 110 | 111 | # AM_PROG_CC_C_O 112 | # -------------- 113 | # Like AC_PROG_CC_C_O, but changed for automake. 114 | AC_DEFUN([AM_PROG_CC_C_O], 115 | [AC_REQUIRE([AC_PROG_CC_C_O])dnl 116 | AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl 117 | AC_REQUIRE_AUX_FILE([compile])dnl 118 | # FIXME: we rely on the cache variable name because 119 | # there is no other way. 120 | set dummy $CC 121 | ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` 122 | if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then 123 | # Losing compiler, so override with the script. 124 | # FIXME: It is wrong to rewrite CC. 125 | # But if we don't then we get into trouble of one sort or another. 126 | # A longer-term fix would be to have automake use am__CC in this case, 127 | # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" 128 | CC="$am_aux_dir/compile $CC" 129 | fi 130 | dnl Make sure AC_PROG_CC is never called again, or it will override our 131 | dnl setting of CC. 132 | m4_define([AC_PROG_CC], 133 | [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) 134 | ]) 135 | 136 | # Copyright (C) 2006 Free Software Foundation, Inc. 137 | # 138 | # This file is free software; the Free Software Foundation 139 | # gives unlimited permission to copy and/or distribute it, 140 | # with or without modifications, as long as this notice is preserved. 141 | 142 | # _AM_SUBST_NOTMAKE(VARIABLE) 143 | # --------------------------- 144 | # Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. 145 | # This macro is traced by Automake. 146 | AC_DEFUN([_AM_SUBST_NOTMAKE]) 147 | 148 | -------------------------------------------------------------------------------- /compile: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Wrapper for compilers which do not understand `-c -o'. 3 | 4 | scriptversion=2005-05-14.22 5 | 6 | # Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. 7 | # Written by Tom Tromey . 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | # As a special exception to the GNU General Public License, if you 24 | # distribute this file as part of a program that contains a 25 | # configuration script generated by Autoconf, you may include it under 26 | # the same distribution terms that you use for the rest of that program. 27 | 28 | # This file is maintained in Automake, please report 29 | # bugs to or send patches to 30 | # . 31 | 32 | case $1 in 33 | '') 34 | echo "$0: No command. Try \`$0 --help' for more information." 1>&2 35 | exit 1; 36 | ;; 37 | -h | --h*) 38 | cat <<\EOF 39 | Usage: compile [--help] [--version] PROGRAM [ARGS] 40 | 41 | Wrapper for compilers which do not understand `-c -o'. 42 | Remove `-o dest.o' from ARGS, run PROGRAM with the remaining 43 | arguments, and rename the output as expected. 44 | 45 | If you are trying to build a whole package this is not the 46 | right script to run: please start by reading the file `INSTALL'. 47 | 48 | Report bugs to . 49 | EOF 50 | exit $? 51 | ;; 52 | -v | --v*) 53 | echo "compile $scriptversion" 54 | exit $? 55 | ;; 56 | esac 57 | 58 | ofile= 59 | cfile= 60 | eat= 61 | 62 | for arg 63 | do 64 | if test -n "$eat"; then 65 | eat= 66 | else 67 | case $1 in 68 | -o) 69 | # configure might choose to run compile as `compile cc -o foo foo.c'. 70 | # So we strip `-o arg' only if arg is an object. 71 | eat=1 72 | case $2 in 73 | *.o | *.obj) 74 | ofile=$2 75 | ;; 76 | *) 77 | set x "$@" -o "$2" 78 | shift 79 | ;; 80 | esac 81 | ;; 82 | *.c) 83 | cfile=$1 84 | set x "$@" "$1" 85 | shift 86 | ;; 87 | *) 88 | set x "$@" "$1" 89 | shift 90 | ;; 91 | esac 92 | fi 93 | shift 94 | done 95 | 96 | if test -z "$ofile" || test -z "$cfile"; then 97 | # If no `-o' option was seen then we might have been invoked from a 98 | # pattern rule where we don't need one. That is ok -- this is a 99 | # normal compilation that the losing compiler can handle. If no 100 | # `.c' file was seen then we are probably linking. That is also 101 | # ok. 102 | exec "$@" 103 | fi 104 | 105 | # Name of file we expect compiler to create. 106 | cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` 107 | 108 | # Create the lock directory. 109 | # Note: use `[/.-]' here to ensure that we don't use the same name 110 | # that we are using for the .o file. Also, base the name on the expected 111 | # object file name, since that is what matters with a parallel build. 112 | lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d 113 | while true; do 114 | if mkdir "$lockdir" >/dev/null 2>&1; then 115 | break 116 | fi 117 | sleep 1 118 | done 119 | # FIXME: race condition here if user kills between mkdir and trap. 120 | trap "rmdir '$lockdir'; exit 1" 1 2 15 121 | 122 | # Run the compile. 123 | "$@" 124 | ret=$? 125 | 126 | if test -f "$cofile"; then 127 | mv "$cofile" "$ofile" 128 | elif test -f "${cofile}bj"; then 129 | mv "${cofile}bj" "$ofile" 130 | fi 131 | 132 | rmdir "$lockdir" 133 | exit $ret 134 | 135 | # Local Variables: 136 | # mode: shell-script 137 | # sh-indentation: 2 138 | # eval: (add-hook 'write-file-hooks 'time-stamp) 139 | # time-stamp-start: "scriptversion=" 140 | # time-stamp-format: "%:y-%02m-%02d.%02H" 141 | # time-stamp-end: "$" 142 | # End: 143 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.in by autoheader. */ 2 | 3 | /* Define to 1 if you have the `fdatasync' function. */ 4 | #undef HAVE_FDATASYNC 5 | 6 | /* Define to 1 if you have the `fork' function. */ 7 | #undef HAVE_FORK 8 | 9 | /* Define to 1 if you have the header file. */ 10 | #undef HAVE_INTTYPES_H 11 | 12 | /* Define to 1 if you have the header file. */ 13 | #undef HAVE_MEMORY_H 14 | 15 | /* Define to 1 if you have the `setxattr' function. */ 16 | #undef HAVE_SETXATTR 17 | 18 | /* Define to 1 if you have the header file. */ 19 | #undef HAVE_STDINT_H 20 | 21 | /* Define to 1 if you have the header file. */ 22 | #undef HAVE_STDLIB_H 23 | 24 | /* Define to 1 if you have the header file. */ 25 | #undef HAVE_STRINGS_H 26 | 27 | /* Define to 1 if you have the header file. */ 28 | #undef HAVE_STRING_H 29 | 30 | /* Define to 1 if `st_atim' is member of `struct stat'. */ 31 | #undef HAVE_STRUCT_STAT_ST_ATIM 32 | 33 | /* Define to 1 if `st_atimespec' is member of `struct stat'. */ 34 | #undef HAVE_STRUCT_STAT_ST_ATIMESPEC 35 | 36 | /* Define to 1 if you have the header file. */ 37 | #undef HAVE_SYS_STAT_H 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #undef HAVE_SYS_TYPES_H 41 | 42 | /* Define to 1 if you have the header file. */ 43 | #undef HAVE_UNISTD_H 44 | 45 | /* Define to 1 if your C compiler doesn't accept -c and -o together. */ 46 | #undef NO_MINUS_C_MINUS_O 47 | 48 | /* Define to the address where bug reports for this package should be sent. */ 49 | #undef PACKAGE_BUGREPORT 50 | 51 | /* Define to the full name of this package. */ 52 | #undef PACKAGE_NAME 53 | 54 | /* Define to the full name and version of this package. */ 55 | #undef PACKAGE_STRING 56 | 57 | /* Define to the one symbol short name of this package. */ 58 | #undef PACKAGE_TARNAME 59 | 60 | /* Define to the version of this package. */ 61 | #undef PACKAGE_VERSION 62 | 63 | /* Define to 1 if you have the ANSI C header files. */ 64 | #undef STDC_HEADERS 65 | -------------------------------------------------------------------------------- /configure.in: -------------------------------------------------------------------------------- 1 | AC_INIT(fuse, 2.7.2) 2 | AC_CONFIG_HEADERS(config.h) 3 | AC_PROG_CC 4 | AC_LANG_C 5 | AM_PROG_CC_C_O 6 | AC_PROG_INSTALL 7 | 8 | # compatibility for automake < 1.8 9 | if test -z "$mkdir_p"; then 10 | mkdir_p="../mkinstalldirs" 11 | AC_SUBST(mkdir_p) 12 | fi 13 | 14 | case $target_os in 15 | *linux*) arch=linux;; 16 | *bsd*) arch=bsd;; 17 | *) arch=unknown;; 18 | esac 19 | 20 | CFLAGS="-D_FILE_OFFSET_BITS=64 -O3 -D_REENTRANT -ansi -Wall -g -fno-strict-aliasing -I/usr/local/include -I/usr/include" 21 | CPPFLAGS="-I/usr/local/include -I/usr/include" 22 | DEFS="-D_FILE_OFFSET_BITS=64 -D_REENTRANT" 23 | LDFLAGS="-L/usr/local/lib -L/usr/lib" 24 | LIBS="-pthread -lrt -lfuse -lulockmgr -lgcrypt /usr/local/lib/libtar.a" 25 | libexecdir="metfs.o mstring.o readpassphrase.o" 26 | 27 | AC_CHECK_FUNCS([fork setxattr fdatasync]) 28 | AC_CHECK_MEMBERS([struct stat.st_atim]) 29 | AC_CHECK_MEMBERS([struct stat.st_atimespec]) 30 | 31 | AC_SEARCH_LIBS(dlopen, [dl]) 32 | AC_SEARCH_LIBS(clock_gettime, [rt]) 33 | AC_SEARCH_LIBS([pthread]) 34 | AC_SEARCH_LIBS([fuse]) 35 | AC_SEARCH_LIBS([ulockmgr]) 36 | AC_SEARCH_LIBS([gcrypt]) 37 | 38 | AM_CONDITIONAL(LINUX, test "$arch" = linux) 39 | AM_CONDITIONAL(BSD, test "$arch" = bsd) 40 | 41 | AC_CONFIG_FILES([Makefile]) 42 | AC_OUTPUT 43 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # install - install a program, script, or datafile 3 | 4 | scriptversion=2006-10-14.15 5 | 6 | # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 | # later released in X11R6 (xc/config/util/install.sh) with the 8 | # following copyright and license. 9 | # 10 | # Copyright (C) 1994 X Consortium 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to 14 | # deal in the Software without restriction, including without limitation the 15 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | # sell copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 | # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 | # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # Except as contained in this notice, the name of the X Consortium shall not 30 | # be used in advertising or otherwise to promote the sale, use or other deal- 31 | # ings in this Software without prior written authorization from the X Consor- 32 | # tium. 33 | # 34 | # 35 | # FSF changes to this file are in the public domain. 36 | # 37 | # Calling this script install-sh is preferred over install.sh, to prevent 38 | # `make' implicit rules from creating a file called install from it 39 | # when there is no Makefile. 40 | # 41 | # This script is compatible with the BSD install script, but was written 42 | # from scratch. 43 | 44 | nl=' 45 | ' 46 | IFS=" "" $nl" 47 | 48 | # set DOITPROG to echo to test this script 49 | 50 | # Don't use :- since 4.3BSD and earlier shells don't like it. 51 | doit="${DOITPROG-}" 52 | if test -z "$doit"; then 53 | doit_exec=exec 54 | else 55 | doit_exec=$doit 56 | fi 57 | 58 | # Put in absolute file names if you don't have them in your path; 59 | # or use environment vars. 60 | 61 | mvprog="${MVPROG-mv}" 62 | cpprog="${CPPROG-cp}" 63 | chmodprog="${CHMODPROG-chmod}" 64 | chownprog="${CHOWNPROG-chown}" 65 | chgrpprog="${CHGRPPROG-chgrp}" 66 | stripprog="${STRIPPROG-strip}" 67 | rmprog="${RMPROG-rm}" 68 | mkdirprog="${MKDIRPROG-mkdir}" 69 | 70 | posix_glob= 71 | posix_mkdir= 72 | 73 | # Desired mode of installed file. 74 | mode=0755 75 | 76 | chmodcmd=$chmodprog 77 | chowncmd= 78 | chgrpcmd= 79 | stripcmd= 80 | rmcmd="$rmprog -f" 81 | mvcmd="$mvprog" 82 | src= 83 | dst= 84 | dir_arg= 85 | dstarg= 86 | no_target_directory= 87 | 88 | usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89 | or: $0 [OPTION]... SRCFILES... DIRECTORY 90 | or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91 | or: $0 [OPTION]... -d DIRECTORIES... 92 | 93 | In the 1st form, copy SRCFILE to DSTFILE. 94 | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95 | In the 4th, create DIRECTORIES. 96 | 97 | Options: 98 | -c (ignored) 99 | -d create directories instead of installing files. 100 | -g GROUP $chgrpprog installed files to GROUP. 101 | -m MODE $chmodprog installed files to MODE. 102 | -o USER $chownprog installed files to USER. 103 | -s $stripprog installed files. 104 | -t DIRECTORY install into DIRECTORY. 105 | -T report an error if DSTFILE is a directory. 106 | --help display this help and exit. 107 | --version display version info and exit. 108 | 109 | Environment variables override the default commands: 110 | CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 111 | " 112 | 113 | while test $# -ne 0; do 114 | case $1 in 115 | -c) shift 116 | continue;; 117 | 118 | -d) dir_arg=true 119 | shift 120 | continue;; 121 | 122 | -g) chgrpcmd="$chgrpprog $2" 123 | shift 124 | shift 125 | continue;; 126 | 127 | --help) echo "$usage"; exit $?;; 128 | 129 | -m) mode=$2 130 | shift 131 | shift 132 | case $mode in 133 | *' '* | *' '* | *' 134 | '* | *'*'* | *'?'* | *'['*) 135 | echo "$0: invalid mode: $mode" >&2 136 | exit 1;; 137 | esac 138 | continue;; 139 | 140 | -o) chowncmd="$chownprog $2" 141 | shift 142 | shift 143 | continue;; 144 | 145 | -s) stripcmd=$stripprog 146 | shift 147 | continue;; 148 | 149 | -t) dstarg=$2 150 | shift 151 | shift 152 | continue;; 153 | 154 | -T) no_target_directory=true 155 | shift 156 | continue;; 157 | 158 | --version) echo "$0 $scriptversion"; exit $?;; 159 | 160 | --) shift 161 | break;; 162 | 163 | -*) echo "$0: invalid option: $1" >&2 164 | exit 1;; 165 | 166 | *) break;; 167 | esac 168 | done 169 | 170 | if test $# -ne 0 && test -z "$dir_arg$dstarg"; then 171 | # When -d is used, all remaining arguments are directories to create. 172 | # When -t is used, the destination is already specified. 173 | # Otherwise, the last argument is the destination. Remove it from $@. 174 | for arg 175 | do 176 | if test -n "$dstarg"; then 177 | # $@ is not empty: it contains at least $arg. 178 | set fnord "$@" "$dstarg" 179 | shift # fnord 180 | fi 181 | shift # arg 182 | dstarg=$arg 183 | done 184 | fi 185 | 186 | if test $# -eq 0; then 187 | if test -z "$dir_arg"; then 188 | echo "$0: no input file specified." >&2 189 | exit 1 190 | fi 191 | # It's OK to call `install-sh -d' without argument. 192 | # This can happen when creating conditional directories. 193 | exit 0 194 | fi 195 | 196 | if test -z "$dir_arg"; then 197 | trap '(exit $?); exit' 1 2 13 15 198 | 199 | # Set umask so as not to create temps with too-generous modes. 200 | # However, 'strip' requires both read and write access to temps. 201 | case $mode in 202 | # Optimize common cases. 203 | *644) cp_umask=133;; 204 | *755) cp_umask=22;; 205 | 206 | *[0-7]) 207 | if test -z "$stripcmd"; then 208 | u_plus_rw= 209 | else 210 | u_plus_rw='% 200' 211 | fi 212 | cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 213 | *) 214 | if test -z "$stripcmd"; then 215 | u_plus_rw= 216 | else 217 | u_plus_rw=,u+rw 218 | fi 219 | cp_umask=$mode$u_plus_rw;; 220 | esac 221 | fi 222 | 223 | for src 224 | do 225 | # Protect names starting with `-'. 226 | case $src in 227 | -*) src=./$src ;; 228 | esac 229 | 230 | if test -n "$dir_arg"; then 231 | dst=$src 232 | dstdir=$dst 233 | test -d "$dstdir" 234 | dstdir_status=$? 235 | else 236 | 237 | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 238 | # might cause directories to be created, which would be especially bad 239 | # if $src (and thus $dsttmp) contains '*'. 240 | if test ! -f "$src" && test ! -d "$src"; then 241 | echo "$0: $src does not exist." >&2 242 | exit 1 243 | fi 244 | 245 | if test -z "$dstarg"; then 246 | echo "$0: no destination specified." >&2 247 | exit 1 248 | fi 249 | 250 | dst=$dstarg 251 | # Protect names starting with `-'. 252 | case $dst in 253 | -*) dst=./$dst ;; 254 | esac 255 | 256 | # If destination is a directory, append the input filename; won't work 257 | # if double slashes aren't ignored. 258 | if test -d "$dst"; then 259 | if test -n "$no_target_directory"; then 260 | echo "$0: $dstarg: Is a directory" >&2 261 | exit 1 262 | fi 263 | dstdir=$dst 264 | dst=$dstdir/`basename "$src"` 265 | dstdir_status=0 266 | else 267 | # Prefer dirname, but fall back on a substitute if dirname fails. 268 | dstdir=` 269 | (dirname "$dst") 2>/dev/null || 270 | expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 271 | X"$dst" : 'X\(//\)[^/]' \| \ 272 | X"$dst" : 'X\(//\)$' \| \ 273 | X"$dst" : 'X\(/\)' \| . 2>/dev/null || 274 | echo X"$dst" | 275 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 276 | s//\1/ 277 | q 278 | } 279 | /^X\(\/\/\)[^/].*/{ 280 | s//\1/ 281 | q 282 | } 283 | /^X\(\/\/\)$/{ 284 | s//\1/ 285 | q 286 | } 287 | /^X\(\/\).*/{ 288 | s//\1/ 289 | q 290 | } 291 | s/.*/./; q' 292 | ` 293 | 294 | test -d "$dstdir" 295 | dstdir_status=$? 296 | fi 297 | fi 298 | 299 | obsolete_mkdir_used=false 300 | 301 | if test $dstdir_status != 0; then 302 | case $posix_mkdir in 303 | '') 304 | # Create intermediate dirs using mode 755 as modified by the umask. 305 | # This is like FreeBSD 'install' as of 1997-10-28. 306 | umask=`umask` 307 | case $stripcmd.$umask in 308 | # Optimize common cases. 309 | *[2367][2367]) mkdir_umask=$umask;; 310 | .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 311 | 312 | *[0-7]) 313 | mkdir_umask=`expr $umask + 22 \ 314 | - $umask % 100 % 40 + $umask % 20 \ 315 | - $umask % 10 % 4 + $umask % 2 316 | `;; 317 | *) mkdir_umask=$umask,go-w;; 318 | esac 319 | 320 | # With -d, create the new directory with the user-specified mode. 321 | # Otherwise, rely on $mkdir_umask. 322 | if test -n "$dir_arg"; then 323 | mkdir_mode=-m$mode 324 | else 325 | mkdir_mode= 326 | fi 327 | 328 | posix_mkdir=false 329 | case $umask in 330 | *[123567][0-7][0-7]) 331 | # POSIX mkdir -p sets u+wx bits regardless of umask, which 332 | # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 333 | ;; 334 | *) 335 | tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 336 | trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 337 | 338 | if (umask $mkdir_umask && 339 | exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 340 | then 341 | if test -z "$dir_arg" || { 342 | # Check for POSIX incompatibilities with -m. 343 | # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 344 | # other-writeable bit of parent directory when it shouldn't. 345 | # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 346 | ls_ld_tmpdir=`ls -ld "$tmpdir"` 347 | case $ls_ld_tmpdir in 348 | d????-?r-*) different_mode=700;; 349 | d????-?--*) different_mode=755;; 350 | *) false;; 351 | esac && 352 | $mkdirprog -m$different_mode -p -- "$tmpdir" && { 353 | ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 354 | test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 355 | } 356 | } 357 | then posix_mkdir=: 358 | fi 359 | rmdir "$tmpdir/d" "$tmpdir" 360 | else 361 | # Remove any dirs left behind by ancient mkdir implementations. 362 | rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 363 | fi 364 | trap '' 0;; 365 | esac;; 366 | esac 367 | 368 | if 369 | $posix_mkdir && ( 370 | umask $mkdir_umask && 371 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 372 | ) 373 | then : 374 | else 375 | 376 | # The umask is ridiculous, or mkdir does not conform to POSIX, 377 | # or it failed possibly due to a race condition. Create the 378 | # directory the slow way, step by step, checking for races as we go. 379 | 380 | case $dstdir in 381 | /*) prefix=/ ;; 382 | -*) prefix=./ ;; 383 | *) prefix= ;; 384 | esac 385 | 386 | case $posix_glob in 387 | '') 388 | if (set -f) 2>/dev/null; then 389 | posix_glob=true 390 | else 391 | posix_glob=false 392 | fi ;; 393 | esac 394 | 395 | oIFS=$IFS 396 | IFS=/ 397 | $posix_glob && set -f 398 | set fnord $dstdir 399 | shift 400 | $posix_glob && set +f 401 | IFS=$oIFS 402 | 403 | prefixes= 404 | 405 | for d 406 | do 407 | test -z "$d" && continue 408 | 409 | prefix=$prefix$d 410 | if test -d "$prefix"; then 411 | prefixes= 412 | else 413 | if $posix_mkdir; then 414 | (umask=$mkdir_umask && 415 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 416 | # Don't fail if two instances are running concurrently. 417 | test -d "$prefix" || exit 1 418 | else 419 | case $prefix in 420 | *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 421 | *) qprefix=$prefix;; 422 | esac 423 | prefixes="$prefixes '$qprefix'" 424 | fi 425 | fi 426 | prefix=$prefix/ 427 | done 428 | 429 | if test -n "$prefixes"; then 430 | # Don't fail if two instances are running concurrently. 431 | (umask $mkdir_umask && 432 | eval "\$doit_exec \$mkdirprog $prefixes") || 433 | test -d "$dstdir" || exit 1 434 | obsolete_mkdir_used=true 435 | fi 436 | fi 437 | fi 438 | 439 | if test -n "$dir_arg"; then 440 | { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 441 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 442 | { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 443 | test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 444 | else 445 | 446 | # Make a couple of temp file names in the proper directory. 447 | dsttmp=$dstdir/_inst.$$_ 448 | rmtmp=$dstdir/_rm.$$_ 449 | 450 | # Trap to clean up those temp files at exit. 451 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 452 | 453 | # Copy the file name to the temp name. 454 | (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 455 | 456 | # and set any options; do chmod last to preserve setuid bits. 457 | # 458 | # If any of these fail, we abort the whole thing. If we want to 459 | # ignore errors from any of these, just make sure not to ignore 460 | # errors from the above "$doit $cpprog $src $dsttmp" command. 461 | # 462 | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 463 | && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 464 | && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 465 | && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 466 | 467 | # Now rename the file to the real destination. 468 | { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ 469 | || { 470 | # The rename failed, perhaps because mv can't rename something else 471 | # to itself, or perhaps because mv is so ancient that it does not 472 | # support -f. 473 | 474 | # Now remove or move aside any old file at destination location. 475 | # We try this two ways since rm can't unlink itself on some 476 | # systems and the destination file might be busy for other 477 | # reasons. In this case, the final cleanup might fail but the new 478 | # file should still install successfully. 479 | { 480 | if test -f "$dst"; then 481 | $doit $rmcmd -f "$dst" 2>/dev/null \ 482 | || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ 483 | && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ 484 | || { 485 | echo "$0: cannot unlink or rename $dst" >&2 486 | (exit 1); exit 1 487 | } 488 | else 489 | : 490 | fi 491 | } && 492 | 493 | # Now rename the file to the real destination. 494 | $doit $mvcmd "$dsttmp" "$dst" 495 | } 496 | } || exit 1 497 | 498 | trap '' 0 499 | fi 500 | done 501 | 502 | # Local variables: 503 | # eval: (add-hook 'write-file-hooks 'time-stamp) 504 | # time-stamp-start: "scriptversion=" 505 | # time-stamp-format: "%:y-%02m-%02d.%02H" 506 | # time-stamp-end: "$" 507 | # End: 508 | -------------------------------------------------------------------------------- /metfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Metin KAYA 3 | * 4 | * April 2008, Istanbul/TURKIYE 5 | * http://www.enderunix.org/metfs/ 6 | * 7 | * $Id: metfs.c,v 1.16 2008/04/13 07:55:33 mk Exp $ 8 | */ 9 | 10 | #define FUSE_USE_VERSION 26 11 | #define _GNU_SOURCE 12 | 13 | #include "config.h" 14 | #include "mstring.h" 15 | #include "readpassphrase.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef HAVE_SETXATTR 37 | #include 38 | #endif 39 | 40 | #define ARCFOUR_KEY_LEN 16 /* Maximum key length of ARCFOUR cipher algorithm */ 41 | #define BUFSIZE 1024 42 | #define MAX_KEY_LEN 256 /* maximum length of the user key */ 43 | #define MIN_KEY_LEN 6 /* minimum length of the user key */ 44 | #define SEC_MEM_SIZE 32768 /* the size of secure memory in bytes (32 KB) */ 45 | 46 | char key[ARCFOUR_KEY_LEN]; 47 | 48 | static void 49 | metfs_error(const char *format, ...) 50 | { 51 | va_list arg_ptr; 52 | 53 | va_start(arg_ptr, format); 54 | vfprintf(stderr, format, arg_ptr); 55 | va_end(arg_ptr); 56 | 57 | exit(-1); 58 | } 59 | 60 | static unsigned char * 61 | metfs_md5(const char *data, int len) 62 | { 63 | gcry_md_hd_t hd; 64 | 65 | if (gcry_md_open(&hd, GCRY_MD_MD5, GCRY_MD_FLAG_SECURE)) 66 | metfs_error("MD5 grcy_md_open() failed\n"); 67 | 68 | if (gcry_md_get_algo_dlen(GCRY_MD_MD5) > ARCFOUR_KEY_LEN) 69 | metfs_error("MD5 grcy_md_get_algo_dlen() failed: %d\n", gcry_md_get_algo_dlen(GCRY_MD_MD5)); 70 | 71 | gcry_md_write(hd, data, len); 72 | 73 | return (gcry_md_read(hd, GCRY_MD_MD5)); 74 | } 75 | 76 | static void 77 | metfs_decrypt(int algo_num, int mode, char *out, char *plain, char *dec_key, int len) 78 | { 79 | gcry_cipher_hd_t hd; 80 | gcry_error_t err = 0; 81 | int keylen; 82 | 83 | keylen = gcry_cipher_get_algo_keylen(algo_num); 84 | if (!keylen) 85 | metfs_error("algorithm %d, mode %d, gcry_cipher_get_algo_keylen() died\n", algo_num, mode); 86 | 87 | if (keylen < MIN_KEY_LEN || keylen > 32) 88 | metfs_error("algorithm %d, mode %d, keylength problem (%d)\n", algo_num, mode, keylen); 89 | 90 | err = gcry_cipher_open(&hd, algo_num, mode, GCRY_CIPHER_SECURE); 91 | if (err) 92 | metfs_error("algorithm %d, mode %d, grcy_open_cipher() died: %s\n", algo_num, mode, gpg_strerror(err)); 93 | 94 | err = gcry_cipher_setkey(hd, dec_key, keylen); 95 | if (err) { 96 | gcry_cipher_close(hd); 97 | metfs_error("algorithm %d, mode %d, gcry_cipher_setkey() died: %s\n", algo_num, mode, gpg_strerror(err)); 98 | } 99 | 100 | err = gcry_cipher_decrypt(hd, plain, len, out, len); 101 | if (err) { 102 | gcry_cipher_close(hd); 103 | metfs_error("algorithm %d, mode %d, gcry_cipher_decrypt() died: %s\n", algo_num, mode, gpg_strerror(err)); 104 | } 105 | 106 | gcry_cipher_close(hd); 107 | } 108 | 109 | static void 110 | metfs_encrypt(int algo_num, int mode, char *plain, char *out, char *enc_key, int len) 111 | { 112 | gcry_cipher_hd_t hd; 113 | gcry_error_t err = 0; 114 | int keylen; 115 | 116 | keylen = gcry_cipher_get_algo_keylen(algo_num); 117 | if (!keylen) 118 | metfs_error("algorithm %d, mode %d, gcry_cipher_get_algo_keylen() died\n", algo_num, mode); 119 | 120 | if (keylen < MIN_KEY_LEN || keylen > 32) 121 | metfs_error("algorithm %d, mode %d, keylength problem (%d)\n", algo_num, mode, keylen); 122 | 123 | err = gcry_cipher_open(&hd, algo_num, mode, GCRY_CIPHER_SECURE); 124 | if (err) 125 | metfs_error("algorithm %d, mode %d, grcy_open_cipher() died: %s\n", algo_num, mode, gpg_strerror(err)); 126 | 127 | err = gcry_cipher_setkey(hd, enc_key, keylen); 128 | if (err) { 129 | gcry_cipher_close(hd); 130 | metfs_error("algorithm %d, mode %d, gcry_cipher_setkey() died: %s\n", algo_num, mode, gpg_strerror(err)); 131 | } 132 | 133 | err = gcry_cipher_encrypt(hd, out, len, plain, len); 134 | if (err) { 135 | gcry_cipher_close(hd); 136 | metfs_error("algorithm %d, mode %d, gcry_cipher_encrypt() died: %s\n", algo_num, mode, gpg_strerror(err)); 137 | } 138 | 139 | gcry_cipher_close(hd); 140 | } 141 | 142 | static int 143 | metfs_getattr(const char *path, struct stat *stbuf) 144 | { 145 | 146 | if (lstat(path, stbuf) == -1) 147 | return (-errno); 148 | 149 | return (0); 150 | } 151 | 152 | static int 153 | metfs_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) 154 | { 155 | 156 | (void) path; 157 | if (fstat(fi->fh, stbuf) == -1) 158 | return (-errno); 159 | 160 | return (0); 161 | } 162 | 163 | static int 164 | metfs_access(const char *path, int mask) 165 | { 166 | 167 | if (access(path, mask) == -1) 168 | return (-errno); 169 | 170 | return (0); 171 | } 172 | 173 | static int 174 | metfs_readlink(const char *path, char *buf, size_t size) 175 | { 176 | int res; 177 | 178 | if ((res = readlink(path, buf, size - 1)) == -1) 179 | return (-errno); 180 | 181 | buf[res] = '\0'; 182 | 183 | return (0); 184 | } 185 | 186 | struct metfs_dirp { 187 | DIR *dp; 188 | struct dirent *entry; 189 | off_t offset; 190 | }; 191 | 192 | static int 193 | metfs_opendir(const char *path, struct fuse_file_info *fi) 194 | { 195 | struct metfs_dirp *d = NULL; 196 | 197 | if ((d = malloc(sizeof(struct metfs_dirp))) == NULL) 198 | return (-ENOMEM); 199 | 200 | if ((d->dp = opendir(path)) == NULL) { 201 | free(d); 202 | return (-errno); 203 | } 204 | d->offset = 0; 205 | d->entry = NULL; 206 | fi->fh = (unsigned long) d; 207 | 208 | return (0); 209 | } 210 | 211 | static struct metfs_dirp * 212 | get_dirp(struct fuse_file_info *fi) 213 | { 214 | return ((struct metfs_dirp *) (uintptr_t) fi->fh); 215 | } 216 | 217 | static int 218 | metfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) 219 | { 220 | struct metfs_dirp *d = NULL; 221 | 222 | d = get_dirp(fi); 223 | (void) path; 224 | if (offset != d->offset) { 225 | seekdir(d->dp, offset); 226 | d->entry = NULL; 227 | d->offset = offset; 228 | } 229 | 230 | for (;;) { 231 | struct stat st; 232 | off_t nextoff; 233 | 234 | if (!d->entry) { 235 | d->entry = readdir(d->dp); 236 | if (!d->entry) 237 | break; 238 | } 239 | 240 | memset(&st, 0x0, sizeof(st)); 241 | st.st_ino = d->entry->d_ino; 242 | st.st_mode = d->entry->d_type << 12; 243 | nextoff = telldir(d->dp); 244 | if (filler(buf, d->entry->d_name, &st, nextoff)) 245 | break; 246 | 247 | d->entry = NULL; 248 | d->offset = nextoff; 249 | } 250 | 251 | return (0); 252 | } 253 | 254 | static int 255 | metfs_releasedir(const char *path, struct fuse_file_info *fi) 256 | { 257 | struct metfs_dirp *d = NULL; 258 | 259 | d = get_dirp(fi); 260 | (void) path; 261 | closedir(d->dp); 262 | free(d); 263 | 264 | return (0); 265 | } 266 | 267 | static int 268 | metfs_mknod(const char *path, mode_t mode, dev_t rdev) 269 | { 270 | int res; 271 | 272 | if (S_ISFIFO(mode)) 273 | res = mkfifo(path, mode); 274 | else 275 | res = mknod(path, mode, rdev); 276 | 277 | if (res == -1) 278 | return (-errno); 279 | 280 | return (0); 281 | } 282 | 283 | static int 284 | metfs_mkdir(const char *path, mode_t mode) 285 | { 286 | 287 | if (mkdir(path, mode) == -1) 288 | return (-errno); 289 | 290 | return (0); 291 | } 292 | 293 | static int 294 | metfs_unlink(const char *path) 295 | { 296 | 297 | if (unlink(path) == -1) 298 | return (-errno); 299 | 300 | return (0); 301 | } 302 | 303 | static int 304 | metfs_rmdir(const char *path) 305 | { 306 | 307 | if (rmdir(path) == -1) 308 | return (-errno); 309 | 310 | return (0); 311 | } 312 | 313 | static int 314 | metfs_symlink(const char *from, const char *to) 315 | { 316 | 317 | if (symlink(from, to) == -1) 318 | return (-errno); 319 | 320 | return (0); 321 | } 322 | 323 | static int 324 | metfs_rename(const char *from, const char *to) 325 | { 326 | 327 | if (rename(from, to) == -1) 328 | return (-errno); 329 | 330 | return (0); 331 | } 332 | 333 | static int 334 | metfs_link(const char *from, const char *to) 335 | { 336 | 337 | if (link(from, to) == -1) 338 | return (-errno); 339 | 340 | return (0); 341 | } 342 | 343 | static int 344 | metfs_chmod(const char *path, mode_t mode) 345 | { 346 | 347 | if (chmod(path, mode) == -1) 348 | return (-errno); 349 | 350 | return (0); 351 | } 352 | 353 | static int 354 | metfs_chown(const char *path, uid_t uid, gid_t gid) 355 | { 356 | 357 | if (lchown(path, uid, gid) == -1) 358 | return (-errno); 359 | 360 | return (0); 361 | } 362 | 363 | static int 364 | metfs_utimens(const char *path, const struct timespec ts[2]) 365 | { 366 | struct timeval tv[2]; 367 | 368 | tv[0].tv_sec = ts[0].tv_sec; 369 | tv[0].tv_usec = ts[0].tv_nsec / 1000; 370 | tv[1].tv_sec = ts[1].tv_sec; 371 | tv[1].tv_usec = ts[1].tv_nsec / 1000; 372 | 373 | if (utimes(path, tv) == -1) 374 | return (-errno); 375 | 376 | return (0); 377 | } 378 | 379 | static int 380 | metfs_create(const char *path, mode_t mode, struct fuse_file_info *fi) 381 | { 382 | int fd = 0; 383 | 384 | if ((fd = open(path, fi->flags, mode)) == -1) 385 | return (-errno); 386 | 387 | fi->fh = fd; 388 | 389 | return (0); 390 | } 391 | 392 | static int 393 | metfs_open(const char *path, struct fuse_file_info *fi) 394 | { 395 | int fd = 0; 396 | 397 | if ((fd = open(path, fi->flags)) == -1) 398 | return (-errno); 399 | 400 | fi->fh = fd; 401 | 402 | return (0); 403 | } 404 | 405 | static int 406 | metfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) 407 | { 408 | int res = 0; 409 | char decrypted[4096]; 410 | char encrypted[4096]; 411 | (void) path; 412 | 413 | memset(decrypted, 0x0, 4096); 414 | memset(encrypted, 0x0, 4096); 415 | 416 | if ((res = pread(fi->fh, encrypted, 4096, offset)) == -1) 417 | return (-errno); 418 | 419 | metfs_decrypt(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, encrypted, decrypted, key, res); 420 | memcpy(buf, decrypted, res); 421 | 422 | return (res); 423 | } 424 | 425 | static int 426 | metfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) 427 | { 428 | int res = 0, fd = 0, full_blk = 0, remainder = 0, total_wr = 0; 429 | char *plain = NULL; 430 | char *encrypted = NULL; 431 | 432 | if (offset % 4096 == 0) { 433 | plain = calloc(size, sizeof(char)); 434 | if (!plain) 435 | return (-ENOMEM); 436 | 437 | encrypted = calloc(size, sizeof(char)); 438 | if (!encrypted) { 439 | free(plain); 440 | return (-ENOMEM); 441 | } 442 | 443 | memcpy(plain, buf, size); 444 | metfs_encrypt(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, plain, encrypted, key, size); 445 | if ((res = pwrite(fi->fh, encrypted, size, offset)) == -1) 446 | res = (-errno); 447 | } else { 448 | full_blk = offset / 4096; 449 | remainder = offset % 4096; 450 | total_wr = remainder + size; 451 | 452 | plain = (char *) calloc(total_wr, sizeof(char)); 453 | if (!plain) 454 | return (-ENOMEM); 455 | 456 | encrypted = calloc(total_wr, sizeof(char)); 457 | if (!encrypted) { 458 | free(plain); 459 | return (-ENOMEM); 460 | } 461 | 462 | if ((fd = open(path, O_RDWR)) == -1) 463 | return (-errno); 464 | 465 | if ((res = pread(fd, encrypted, remainder, full_blk * 4096)) != remainder) { 466 | free(plain); 467 | free(encrypted); 468 | close(fd); 469 | return (-errno); 470 | } 471 | 472 | metfs_decrypt(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, encrypted, plain, key, res); 473 | memcpy(plain + res, buf, size); 474 | memset(encrypted, 0x0, total_wr); 475 | metfs_encrypt(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, plain, encrypted, key, total_wr); 476 | if ((res = pwrite(fd, encrypted, total_wr, full_blk * 4096)) == -1) { 477 | free(plain); 478 | free(encrypted); 479 | close(fd); 480 | return (-errno); 481 | } 482 | 483 | close(fd); 484 | res = size; 485 | } 486 | 487 | free(plain); 488 | free(encrypted); 489 | 490 | return (res); 491 | } 492 | 493 | static int 494 | metfs_truncate(const char *path, off_t size) 495 | { 496 | 497 | if (truncate(path, size) == -1) 498 | return (-errno); 499 | 500 | return (0); 501 | } 502 | 503 | static int 504 | metfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) 505 | { 506 | 507 | (void) path; 508 | if (ftruncate(fi->fh, size) == -1) 509 | return (-errno); 510 | 511 | return (0); 512 | } 513 | 514 | static int 515 | metfs_statfs(const char *path, struct statvfs *stbuf) 516 | { 517 | 518 | if (statvfs(path, stbuf) == -1) 519 | return (-errno); 520 | 521 | return (0); 522 | } 523 | 524 | static int 525 | metfs_flush(const char *path, struct fuse_file_info *fi) 526 | { 527 | 528 | (void) path; 529 | if (close(dup(fi->fh)) == -1) 530 | return (-errno); 531 | 532 | return (0); 533 | } 534 | 535 | static int 536 | metfs_release(const char *path, struct fuse_file_info *fi) 537 | { 538 | 539 | (void) path; 540 | close(fi->fh); 541 | 542 | return (0); 543 | } 544 | 545 | static int 546 | metfs_fsync(const char *path, int isdatasync, struct fuse_file_info *fi) 547 | { 548 | int res; 549 | 550 | (void) path; 551 | #ifndef HAVE_FDATASYNC 552 | (void) isdatasync; 553 | #else 554 | if (isdatasync) 555 | res = fdatasync(fi->fh); 556 | else 557 | #endif 558 | res = fsync(fi->fh); 559 | if (res == -1) 560 | return (-errno); 561 | 562 | return (0); 563 | } 564 | 565 | #ifdef HAVE_SETXATTR 566 | static int 567 | metfs_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) 568 | { 569 | 570 | if (lsetxattr(path, name, value, size, flags) == -1) 571 | return (-errno); 572 | 573 | return (0); 574 | } 575 | 576 | static int 577 | metfs_getxattr(const char *path, const char *name, char *value, size_t size) 578 | { 579 | int res; 580 | 581 | if ((res = lgetxattr(path, name, value, size)) == -1) 582 | return (-errno); 583 | 584 | return (res); 585 | } 586 | 587 | static int 588 | metfs_listxattr(const char *path, char *list, size_t size) 589 | { 590 | int res; 591 | 592 | if ((res = llistxattr(path, list, size)) == -1) 593 | return (-errno); 594 | 595 | return (res); 596 | } 597 | 598 | static int 599 | metfs_removexattr(const char *path, const char *name) 600 | { 601 | 602 | if (lremovexattr(path, name) == -1) 603 | return (-errno); 604 | 605 | return (0); 606 | } 607 | #endif /* HAVE_SETXATTR */ 608 | 609 | static int 610 | metfs_lock(const char *path, struct fuse_file_info *fi, int cmd, struct flock *lock) 611 | { 612 | 613 | (void) path; 614 | 615 | return (ulockmgr_op(fi->fh, cmd, lock, &fi->lock_owner, sizeof(fi->lock_owner))); 616 | } 617 | 618 | static struct fuse_operations metfs_oper = { 619 | .getattr = metfs_getattr, 620 | .fgetattr = metfs_fgetattr, 621 | .access = metfs_access, 622 | .readlink = metfs_readlink, 623 | .opendir = metfs_opendir, 624 | .readdir = metfs_readdir, 625 | .releasedir = metfs_releasedir, 626 | .mknod = metfs_mknod, 627 | .mkdir = metfs_mkdir, 628 | .symlink = metfs_symlink, 629 | .unlink = metfs_unlink, 630 | .rmdir = metfs_rmdir, 631 | .rename = metfs_rename, 632 | .link = metfs_link, 633 | .chmod = metfs_chmod, 634 | .chown = metfs_chown, 635 | .truncate = metfs_truncate, 636 | .ftruncate = metfs_ftruncate, 637 | .utimens = metfs_utimens, 638 | .create = metfs_create, 639 | .open = metfs_open, 640 | .read = metfs_read, 641 | .write = metfs_write, 642 | .statfs = metfs_statfs, 643 | .flush = metfs_flush, 644 | .release = metfs_release, 645 | .fsync = metfs_fsync, 646 | #ifdef HAVE_SETXATTR 647 | .setxattr = metfs_setxattr, 648 | .getxattr = metfs_getxattr, 649 | .listxattr = metfs_listxattr, 650 | .removexattr = metfs_removexattr, 651 | #endif 652 | .lock = metfs_lock, 653 | }; 654 | 655 | GCRY_THREAD_OPTION_PTHREAD_IMPL; 656 | 657 | static void 658 | metfs_init_encryption(void) 659 | { 660 | 661 | gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); 662 | gcry_control(GCRYCTL_INIT_SECMEM, SEC_MEM_SIZE, 0); 663 | gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); 664 | } 665 | 666 | static void 667 | metfs_set_key(void) 668 | { 669 | char *res1 = NULL; 670 | char *res2 = NULL; 671 | char pass_buf[MAX_KEY_LEN]; 672 | char pass_buf2[MAX_KEY_LEN]; 673 | 674 | memset(key, 0x0, ARCFOUR_KEY_LEN); 675 | 676 | for (;;) { 677 | memset(pass_buf, 0x0, MAX_KEY_LEN); 678 | memset(pass_buf2, 0x0, MAX_KEY_LEN); 679 | 680 | res1 = readpassphrase("New MetFS Password: ", pass_buf, sizeof(pass_buf) - 1, RPP_ECHO_OFF); 681 | if (mstrlen(pass_buf) < MIN_KEY_LEN) { 682 | printf("Password cannot be shorter than %d characters, please try again.\n", MIN_KEY_LEN); 683 | continue; 684 | } 685 | 686 | res2 = readpassphrase("Verify MetFS Password: ", pass_buf2, sizeof(pass_buf2) - 1, RPP_ECHO_OFF); 687 | 688 | if (res1 && res2 && !strncmp(pass_buf, pass_buf2, MAX_KEY_LEN)) { 689 | memcpy(key, (char *) metfs_md5(pass_buf, mstrlen(pass_buf)), ARCFOUR_KEY_LEN); 690 | break; 691 | } else { 692 | printf("Passwords did not match, please try again.\n"); 693 | } 694 | } 695 | } 696 | 697 | static void 698 | check_dir(const char *dir_name) 699 | { 700 | DIR *dp = NULL; 701 | struct dirent *dirp = NULL; 702 | 703 | if ((dp = opendir(dir_name)) == NULL) 704 | metfs_error("File: %s - Line: %d: %s.\n", __FILE__, __LINE__, strerror(errno)); 705 | 706 | while ((dirp = readdir(dp)) != NULL) 707 | if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, "..")) 708 | continue; 709 | else 710 | metfs_error("Working directory or mountpoint must be empty!\n"); 711 | 712 | if (closedir(dp) == -1) 713 | metfs_error("File: %s - Line: %d : %s\n", __FILE__, __LINE__, strerror(errno)); 714 | } 715 | 716 | static int 717 | metfs_clean_workdir(const char *dirpath, const char *dir_name) 718 | { 719 | char new_path[1024]; 720 | DIR *dirp = NULL; 721 | struct dirent *direntp = NULL; 722 | struct stat st; 723 | 724 | memset(&st, 0x0, sizeof(st)); 725 | 726 | if ((dirp = opendir(dirpath)) == NULL) 727 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 728 | 729 | while ((direntp = readdir(dirp)) != NULL) { 730 | memset(new_path, 0x0, sizeof(new_path)); 731 | 732 | if (strcmp(direntp->d_name, ".") !=0 && strcmp(direntp->d_name, "..") != 0) { 733 | snprintf(new_path, sizeof(new_path) - 1, "%s/%s", dirpath, direntp->d_name); 734 | if (lstat(new_path, &st) == -1) { 735 | closedir(dirp); 736 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 737 | } 738 | 739 | if (S_ISDIR(st.st_mode)) 740 | metfs_clean_workdir(new_path, dir_name); 741 | else 742 | if (unlink(new_path) == -1) 743 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 744 | } 745 | } 746 | if (closedir(dirp) == -1) 747 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 748 | 749 | if (strcmp(dirpath, dir_name)) 750 | if (rmdir(dirpath) == -1) 751 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 752 | 753 | return (0); 754 | } 755 | 756 | static int 757 | metfs_create_file(char *tarfile, char *dest, const char *passwd) 758 | { 759 | char plain[BUFSIZE]; 760 | char encrypted[BUFSIZE]; 761 | FILE *fp = NULL; 762 | TAR *t = NULL; 763 | 764 | unlink(tarfile); /* remove old metfs file, if exist. */ 765 | 766 | if (tar_open(&t, tarfile, NULL, O_WRONLY | O_CREAT, 0644, 0) == -1) 767 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 768 | 769 | if (tar_append_tree(t, dest, "/") != 0) { 770 | tar_close(t); 771 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 772 | } 773 | 774 | if (tar_append_eof(t) != 0) { 775 | tar_close(t); 776 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 777 | } 778 | 779 | if (tar_close(t) != 0) 780 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 781 | 782 | if ((fp = fopen(tarfile, "r+")) == NULL) 783 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 784 | 785 | fseek(fp, 0L, SEEK_END); 786 | if (write(fileno(fp), passwd, ARCFOUR_KEY_LEN) != ARCFOUR_KEY_LEN) 787 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 788 | 789 | memset(plain, 0x0, BUFSIZE); 790 | memset(encrypted, 0x0, BUFSIZE); 791 | 792 | if (pread(fileno(fp), plain, BUFSIZE - 1, 0) == -1) 793 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 794 | 795 | metfs_encrypt(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, plain, encrypted, key, BUFSIZE - 1); 796 | 797 | if (pwrite(fileno(fp), encrypted, BUFSIZE - 1, 0) == -1) 798 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 799 | 800 | if (fclose(fp) == -1) 801 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 802 | 803 | return (0); 804 | } 805 | 806 | static int 807 | metfs_extract_file(char *tarfile, char *rootdir, int fd) 808 | { 809 | TAR *t = NULL; 810 | char decrypted[BUFSIZE]; 811 | char encrypted[BUFSIZE]; 812 | 813 | memset(decrypted, 0x0, BUFSIZE); 814 | memset(encrypted, 0x0, BUFSIZE); 815 | 816 | if (pread(fd, encrypted, BUFSIZE - 1, 0) == -1) 817 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 818 | 819 | metfs_decrypt(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, encrypted, decrypted, key, BUFSIZE - 1); 820 | 821 | if (pwrite(fd, decrypted, BUFSIZE - 1, 0) == -1) 822 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 823 | 824 | if (tar_open(&t, tarfile, NULL, O_RDONLY, 0, 0) == -1) 825 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 826 | 827 | if (tar_extract_all(t, rootdir) != 0) 828 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 829 | 830 | if (tar_close(t) != 0) 831 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 832 | 833 | return (0); 834 | } 835 | 836 | int 837 | main(int argc, char** argv) 838 | { 839 | if (argc != 3 && argc != 4) 840 | metfs_error("Wrong number of parameters!\n" 841 | "Usage (sequence of arguments is mandatory): metfs [-d] \n"); 842 | 843 | check_dir(argv[1]); 844 | check_dir(argv[argc - 1]); 845 | 846 | char *metfs_argv[8], fname[1024], tmp[512], *addr = NULL, *pass_res = NULL, pass_buf[MAX_KEY_LEN]; 847 | int metfs_argc = 0, i = 0, flag = 0, fd = 0; 848 | off_t fsize = 0, offset = 0; 849 | struct stat st; 850 | 851 | memset(&st, 0x0, sizeof(st)); 852 | memset(fname, 0x0, sizeof(fname)); 853 | memset(tmp, 0x0, sizeof(tmp)); 854 | memset(pass_buf, 0x0, sizeof(pass_buf)); 855 | 856 | for (i = 0; i < 7; i++) 857 | metfs_argv[i] = NULL; /* libfuse expects null args. */ 858 | 859 | for (i = 0; i < argc; i++) 860 | metfs_argv[i] = argv[i]; 861 | 862 | snprintf(tmp, sizeof(tmp) - 1, "%s/", argv[argc - 1]); 863 | strcpy(metfs_argv[argc - 1], "-omodules=subdir,subdir="); 864 | strncat(metfs_argv[argc - 1], tmp, 486); 865 | metfs_argv[argc] = "-omax_read=4096"; /* set max_read size as 4K */ 866 | metfs_argc = argc + 1; 867 | 868 | metfs_init_encryption(); 869 | 870 | printf("Enter your metfs file name (if you don't have, just hit ENTER): "); 871 | fgets(fname, sizeof(fname) - 1, stdin); 872 | if (mstrlen(fname) > 1) { 873 | fname[mstrlen(fname) - 1] = '\0'; 874 | flag = 1; 875 | } 876 | 877 | if (flag) { 878 | if (stat(fname, &st) == -1) 879 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 880 | fsize = st.st_size; 881 | 882 | if ((fd = open(fname, O_RDWR)) == -1) 883 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 884 | 885 | offset = 0x0 & ~(sysconf(_SC_PAGE_SIZE) - 1); 886 | if ((addr = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd, offset)) == MAP_FAILED) 887 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 888 | 889 | pass_res = readpassphrase("Enter MetFS Password: ", pass_buf, sizeof(pass_buf) - 1, RPP_ECHO_OFF); 890 | if (!(pass_res && !memcmp(addr + fsize - ARCFOUR_KEY_LEN, (char *) metfs_md5(pass_buf, mstrlen(pass_buf)), ARCFOUR_KEY_LEN))) 891 | metfs_error("Wrong password!\n"); 892 | 893 | write(STDOUT_FILENO, "Password OK...\n", 15); 894 | munmap(addr, fsize); 895 | memset(key, 0x0, ARCFOUR_KEY_LEN); 896 | memcpy(key, (char *) metfs_md5(pass_buf, mstrlen(pass_buf)), ARCFOUR_KEY_LEN); 897 | 898 | if (truncate(fname, fsize - ARCFOUR_KEY_LEN) == -1) 899 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 900 | 901 | metfs_extract_file(fname, tmp, fd); 902 | 903 | if (pwrite(fd, key, ARCFOUR_KEY_LEN, fsize) != ARCFOUR_KEY_LEN) 904 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 905 | 906 | if (close(fd) == -1) 907 | metfs_error("File: %s - Line: %d: %s\n", __FILE__, __LINE__, strerror(errno)); 908 | } else { 909 | metfs_set_key(); 910 | printf("Enter the file name that will contain your encrypted data [max. 1024 characters]: "); 911 | scanf("%s", fname); 912 | } 913 | 914 | umask(0); 915 | fuse_main(metfs_argc, metfs_argv, &metfs_oper, NULL); 916 | metfs_create_file(fname, tmp, key); 917 | metfs_clean_workdir(tmp, tmp); 918 | 919 | exit(0); /* game over... */ 920 | } 921 | -------------------------------------------------------------------------------- /mstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Metin KAYA 3 | * 4 | * April 2008, Istanbul/TURKIYE 5 | * http://www.enderunix.org/metfs/ 6 | * 7 | * $Id: mstring.c,v 1.4 2008/04/13 05:10:16 mk Exp $ 8 | */ 9 | 10 | /*- 11 | * These string functions are ported from OpenBSD source code and copyrights 12 | * are stated below: 13 | * 14 | * Copyright (c) 1998 Todd C. Miller 15 | * All rights reserved. 16 | * 17 | * Redistribution and use in source and binary forms, with or without 18 | * modification, are permitted provided that the following conditions 19 | * are met: 20 | * 1. Redistributions of source code must retain the above copyright 21 | * notice, this list of conditions and the following disclaimer. 22 | * 2. Redistributions in binary form must reproduce the above copyright 23 | * notice, this list of conditions and the following disclaimer in the 24 | * documentation and/or other materials provided with the distribution. 25 | * 3. The name of the author may not be used to endorse or promote products 26 | * derived from this software without specific prior written permission. 27 | * 28 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 29 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 30 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 31 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 32 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 33 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 34 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 36 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 37 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | 48 | /* str_len() function of D.J.B. */ 49 | size_t 50 | mstrlen(const char *s) 51 | { 52 | register char *t; 53 | 54 | t = (char *) s; 55 | for (;;) { 56 | if (!*t) return (t - s); ++t; 57 | if (!*t) return (t - s); ++t; 58 | if (!*t) return (t - s); ++t; 59 | if (!*t) return (t - s); ++t; 60 | } 61 | } 62 | 63 | char * 64 | mstrdup(const char *str) 65 | { 66 | size_t siz; 67 | char *copy; 68 | 69 | siz = mstrlen(str) + 1; 70 | if ((copy = malloc(siz)) == NULL) 71 | return (NULL); 72 | (void) memcpy(copy, str, siz); 73 | 74 | return (copy); 75 | } 76 | 77 | size_t 78 | mstrcat(char *dst, const char *src, size_t size) 79 | { 80 | register char *d = dst; 81 | register const char *s = src; 82 | register size_t n = size; 83 | size_t dlen; 84 | 85 | /* Find the end of dst and adjust bytes left but don't go past end */ 86 | while (n-- != 0 && *d != '\0') 87 | d++; 88 | dlen = d - dst; 89 | n = size - dlen; 90 | 91 | if (n == 0) 92 | return(dlen + mstrlen(s)); 93 | while (*s != '\0') { 94 | if (n != 1) { 95 | *d++ = *s; 96 | n--; 97 | } 98 | s++; 99 | } 100 | *d = '\0'; 101 | 102 | return (dlen + (s - src)); /* count does not include NUL */ 103 | } 104 | 105 | size_t 106 | mstrcpy(char *dst, const char *src, size_t size) 107 | { 108 | register char *d = dst; 109 | register const char *s = src; 110 | register size_t n = size; 111 | 112 | /* Copy as many bytes as will fit */ 113 | if (n != 0 && --n != 0) { 114 | do { 115 | if ((*d++ = *s++) == 0) 116 | break; 117 | } while (--n != 0); 118 | } 119 | 120 | /* Not enough room in dst, add NUL and traverse rest of src */ 121 | if (n == 0) { 122 | if (size != 0) 123 | *d = '\0'; /* NUL-terminate dst */ 124 | while (*s++) 125 | ; 126 | } 127 | 128 | return (s - src - 1); /* count does not include NUL */ 129 | } 130 | 131 | char * 132 | mstrstr(char *string, char *find) 133 | { 134 | size_t stringlen, findlen; 135 | char *cp; 136 | 137 | findlen = mstrlen(find); 138 | stringlen = mstrlen(string); 139 | if (findlen > stringlen) 140 | return (NULL); 141 | 142 | for (cp = string + stringlen - findlen; cp >= string; cp--) 143 | if (strncmp(cp, find, findlen) == 0) 144 | return (cp); 145 | 146 | return (NULL); 147 | } 148 | -------------------------------------------------------------------------------- /mstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Metin KAYA 3 | * 4 | * April 2008, Istanbul/TURKIYE 5 | * http://www.enderunix.org/metfs/ 6 | * 7 | * $Id: mstring.h,v 1.2 2008/04/10 04:21:17 mk Exp $ 8 | */ 9 | 10 | /*- 11 | * These string functions are ported from OpenBSD source code and copyrights 12 | * are stated below: 13 | * 14 | * Copyright (c) 1998 Todd C. Miller 15 | * All rights reserved. 16 | * 17 | * Redistribution and use in source and binary forms, with or without 18 | * modification, are permitted provided that the following conditions 19 | * are met: 20 | * 1. Redistributions of source code must retain the above copyright 21 | * notice, this list of conditions and the following disclaimer. 22 | * 2. Redistributions in binary form must reproduce the above copyright 23 | * notice, this list of conditions and the following disclaimer in the 24 | * documentation and/or other materials provided with the distribution. 25 | * 3. The name of the author may not be used to endorse or promote products 26 | * derived from this software without specific prior written permission. 27 | * 28 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 29 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 30 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 31 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 32 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 33 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 34 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 36 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 37 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | */ 40 | 41 | #ifndef _MSTRING_H_ 42 | #define _MSTRING_H_ 43 | 44 | #include 45 | 46 | #include 47 | 48 | size_t 49 | mstrlen(const char *s); 50 | 51 | char * 52 | mstrdup(const char *str); 53 | 54 | size_t 55 | mstrcat(char *dst, const char *src, size_t size); 56 | 57 | size_t 58 | mstrcpy(char *dst, const char *src, size_t size); 59 | 60 | char * 61 | mstrstr(char *string, char *find); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /readpassphrase.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Metin KAYA 3 | * 4 | * April 2008, Istanbul/TURKIYE 5 | * http://www.enderunix.org/metfs/ 6 | * 7 | * $Id: readpassphrase.c,v 1.2 2008/04/10 04:21:17 mk Exp $ 8 | */ 9 | 10 | /* $OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $ */ 11 | 12 | /* 13 | * Copyright (c) 2000 Todd C. Miller 14 | * All rights reserved. 15 | * 16 | * Redistribution and use in source and binary forms, with or without 17 | * modification, are permitted provided that the following conditions 18 | * are met: 19 | * 1. Redistributions of source code must retain the above copyright 20 | * notice, this list of conditions and the following disclaimer. 21 | * 2. Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the distribution. 24 | * 3. The name of the author may not be used to endorse or promote products 25 | * derived from this software without specific prior written permission. 26 | * 27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 28 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 29 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 30 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 33 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 35 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 36 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #if defined(LIBC_SCCS) && !defined(lint) 40 | static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; 41 | #endif /* LIBC_SCCS and not lint */ 42 | 43 | #ifndef HAVE_READPASSPHRASE 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include "readpassphrase.h" 57 | 58 | #ifdef TCSASOFT 59 | # define _T_FLUSH (TCSAFLUSH|TCSASOFT) 60 | #else 61 | # define _T_FLUSH (TCSAFLUSH) 62 | #endif 63 | 64 | /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ 65 | #if !defined(_POSIX_VDISABLE) && defined(VDISABLE) 66 | # define _POSIX_VDISABLE VDISABLE 67 | #endif 68 | 69 | static volatile sig_atomic_t signo; 70 | 71 | static void handler(int); 72 | 73 | char * 74 | readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) 75 | { 76 | ssize_t nr; 77 | int input, output, save_errno; 78 | char ch, *p, *end; 79 | struct termios term, oterm; 80 | struct sigaction sa, saveint, savehup, savequit, saveterm; 81 | struct sigaction savetstp, savettin, savettou; 82 | 83 | /* I suppose we could alloc on demand in this case (XXX). */ 84 | if (bufsiz == 0) { 85 | errno = EINVAL; 86 | return(NULL); 87 | } 88 | 89 | restart: 90 | /* 91 | * Read and write to /dev/tty if available. If not, read from 92 | * stdin and write to stderr unless a tty is required. 93 | */ 94 | if ((input = output = open(_PATH_TTY, O_RDWR)) == -1) { 95 | if (flags & RPP_REQUIRE_TTY) { 96 | errno = ENOTTY; 97 | return(NULL); 98 | } 99 | input = STDIN_FILENO; 100 | output = STDERR_FILENO; 101 | } 102 | 103 | /* 104 | * Catch signals that would otherwise cause the user to end 105 | * up with echo turned off in the shell. Don't worry about 106 | * things like SIGALRM and SIGPIPE for now. 107 | */ 108 | sigemptyset(&sa.sa_mask); 109 | sa.sa_flags = 0; /* don't restart system calls */ 110 | sa.sa_handler = handler; 111 | (void)sigaction(SIGINT, &sa, &saveint); 112 | (void)sigaction(SIGHUP, &sa, &savehup); 113 | (void)sigaction(SIGQUIT, &sa, &savequit); 114 | (void)sigaction(SIGTERM, &sa, &saveterm); 115 | (void)sigaction(SIGTSTP, &sa, &savetstp); 116 | (void)sigaction(SIGTTIN, &sa, &savettin); 117 | (void)sigaction(SIGTTOU, &sa, &savettou); 118 | 119 | /* Turn off echo if possible. */ 120 | if (tcgetattr(input, &oterm) == 0) { 121 | memcpy(&term, &oterm, sizeof(term)); 122 | if (!(flags & RPP_ECHO_ON)) 123 | term.c_lflag &= ~(ECHO | ECHONL); 124 | #ifdef VSTATUS 125 | if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) 126 | term.c_cc[VSTATUS] = _POSIX_VDISABLE; 127 | #endif 128 | (void)tcsetattr(input, _T_FLUSH, &term); 129 | } else { 130 | memset(&term, 0, sizeof(term)); 131 | memset(&oterm, 0, sizeof(oterm)); 132 | } 133 | 134 | (void)write(output, prompt, mstrlen(prompt)); 135 | end = buf + bufsiz - 1; 136 | for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { 137 | if (p < end) { 138 | if ((flags & RPP_SEVENBIT)) 139 | ch &= 0x7f; 140 | if (isalpha(ch)) { 141 | if ((flags & RPP_FORCELOWER)) 142 | ch = tolower(ch); 143 | if ((flags & RPP_FORCEUPPER)) 144 | ch = toupper(ch); 145 | } 146 | *p++ = ch; 147 | } 148 | } 149 | *p = '\0'; 150 | save_errno = errno; 151 | if (!(term.c_lflag & ECHO)) 152 | (void)write(output, "\n", 1); 153 | 154 | /* Restore old terminal settings and signals. */ 155 | if (memcmp(&term, &oterm, sizeof(term)) != 0) 156 | (void)tcsetattr(input, _T_FLUSH, &oterm); 157 | (void)sigaction(SIGINT, &saveint, NULL); 158 | (void)sigaction(SIGHUP, &savehup, NULL); 159 | (void)sigaction(SIGQUIT, &savequit, NULL); 160 | (void)sigaction(SIGTERM, &saveterm, NULL); 161 | (void)sigaction(SIGTSTP, &savetstp, NULL); 162 | (void)sigaction(SIGTTIN, &savettin, NULL); 163 | (void)sigaction(SIGTTOU, &savettou, NULL); 164 | if (input != STDIN_FILENO) 165 | (void)close(input); 166 | 167 | /* 168 | * If we were interrupted by a signal, resend it to ourselves 169 | * now that we have restored the signal handlers. 170 | */ 171 | if (signo) { 172 | kill(getpid(), signo); 173 | switch (signo) { 174 | case SIGTSTP: 175 | case SIGTTIN: 176 | case SIGTTOU: 177 | signo = 0; 178 | goto restart; 179 | } 180 | } 181 | 182 | errno = save_errno; 183 | return(nr == -1 ? NULL : buf); 184 | } 185 | #endif /* HAVE_READPASSPHRASE */ 186 | 187 | #if 0 188 | char * 189 | getpass(const char *prompt) 190 | { 191 | static char buf[_PASSWORD_LEN + 1]; 192 | 193 | return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF)); 194 | } 195 | #endif 196 | 197 | static void handler(int s) 198 | { 199 | signo = s; 200 | } 201 | -------------------------------------------------------------------------------- /readpassphrase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Metin KAYA 3 | * 4 | * April 2008, Istanbul/TURKIYE 5 | * http://www.enderunix.org/metfs/ 6 | * 7 | * $Id: readpassphrase.h,v 1.2 2008/04/10 04:21:17 mk Exp $ 8 | */ 9 | 10 | /* $OpenBSD: readpassphrase.h,v 1.1 2000/11/21 00:48:38 millert Exp $ */ 11 | 12 | /* 13 | * Copyright (c) 2000 Todd C. Miller 14 | * All rights reserved. 15 | * 16 | * Redistribution and use in source and binary forms, with or without 17 | * modification, are permitted provided that the following conditions 18 | * are met: 19 | * 1. Redistributions of source code must retain the above copyright 20 | * notice, this list of conditions and the following disclaimer. 21 | * 2. Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the distribution. 24 | * 3. The name of the author may not be used to endorse or promote products 25 | * derived from this software without specific prior written permission. 26 | * 27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 28 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 29 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 30 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 33 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 34 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 35 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 36 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #ifndef _READPASSPHRASE_H_ 40 | #define _READPASSPHRASE_H_ 41 | 42 | #include 43 | #include "mstring.h" 44 | 45 | #ifndef HAVE_READPASSPHRASE 46 | 47 | #define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ 48 | #define RPP_ECHO_ON 0x01 /* Leave echo on. */ 49 | #define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ 50 | #define RPP_FORCELOWER 0x04 /* Force input to lower case. */ 51 | #define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ 52 | #define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ 53 | 54 | #ifdef __cplusplus 55 | extern "C" 56 | #endif 57 | char * 58 | readpassphrase(const char *prompt, char *buf, size_t bufSize, int flags); 59 | 60 | #endif /* HAVE_READPASSPHRASE */ 61 | 62 | #endif /* !_READPASSPHRASE_H_ */ 63 | --------------------------------------------------------------------------------