]> granicus.if.org Git - vim/commitdiff
A few more changes for encryption. Add test that encrypted file can be read.
authorBram Moolenaar <Bram@vim.org>
Fri, 21 May 2010 13:36:08 +0000 (15:36 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 21 May 2010 13:36:08 +0000 (15:36 +0200)
runtime/doc/options.txt
runtime/doc/todo.txt
src/fileio.c
src/testdir/test71.in
src/testdir/test71.ok

index c07549d07933fae82025fef605e89946cbbbef83..3493a14bbc495dc5665141e6eb047a26a7d032ca 100644 (file)
@@ -2056,12 +2056,21 @@ A jump table for the options with a short description can be found at |Q_op|.
        Method used for encryption when the buffer is written to a file:
                                                        *pkzip*
                0       PkZip compatible method.  A weak kind of encryption.
-                       backwards compatible with Vim 7.2 and older.
+                       Backwards compatible with Vim 7.2 and older.
                                                        *blowfish*
-               1       Blowfish method.  Strong encryption.  Not compatible
-                       with Vim 7.2 and older.
+               1       Blowfish method.  Strong encryption.  Requires Vim 7.3
+                       or later, files can NOT be read by Vim 7.2 and older.
+                       This adds a "seed" to the file, every time you write
+                       the file the encrypted bytes will be different.
+
        When reading an encrypted file 'cryptmethod' will be set automatically
-       to detected method for the file being read.
+       to the detected method of the file being read.  Thus if you write it
+       without changing 'cryptmethod' the same method will be used.
+       Changing 'cryptmethod' does not mark the file as modified, you have to
+       explicitly write it when not making modifications.
+       Also see |:X|.
+       When a new encryption method is added in a later version of Vim, and
+       the current version does not recognize it, you will get *E821* .
 
 
                                                *'cscopepathcomp'* *'cspc'*
index cd89dba7e9a1ea674ed9e208ebb02a855dee31a5..9987cafff59eca5706214a0678bb04e1646c9931 100644 (file)
@@ -30,16 +30,6 @@ be worked on, but only if you sponsor Vim development.  See |sponsor|.
                                                        *known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-Crypt update:
-- Make sure test71 fails when blowfish test fails.
-- When not full match with magic, check for head and give warning about
-  unsupported crypt method.
-- if 'enc' is ucs-2, does utf-8 to ucs-2 encoding always work for seed?
-
-After patch 7.2.407 a backslash before a newline is turned into a NUL. (Andy
-Wokula, 2010 May 18)
-No longer possible to insert a line break?  Roll back the patch?
-
 "g8" doesn't produce right value on NUL. Patch (Dominique Pelle, 2010 May 18)
 
 Include cabal and obj syntax files. (Vincent Berthoux, 2010 May 16)
index ad5fddde235db458e5b0a2d7e253e26f7553b6c2..8cf799d2bfa770fa444a53fe25af8102069e5acd 100644 (file)
 #define SMBUFSIZE      256     /* size of emergency write buffer */
 
 #ifdef FEAT_CRYPT
-char crypt_magic_01[] = "VimCrypt~01!";
-char crypt_magic_02[] = "VimCrypt~02!";
-# define CRYPT_MAGIC_LEN       12              /* must be multiple of 4! */
-
 /* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */
-static char   *crypt_magic[] = {crypt_magic_01, crypt_magic_02};
-static int    crypt_seed_len[] = {0, 8};
+static char    *crypt_magic[] = {"VimCrypt~01!", "VimCrypt~02!"};
+static char    crypt_magic_head[] = "VimCrypt~";
+# define CRYPT_MAGIC_LEN       12              /* must be multiple of 4! */
+static int     crypt_seed_len[] = {0, 8};
 #define CRYPT_SEED_LEN_MAX 8
 #endif
 
@@ -61,7 +59,7 @@ static void check_marks_read __ARGS((void));
 #endif
 #ifdef FEAT_CRYPT
 static int get_crypt_method __ARGS((char *ptr, int len));
-static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, long *filesizep, int newfile));
+static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, long *filesizep, int newfile, int *did_ask));
 #endif
 #ifdef UNIX
 static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime));
@@ -253,6 +251,7 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
     int                skip_read = FALSE;
 #ifdef FEAT_CRYPT
     char_u     *cryptkey = NULL;
+    int                did_ask_for_key = FALSE;
 #endif
     int                split = 0;              /* number of split lines */
 #define UNKNOWN         0x0fffffff             /* file size is unknown */
@@ -1412,7 +1411,7 @@ retry:
                 */
                if (filesize == 0)
                    cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
-                                                         &filesize, newfile);
+                                       &filesize, newfile, &did_ask_for_key);
                /*
                 * Decrypt the read bytes.
                 */
@@ -2811,6 +2810,11 @@ get_crypt_method(ptr, len)
        if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0)
            return i;
     }
+
+    i = STRLEN(crypt_magic_head);
+    if (len >= i && memcmp(ptr, crypt_magic_head, i) == 0)
+       EMSG(_("E821: File is encrypted with unknown method"));
+
     return -1;
 }
 
@@ -2821,12 +2825,13 @@ get_crypt_method(ptr, len)
  * Return the (new) encryption key, NULL for no encryption.
  */
     static char_u *
-check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
+check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, did_ask)
     char_u     *cryptkey;      /* previous encryption key or NULL */
     char_u     *ptr;           /* pointer to read bytes */
     long       *sizep;         /* length of read bytes */
     long       *filesizep;     /* nr of bytes used from file */
     int                newfile;        /* editing a new buffer */
+    int                *did_ask;       /* flag: whether already asked for key */
 {
     int method = get_crypt_method((char *)ptr, *sizep);
 
@@ -2836,7 +2841,7 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
        use_crypt_method = method;
        if (method > 0)
            (void)blowfish_self_test();
-       if (cryptkey == NULL)
+       if (cryptkey == NULL && !*did_ask)
        {
            if (*curbuf->b_p_key)
                cryptkey = curbuf->b_p_key;
@@ -2844,8 +2849,11 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
            {
                /* When newfile is TRUE, store the typed key in the 'key'
                 * option and don't free it.  bf needs hash of the key saved.
-                */
+                * Don't ask for the key again when first time Enter was hit.
+                * Happens when retrying to detect encoding. */
                cryptkey = get_crypt_key(newfile, FALSE);
+               *did_ask = TRUE;
+
                /* check if empty key entered */
                if (cryptkey != NULL && *cryptkey == NUL)
                {
index a2eadd3c1b84697b793d3d239aac2d08340f7556..717b66026ac7da6e276e3971b5cc79227d185420 100644 (file)
@@ -2,10 +2,14 @@ Test for encryption.
 
 STARTTEST
 :so small.vim
-:/^start of testfile/+1
-:let lines = getline('.', '$')
-:new
-:call append(0, lines)
+:/^start of text/+1
+:let text_lines = getline('.', line('.') + 2)
+:/^start of cm=0 bytes/+1
+:let cm0_bytes = getline('.', '.')
+:/^start of cm=1 bytes/+1
+:let cm1_bytes = getline('.', '.')
+:bwipe
+:call append(0, text_lines)
 :$d
 :X
 foobar
@@ -14,10 +18,11 @@ foobar
 :bwipe!
 :e Xtestfile
 foobar
-:let dec1_lines = getline('.', '$')
-:%s/^/2/
+:let cm0_read_back = getline('.', '$')
 :set key=
 :set cryptmethod=1
+:" If the blowfish test fails 'cryptmethod' will be 0 now.
+:%s/^/\=&cryptmethod == 1 ? "OK " : "blowfish test failed "/
 :X
 barfoo
 barfoo
@@ -25,13 +30,46 @@ barfoo
 :bwipe!
 :e Xtestfile
 barfoo
-:call append(0, dec1_lines)
-:set key=
+:let cm1_read_back = getline('.', '$')
+:bwipe!
+:set bin noeol key=
+:call append(0, cm0_bytes)
+:$d
+:set fenc=latin1
+:w! Xtestfile
+:bwipe!
+:set nobin
+:e Xtestfile
+foofoo
+:let cm0_read_bin = getline('.', '$')
+:bwipe!
+:set bin noeol key=
+:call append(0, cm1_bytes)
+:$d
+:set fenc=latin1
+:w! Xtestfile
+:bwipe!
+:set nobin
+:e Xtestfile
+barbar
+:call append(0, cm0_read_bin)
+:call append(0, cm1_read_back)
+:call append(0, cm0_read_back)
+:set key= fenc=latin1
 :w! test.out
 :qa!
 ENDTEST
 
-start of testfile
+start of text
 01234567890123456789012345678901234567
 line 2  foo bar blah
 line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+end of text
+
+start of cm=0 bytes
+VimCrypt~01!\ 6\1clV'Þ}Mg ê£V©ç\aE#3\8e2Ué\97
+end of cm=0 bytes
+
+start of cm=1 bytes
+VimCrypt~02!¨Ò9Z\9aÙ¢èì\94F¼èÃ[,ì\94\83\80\ fz¼Ö\13è»\82\fy¾Ô(
+end of cm=1 bytes
index 5820892b6e7c8aaa29e6ca1a5b320e20b070c0f6..24652c4380a078a9555bf2eecf7321fd489aa7bd 100644 (file)
@@ -1,6 +1,10 @@
 01234567890123456789012345678901234567
 line 2  foo bar blah
 line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-201234567890123456789012345678901234567
-2line 2  foo bar blah
-2line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+OK 01234567890123456789012345678901234567
+OK line 2  foo bar blah
+OK line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+1234567890
+aábbccddeëff
+asdfasdfasdf
+0001112223333