diff options
Diffstat (limited to 'mount/lomount.c')
-rw-r--r-- | mount/lomount.c | 111 |
1 files changed, 102 insertions, 9 deletions
diff --git a/mount/lomount.c b/mount/lomount.c index b17ed5c8..fd12ce29 100644 --- a/mount/lomount.c +++ b/mount/lomount.c @@ -18,12 +18,17 @@ #include "loop.h" #include "lomount.h" +#include "rmd160.h" #include "xstrncpy.h" #include "nls.h" #include "sundries.h" #include "xmalloc.h" #include "pathnames.h" +#ifndef HAVE_VERSIONSORT +# include "strverscmp.h" +#endif + #define SIZE(a) (sizeof(a)/sizeof(a[0])) #ifdef LOOP_SET_FD @@ -668,7 +673,8 @@ digits_only(const char *s) { */ int set_loop(const char *device, const char *file, unsigned long long offset, - unsigned long long sizelimit, const char *encryption, int pfd, int *options) { + unsigned long long sizelimit, const char *encryption, int pfd, int *options, + int keysz, int hash_pass) { struct loop_info64 loopinfo64; int fd, ffd, mode, i; char *pass; @@ -736,20 +742,87 @@ set_loop(const char *device, const char *file, unsigned long long offset, } #endif + + if (keysz==0) + keysz=LO_KEY_SIZE*8; switch (loopinfo64.lo_encrypt_type) { case LO_CRYPT_NONE: loopinfo64.lo_encrypt_key_size = 0; break; case LO_CRYPT_XOR: pass = getpass(_("Password: ")); - goto gotpass; - default: - pass = xgetpass(pfd, _("Password: ")); - gotpass: memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE); xstrncpy((char *)loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE); memset(pass, 0, strlen(pass)); loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE; + break; +#define HASHLENGTH 20 +#if 0 + case LO_CRYPT_FISH2: + case LO_CRYPT_BLOW: + case LO_CRYPT_IDEA: + case LO_CRYPT_CAST128: + case LO_CRYPT_SERPENT: + case LO_CRYPT_MARS: + case LO_CRYPT_RC6: + case LO_CRYPT_3DES: + case LO_CRYPT_DFC: + case LO_CRYPT_RIJNDAEL: + { + char keybits[2*HASHLENGTH]; + char *pass2; + int passwdlen; + int keylength; + int i; + + pass = xgetpass(pfd, _("Password: ")); + passwdlen=strlen(pass); + pass2=malloc(passwdlen+2); + pass2[0]='A'; + strcpy(pass2+1,pass); + rmd160_hash_buffer(keybits,pass,passwdlen); + rmd160_hash_buffer(keybits+HASHLENGTH,pass2,passwdlen+1); + memcpy((char*)loopinfo64.lo_encrypt_key,keybits,2*HASHLENGTH); + memset(pass, 0, passwdlen); + memset(pass2, 0, passwdlen+1); + free(pass2); + keylength=0; + for(i=0; crypt_type_tbl[i].id != -1; i++){ + if(loopinfo64.lo_encrypt_type == crypt_type_tbl[i].id){ + keylength = crypt_type_tbl[i].keylength; + break; + } + } + loopinfo64.lo_encrypt_key_size=keylength; + break; + } +#endif + default: + if (hash_pass) { + char keybits[2*HASHLENGTH]; + char *pass2; + int passwdlen; + + pass = xgetpass(pfd, _("Password: ")); + passwdlen=strlen(pass); + pass2=malloc(passwdlen+2); + pass2[0]='A'; + strcpy(pass2+1,pass); + rmd160_hash_buffer(keybits,pass,passwdlen); + rmd160_hash_buffer(keybits+HASHLENGTH,pass2,passwdlen+1); + memset(pass, 0, passwdlen); + memset(pass2, 0, passwdlen+1); + free(pass2); + + memcpy((char*)loopinfo64.lo_encrypt_key,keybits,keysz/8); + loopinfo64.lo_encrypt_key_size = keysz/8; + } else { + pass = xgetpass(pfd, _("Password: ")); + memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE); + xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE); + memset(pass, 0, strlen(pass)); + loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE; + } } if (ioctl(fd, LOOP_SET_FD, ffd) < 0) { @@ -856,8 +929,8 @@ mutter(void) { int set_loop(const char *device, const char *file, unsigned long long offset, - unsigned long long sizelimit, const char *encryption, int pfd, int *loopro, - int keysz, int hash_pass) { + unsigned long long sizelimit, const char *encryption, int pfd, int *options, + int keysz, int hash_pass) { mutter(); return 1; } @@ -903,6 +976,12 @@ usage(void) { " -p | --pass-fd <num> read passphrase from file descriptor <num>\n" " -r | --read-only setup read-only loop device\n" " --show print device name (with -f <file>)\n" + " -N | --nohashpass Do not hash the given password (Debian hashes)\n" + " -k | --keybits <num> specify number of bits in the hashed key given\n" + " to the cipher. Some ciphers support several key\n" + " sizes and might be more efficient with a smaller\n" + " key size. Key sizes < 128 are generally not\n" + " recommended\n" " -v | --verbose verbose mode\n\n")); exit(1); } @@ -910,11 +989,14 @@ usage(void) { int main(int argc, char **argv) { char *p, *offset, *sizelimit, *encryption, *passfd, *device, *file, *assoc; + char *keysize; int delete, find, c, all, capacity; int res = 0; int showdev = 0; int ro = 0; int pfd = -1; + int keysz = 0; + int hash_pass = 1; unsigned long long off, slimit; struct option longopts[] = { { "all", 0, 0, 'a' }, @@ -923,6 +1005,9 @@ main(int argc, char **argv) { { "encryption", 1, 0, 'e' }, { "find", 0, 0, 'f' }, { "help", 0, 0, 'h' }, + { "keybits", 1, 0, 'k' }, + { "nopasshash", 0, 0, 'N' }, + { "nohashpass", 0, 0, 'N' }, { "associated", 1, 0, 'j' }, { "offset", 1, 0, 'o' }, { "sizelimit", 1, 0, 128 }, @@ -941,12 +1026,13 @@ main(int argc, char **argv) { off = 0; slimit = 0; assoc = offset = sizelimit = encryption = passfd = NULL; + keysize = NULL; progname = argv[0]; if ((p = strrchr(progname, '/')) != NULL) progname = p+1; - while ((c = getopt_long(argc, argv, "acde:E:fhj:o:p:rsv", + while ((c = getopt_long(argc, argv, "acde:E:fhj:k:No:p:rsv", longopts, NULL)) != -1) { switch (c) { case 'a': @@ -970,6 +1056,11 @@ main(int argc, char **argv) { break; case 'j': assoc = optarg; + case 'k': + keysize = optarg; + break; + case 'N': + hash_pass = 0; break; case 'o': offset = optarg; @@ -1056,8 +1147,10 @@ main(int argc, char **argv) { else { if (passfd && sscanf(passfd, "%d", &pfd) != 1) usage(); + if (keysize && sscanf(keysize,"%d",&keysz) != 1) + usage(); do { - res = set_loop(device, file, off, slimit, encryption, pfd, &ro); + res = set_loop(device, file, off, slimit, encryption, pfd, &ro, keysz, hash_pass); if (res == 2 && find) { if (verbose) printf(_("stolen loop=%s...trying again\n"), |