comparison src/fileio.c @ 2204:c493d6bfde09 vim73

A few more changes for encryption. Add test that encrypted file can be read.
author Bram Moolenaar <bram@vim.org>
date Fri, 21 May 2010 15:36:08 +0200
parents f60a0c9cbe6c
children 8c6a66e2b3cc
comparison
equal deleted inserted replaced
2203:dde812fb2247 2204:c493d6bfde09
31 31
32 #define BUFSIZE 8192 /* size of normal write buffer */ 32 #define BUFSIZE 8192 /* size of normal write buffer */
33 #define SMBUFSIZE 256 /* size of emergency write buffer */ 33 #define SMBUFSIZE 256 /* size of emergency write buffer */
34 34
35 #ifdef FEAT_CRYPT 35 #ifdef FEAT_CRYPT
36 char crypt_magic_01[] = "VimCrypt~01!"; 36 /* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */
37 char crypt_magic_02[] = "VimCrypt~02!"; 37 static char *crypt_magic[] = {"VimCrypt~01!", "VimCrypt~02!"};
38 static char crypt_magic_head[] = "VimCrypt~";
38 # define CRYPT_MAGIC_LEN 12 /* must be multiple of 4! */ 39 # define CRYPT_MAGIC_LEN 12 /* must be multiple of 4! */
39 40 static int crypt_seed_len[] = {0, 8};
40 /* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */
41 static char *crypt_magic[] = {crypt_magic_01, crypt_magic_02};
42 static int crypt_seed_len[] = {0, 8};
43 #define CRYPT_SEED_LEN_MAX 8 41 #define CRYPT_SEED_LEN_MAX 8
44 #endif 42 #endif
45 43
46 /* Is there any system that doesn't have access()? */ 44 /* Is there any system that doesn't have access()? */
47 #define USE_MCH_ACCESS 45 #define USE_MCH_ACCESS
59 #ifdef FEAT_VIMINFO 57 #ifdef FEAT_VIMINFO
60 static void check_marks_read __ARGS((void)); 58 static void check_marks_read __ARGS((void));
61 #endif 59 #endif
62 #ifdef FEAT_CRYPT 60 #ifdef FEAT_CRYPT
63 static int get_crypt_method __ARGS((char *ptr, int len)); 61 static int get_crypt_method __ARGS((char *ptr, int len));
64 static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, long *filesizep, int newfile)); 62 static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, long *filesizep, int newfile, int *did_ask));
65 #endif 63 #endif
66 #ifdef UNIX 64 #ifdef UNIX
67 static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime)); 65 static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime));
68 #endif 66 #endif
69 static int set_rw_fname __ARGS((char_u *fname, char_u *sfname)); 67 static int set_rw_fname __ARGS((char_u *fname, char_u *sfname));
251 char_u *p; 249 char_u *p;
252 long filesize = 0; 250 long filesize = 0;
253 int skip_read = FALSE; 251 int skip_read = FALSE;
254 #ifdef FEAT_CRYPT 252 #ifdef FEAT_CRYPT
255 char_u *cryptkey = NULL; 253 char_u *cryptkey = NULL;
254 int did_ask_for_key = FALSE;
256 #endif 255 #endif
257 int split = 0; /* number of split lines */ 256 int split = 0; /* number of split lines */
258 #define UNKNOWN 0x0fffffff /* file size is unknown */ 257 #define UNKNOWN 0x0fffffff /* file size is unknown */
259 linenr_T linecnt; 258 linenr_T linecnt;
260 int error = FALSE; /* errors encountered */ 259 int error = FALSE; /* errors encountered */
1410 /* 1409 /*
1411 * At start of file: Check for magic number of encryption. 1410 * At start of file: Check for magic number of encryption.
1412 */ 1411 */
1413 if (filesize == 0) 1412 if (filesize == 0)
1414 cryptkey = check_for_cryptkey(cryptkey, ptr, &size, 1413 cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
1415 &filesize, newfile); 1414 &filesize, newfile, &did_ask_for_key);
1416 /* 1415 /*
1417 * Decrypt the read bytes. 1416 * Decrypt the read bytes.
1418 */ 1417 */
1419 if (cryptkey != NULL && size > 0) 1418 if (cryptkey != NULL && size > 0)
1420 for (p = ptr; p < ptr + size; ++p) 1419 for (p = ptr; p < ptr + size; ++p)
2809 if (len < (CRYPT_MAGIC_LEN + crypt_seed_len[i])) 2808 if (len < (CRYPT_MAGIC_LEN + crypt_seed_len[i]))
2810 continue; 2809 continue;
2811 if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0) 2810 if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0)
2812 return i; 2811 return i;
2813 } 2812 }
2813
2814 i = STRLEN(crypt_magic_head);
2815 if (len >= i && memcmp(ptr, crypt_magic_head, i) == 0)
2816 EMSG(_("E821: File is encrypted with unknown method"));
2817
2814 return -1; 2818 return -1;
2815 } 2819 }
2816 2820
2817 /* 2821 /*
2818 * Check for magic number used for encryption. Applies to the current buffer. 2822 * Check for magic number used for encryption. Applies to the current buffer.
2819 * If found, the magic number is removed from ptr[*sizep] and *sizep and 2823 * If found, the magic number is removed from ptr[*sizep] and *sizep and
2820 * *filesizep are updated. 2824 * *filesizep are updated.
2821 * Return the (new) encryption key, NULL for no encryption. 2825 * Return the (new) encryption key, NULL for no encryption.
2822 */ 2826 */
2823 static char_u * 2827 static char_u *
2824 check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile) 2828 check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, did_ask)
2825 char_u *cryptkey; /* previous encryption key or NULL */ 2829 char_u *cryptkey; /* previous encryption key or NULL */
2826 char_u *ptr; /* pointer to read bytes */ 2830 char_u *ptr; /* pointer to read bytes */
2827 long *sizep; /* length of read bytes */ 2831 long *sizep; /* length of read bytes */
2828 long *filesizep; /* nr of bytes used from file */ 2832 long *filesizep; /* nr of bytes used from file */
2829 int newfile; /* editing a new buffer */ 2833 int newfile; /* editing a new buffer */
2834 int *did_ask; /* flag: whether already asked for key */
2830 { 2835 {
2831 int method = get_crypt_method((char *)ptr, *sizep); 2836 int method = get_crypt_method((char *)ptr, *sizep);
2832 2837
2833 if (method >= 0) 2838 if (method >= 0)
2834 { 2839 {
2835 curbuf->b_p_cm = method; 2840 curbuf->b_p_cm = method;
2836 use_crypt_method = method; 2841 use_crypt_method = method;
2837 if (method > 0) 2842 if (method > 0)
2838 (void)blowfish_self_test(); 2843 (void)blowfish_self_test();
2839 if (cryptkey == NULL) 2844 if (cryptkey == NULL && !*did_ask)
2840 { 2845 {
2841 if (*curbuf->b_p_key) 2846 if (*curbuf->b_p_key)
2842 cryptkey = curbuf->b_p_key; 2847 cryptkey = curbuf->b_p_key;
2843 else 2848 else
2844 { 2849 {
2845 /* When newfile is TRUE, store the typed key in the 'key' 2850 /* When newfile is TRUE, store the typed key in the 'key'
2846 * option and don't free it. bf needs hash of the key saved. 2851 * option and don't free it. bf needs hash of the key saved.
2847 */ 2852 * Don't ask for the key again when first time Enter was hit.
2853 * Happens when retrying to detect encoding. */
2848 cryptkey = get_crypt_key(newfile, FALSE); 2854 cryptkey = get_crypt_key(newfile, FALSE);
2855 *did_ask = TRUE;
2856
2849 /* check if empty key entered */ 2857 /* check if empty key entered */
2850 if (cryptkey != NULL && *cryptkey == NUL) 2858 if (cryptkey != NULL && *cryptkey == NUL)
2851 { 2859 {
2852 if (cryptkey != curbuf->b_p_key) 2860 if (cryptkey != curbuf->b_p_key)
2853 vim_free(cryptkey); 2861 vim_free(cryptkey);