Mercurial > vim
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); |