Mercurial > vim
annotate src/crypt.c @ 11416:32aed0993813 v8.0.0592
patch 8.0.0592: if a job writes to a buffer screen is not updated
commit https://github.com/vim/vim/commit/29ae377ea7039874337bc79ace9ab2b37b9056e5
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Apr 30 19:39:39 2017 +0200
patch 8.0.0592: if a job writes to a buffer screen is not updated
Problem: If a job writes to a buffer and the user is typing a command, the
screen isn't updated. When a message is displayed the changed
buffer may cause it to be cleared. (Ramel Eshed)
Solution: Update the screen and then the command line if the screen didn't
scroll. Avoid inserting screen lines, as it clears any message.
Update the status line when the buffer changed.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 30 Apr 2017 19:45:03 +0200 |
parents | 4aead6a9b7a9 |
children | ac42c4b11dbc |
rev | line source |
---|---|
10042
4aead6a9b7a9
commit https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47
Christian Brabandt <cb@256bit.org>
parents:
7817
diff
changeset
|
1 /* vi:set ts=8 sts=4 sw=4 noet: |
6122 | 2 * |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read copying and usage conditions. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 | |
10 /* | |
11 * crypt.c: Generic encryption support. | |
12 */ | |
13 #include "vim.h" | |
14 | |
15 #if defined(FEAT_CRYPT) || defined(PROTO) | |
16 /* | |
17 * Optional encryption support. | |
18 * Mohsin Ahmed, mosh@sasi.com, 1998-09-24 | |
19 * Based on zip/crypt sources. | |
20 * Refactored by David Leadbeater, 2014. | |
21 * | |
22 * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to | |
23 * most countries. There are a few exceptions, but that still should not be a | |
24 * problem since this code was originally created in Europe and India. | |
25 * | |
26 * Blowfish addition originally made by Mohsin Ahmed, | |
27 * http://www.cs.albany.edu/~mosh 2010-03-14 | |
28 * Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html) | |
29 * and sha256 by Christophe Devine. | |
30 */ | |
31 | |
32 typedef struct { | |
33 char *name; /* encryption name as used in 'cryptmethod' */ | |
34 char *magic; /* magic bytes stored in file header */ | |
35 int salt_len; /* length of salt, or 0 when not using salt */ | |
36 int seed_len; /* length of seed, or 0 when not using salt */ | |
37 int works_inplace; /* encryption/decryption can be done in-place */ | |
38 int whole_undofile; /* whole undo file is encrypted */ | |
39 | |
40 /* Optional function pointer for a self-test. */ | |
41 int (* self_test_fn)(); | |
42 | |
43 /* Function pointer for initializing encryption/decription. */ | |
44 void (* init_fn)(cryptstate_T *state, char_u *key, | |
45 char_u *salt, int salt_len, char_u *seed, int seed_len); | |
46 | |
47 /* Function pointers for encoding/decoding from one buffer into another. | |
48 * Optional, however, these or the _buffer ones should be configured. */ | |
49 void (*encode_fn)(cryptstate_T *state, char_u *from, size_t len, | |
50 char_u *to); | |
51 void (*decode_fn)(cryptstate_T *state, char_u *from, size_t len, | |
52 char_u *to); | |
53 | |
54 /* Function pointers for encoding and decoding, can buffer data if needed. | |
55 * Optional (however, these or the above should be configured). */ | |
56 long (*encode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len, | |
57 char_u **newptr); | |
58 long (*decode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len, | |
59 char_u **newptr); | |
60 | |
61 /* Function pointers for in-place encoding and decoding, used for | |
62 * crypt_*_inplace(). "from" and "to" arguments will be equal. | |
63 * These may be the same as decode_fn and encode_fn above, however an | |
64 * algorithm may implement them in a way that is not interchangeable with | |
65 * the crypt_(en|de)code() interface (for example because it wishes to add | |
66 * padding to files). | |
67 * This method is used for swap and undo files which have a rigid format. | |
68 */ | |
69 void (*encode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len, | |
70 char_u *p2); | |
71 void (*decode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len, | |
72 char_u *p2); | |
73 } cryptmethod_T; | |
74 | |
75 /* index is method_nr of cryptstate_T, CRYPT_M_* */ | |
76 static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = { | |
77 /* PK_Zip; very weak */ | |
78 { | |
79 "zip", | |
80 "VimCrypt~01!", | |
81 0, | |
82 0, | |
83 TRUE, | |
84 FALSE, | |
85 NULL, | |
86 crypt_zip_init, | |
87 crypt_zip_encode, crypt_zip_decode, | |
88 NULL, NULL, | |
89 crypt_zip_encode, crypt_zip_decode, | |
90 }, | |
91 | |
92 /* Blowfish/CFB + SHA-256 custom key derivation; implementation issues. */ | |
93 { | |
94 "blowfish", | |
95 "VimCrypt~02!", | |
96 8, | |
97 8, | |
98 TRUE, | |
99 FALSE, | |
100 blowfish_self_test, | |
101 crypt_blowfish_init, | |
102 crypt_blowfish_encode, crypt_blowfish_decode, | |
103 NULL, NULL, | |
104 crypt_blowfish_encode, crypt_blowfish_decode, | |
105 }, | |
106 | |
107 /* Blowfish/CFB + SHA-256 custom key derivation; fixed. */ | |
108 { | |
109 "blowfish2", | |
110 "VimCrypt~03!", | |
111 8, | |
112 8, | |
113 TRUE, | |
114 TRUE, | |
115 blowfish_self_test, | |
116 crypt_blowfish_init, | |
117 crypt_blowfish_encode, crypt_blowfish_decode, | |
118 NULL, NULL, | |
119 crypt_blowfish_encode, crypt_blowfish_decode, | |
120 }, | |
121 }; | |
122 | |
123 #define CRYPT_MAGIC_LEN 12 /* cannot change */ | |
124 static char crypt_magic_head[] = "VimCrypt~"; | |
125 | |
126 /* | |
127 * Return int value for crypt method name. | |
128 * 0 for "zip", the old method. Also for any non-valid value. | |
129 * 1 for "blowfish". | |
130 * 2 for "blowfish2". | |
131 */ | |
132 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
133 crypt_method_nr_from_name(char_u *name) |
6122 | 134 { |
135 int i; | |
136 | |
137 for (i = 0; i < CRYPT_M_COUNT; ++i) | |
138 if (STRCMP(name, cryptmethods[i].name) == 0) | |
139 return i; | |
140 return 0; | |
141 } | |
142 | |
143 /* | |
144 * Get the crypt method used for a file from "ptr[len]", the magic text at the | |
145 * start of the file. | |
146 * Returns -1 when no encryption used. | |
147 */ | |
148 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
149 crypt_method_nr_from_magic(char *ptr, int len) |
6122 | 150 { |
151 int i; | |
152 | |
153 if (len < CRYPT_MAGIC_LEN) | |
154 return -1; | |
155 | |
156 for (i = 0; i < CRYPT_M_COUNT; i++) | |
157 if (memcmp(ptr, cryptmethods[i].magic, CRYPT_MAGIC_LEN) == 0) | |
158 return i; | |
159 | |
160 i = (int)STRLEN(crypt_magic_head); | |
161 if (len >= i && memcmp(ptr, crypt_magic_head, i) == 0) | |
162 EMSG(_("E821: File is encrypted with unknown method")); | |
163 | |
164 return -1; | |
165 } | |
166 | |
167 /* | |
168 * Return TRUE if the crypt method for "method_nr" can be done in-place. | |
169 */ | |
170 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
171 crypt_works_inplace(cryptstate_T *state) |
6122 | 172 { |
173 return cryptmethods[state->method_nr].works_inplace; | |
174 } | |
175 | |
176 /* | |
177 * Get the crypt method for buffer "buf" as a number. | |
178 */ | |
179 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
180 crypt_get_method_nr(buf_T *buf) |
6122 | 181 { |
182 return crypt_method_nr_from_name(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm); | |
183 } | |
184 | |
185 /* | |
186 * Return TRUE when the buffer uses an encryption method that encrypts the | |
187 * whole undo file, not only the text. | |
188 */ | |
189 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
190 crypt_whole_undofile(int method_nr) |
6122 | 191 { |
192 return cryptmethods[method_nr].whole_undofile; | |
193 } | |
194 | |
195 /* | |
196 * Get crypt method specifc length of the file header in bytes. | |
197 */ | |
198 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
199 crypt_get_header_len(int method_nr) |
6122 | 200 { |
201 return CRYPT_MAGIC_LEN | |
202 + cryptmethods[method_nr].salt_len | |
203 + cryptmethods[method_nr].seed_len; | |
204 } | |
205 | |
206 /* | |
207 * Set the crypt method for buffer "buf" to "method_nr" using the int value as | |
208 * returned by crypt_method_nr_from_name(). | |
209 */ | |
210 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
211 crypt_set_cm_option(buf_T *buf, int method_nr) |
6122 | 212 { |
213 free_string_option(buf->b_p_cm); | |
214 buf->b_p_cm = vim_strsave((char_u *)cryptmethods[method_nr].name); | |
215 } | |
216 | |
217 /* | |
218 * If the crypt method for the current buffer has a self-test, run it and | |
219 * return OK/FAIL. | |
220 */ | |
221 int | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
222 crypt_self_test(void) |
6122 | 223 { |
224 int method_nr = crypt_get_method_nr(curbuf); | |
225 | |
226 if (cryptmethods[method_nr].self_test_fn == NULL) | |
227 return OK; | |
228 return cryptmethods[method_nr].self_test_fn(); | |
229 } | |
230 | |
231 /* | |
232 * Allocate a crypt state and initialize it. | |
233 */ | |
234 cryptstate_T * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
235 crypt_create( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
236 int method_nr, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
237 char_u *key, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
238 char_u *salt, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
239 int salt_len, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
240 char_u *seed, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
241 int seed_len) |
6122 | 242 { |
243 cryptstate_T *state = (cryptstate_T *)alloc((int)sizeof(cryptstate_T)); | |
244 | |
245 state->method_nr = method_nr; | |
246 cryptmethods[method_nr].init_fn(state, key, salt, salt_len, seed, seed_len); | |
247 return state; | |
248 } | |
249 | |
250 /* | |
251 * Allocate a crypt state from a file header and initialize it. | |
252 * Assumes that header contains at least the number of bytes that | |
253 * crypt_get_header_len() returns for "method_nr". | |
254 */ | |
255 cryptstate_T * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
256 crypt_create_from_header( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
257 int method_nr, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
258 char_u *key, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
259 char_u *header) |
6122 | 260 { |
261 char_u *salt = NULL; | |
262 char_u *seed = NULL; | |
263 int salt_len = cryptmethods[method_nr].salt_len; | |
264 int seed_len = cryptmethods[method_nr].seed_len; | |
265 | |
266 if (salt_len > 0) | |
267 salt = header + CRYPT_MAGIC_LEN; | |
268 if (seed_len > 0) | |
269 seed = header + CRYPT_MAGIC_LEN + salt_len; | |
270 | |
271 return crypt_create(method_nr, key, salt, salt_len, seed, seed_len); | |
272 } | |
273 | |
274 /* | |
275 * Read the crypt method specific header data from "fp". | |
276 * Return an allocated cryptstate_T or NULL on error. | |
277 */ | |
278 cryptstate_T * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
279 crypt_create_from_file(FILE *fp, char_u *key) |
6122 | 280 { |
281 int method_nr; | |
282 int header_len; | |
283 char magic_buffer[CRYPT_MAGIC_LEN]; | |
284 char_u *buffer; | |
285 cryptstate_T *state; | |
286 | |
287 if (fread(magic_buffer, CRYPT_MAGIC_LEN, 1, fp) != 1) | |
288 return NULL; | |
289 method_nr = crypt_method_nr_from_magic(magic_buffer, CRYPT_MAGIC_LEN); | |
290 if (method_nr < 0) | |
291 return NULL; | |
292 | |
293 header_len = crypt_get_header_len(method_nr); | |
294 if ((buffer = alloc(header_len)) == NULL) | |
295 return NULL; | |
296 mch_memmove(buffer, magic_buffer, CRYPT_MAGIC_LEN); | |
297 if (header_len > CRYPT_MAGIC_LEN | |
298 && fread(buffer + CRYPT_MAGIC_LEN, | |
299 header_len - CRYPT_MAGIC_LEN, 1, fp) != 1) | |
300 { | |
301 vim_free(buffer); | |
302 return NULL; | |
303 } | |
304 | |
305 state = crypt_create_from_header(method_nr, key, buffer); | |
306 vim_free(buffer); | |
307 return state; | |
308 } | |
309 | |
310 /* | |
311 * Allocate a cryptstate_T for writing and initialize it with "key". | |
312 * Allocates and fills in the header and stores it in "header", setting | |
313 * "header_len". The header may include salt and seed, depending on | |
314 * cryptmethod. Caller must free header. | |
315 * Returns the state or NULL on failure. | |
316 */ | |
317 cryptstate_T * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
318 crypt_create_for_writing( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
319 int method_nr, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
320 char_u *key, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
321 char_u **header, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
322 int *header_len) |
6122 | 323 { |
324 int len = crypt_get_header_len(method_nr); | |
325 char_u *salt = NULL; | |
326 char_u *seed = NULL; | |
327 int salt_len = cryptmethods[method_nr].salt_len; | |
328 int seed_len = cryptmethods[method_nr].seed_len; | |
329 cryptstate_T *state; | |
330 | |
331 *header_len = len; | |
332 *header = alloc(len); | |
333 if (*header == NULL) | |
334 return NULL; | |
335 | |
336 mch_memmove(*header, cryptmethods[method_nr].magic, CRYPT_MAGIC_LEN); | |
337 if (salt_len > 0 || seed_len > 0) | |
338 { | |
339 if (salt_len > 0) | |
340 salt = *header + CRYPT_MAGIC_LEN; | |
341 if (seed_len > 0) | |
342 seed = *header + CRYPT_MAGIC_LEN + salt_len; | |
343 | |
344 /* TODO: Should this be crypt method specific? (Probably not worth | |
345 * it). sha2_seed is pretty bad for large amounts of entropy, so make | |
346 * that into something which is suitable for anything. */ | |
347 sha2_seed(salt, salt_len, seed, seed_len); | |
348 } | |
349 | |
350 state = crypt_create(method_nr, key, salt, salt_len, seed, seed_len); | |
351 if (state == NULL) | |
352 { | |
353 vim_free(*header); | |
354 *header = NULL; | |
355 } | |
356 return state; | |
357 } | |
358 | |
359 /* | |
360 * Free the crypt state. | |
361 */ | |
362 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
363 crypt_free_state(cryptstate_T *state) |
6122 | 364 { |
365 vim_free(state->method_state); | |
366 vim_free(state); | |
367 } | |
368 | |
369 /* | |
370 * Encode "from[len]" and store the result in a newly allocated buffer, which | |
371 * is stored in "newptr". | |
372 * Return number of bytes in "newptr", 0 for need more or -1 on error. | |
373 */ | |
374 long | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
375 crypt_encode_alloc( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
376 cryptstate_T *state, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
377 char_u *from, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
378 size_t len, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
379 char_u **newptr) |
6122 | 380 { |
381 cryptmethod_T *method = &cryptmethods[state->method_nr]; | |
382 | |
383 if (method->encode_buffer_fn != NULL) | |
384 /* Has buffer function, pass through. */ | |
385 return method->encode_buffer_fn(state, from, len, newptr); | |
386 if (len == 0) | |
387 /* Not buffering, just return EOF. */ | |
6132 | 388 return (long)len; |
6122 | 389 |
6132 | 390 *newptr = alloc((long)len); |
6122 | 391 if (*newptr == NULL) |
392 return -1; | |
393 method->encode_fn(state, from, len, *newptr); | |
6132 | 394 return (long)len; |
6122 | 395 } |
396 | |
397 /* | |
398 * Decrypt "ptr[len]" and store the result in a newly allocated buffer, which | |
399 * is stored in "newptr". | |
400 * Return number of bytes in "newptr", 0 for need more or -1 on error. | |
401 */ | |
402 long | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
403 crypt_decode_alloc( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
404 cryptstate_T *state, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
405 char_u *ptr, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
406 long len, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
407 char_u **newptr) |
6122 | 408 { |
409 cryptmethod_T *method = &cryptmethods[state->method_nr]; | |
410 | |
411 if (method->decode_buffer_fn != NULL) | |
412 /* Has buffer function, pass through. */ | |
413 return method->decode_buffer_fn(state, ptr, len, newptr); | |
414 | |
415 if (len == 0) | |
416 /* Not buffering, just return EOF. */ | |
417 return len; | |
418 | |
419 *newptr = alloc(len); | |
420 if (*newptr == NULL) | |
421 return -1; | |
422 method->decode_fn(state, ptr, len, *newptr); | |
423 return len; | |
424 } | |
425 | |
426 /* | |
427 * Encrypting "from[len]" into "to[len]". | |
428 */ | |
429 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
430 crypt_encode( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
431 cryptstate_T *state, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
432 char_u *from, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
433 size_t len, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
434 char_u *to) |
6122 | 435 { |
436 cryptmethods[state->method_nr].encode_fn(state, from, len, to); | |
437 } | |
438 | |
439 /* | |
440 * decrypting "from[len]" into "to[len]". | |
441 */ | |
442 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
443 crypt_decode( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
444 cryptstate_T *state, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
445 char_u *from, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
446 size_t len, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
447 char_u *to) |
6122 | 448 { |
449 cryptmethods[state->method_nr].decode_fn(state, from, len, to); | |
450 } | |
451 | |
452 /* | |
453 * Simple inplace encryption, modifies "buf[len]" in place. | |
454 */ | |
455 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
456 crypt_encode_inplace( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
457 cryptstate_T *state, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
458 char_u *buf, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
459 size_t len) |
6122 | 460 { |
461 cryptmethods[state->method_nr].encode_inplace_fn(state, buf, len, buf); | |
462 } | |
463 | |
464 /* | |
465 * Simple inplace decryption, modifies "buf[len]" in place. | |
466 */ | |
467 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
468 crypt_decode_inplace( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
469 cryptstate_T *state, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
470 char_u *buf, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
471 size_t len) |
6122 | 472 { |
473 cryptmethods[state->method_nr].decode_inplace_fn(state, buf, len, buf); | |
474 } | |
475 | |
476 /* | |
477 * Free an allocated crypt key. Clear the text to make sure it doesn't stay | |
478 * in memory anywhere. | |
479 */ | |
480 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
481 crypt_free_key(char_u *key) |
6122 | 482 { |
483 char_u *p; | |
484 | |
485 if (key != NULL) | |
486 { | |
487 for (p = key; *p != NUL; ++p) | |
488 *p = 0; | |
489 vim_free(key); | |
490 } | |
491 } | |
492 | |
493 /* | |
6353 | 494 * Check the crypt method and give a warning if it's outdated. |
495 */ | |
496 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
497 crypt_check_method(int method) |
6353 | 498 { |
499 if (method < CRYPT_M_BF2) | |
500 { | |
501 msg_scroll = TRUE; | |
502 MSG(_("Warning: Using a weak encryption method; see :help 'cm'")); | |
503 } | |
504 } | |
505 | |
506 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
507 crypt_check_current_method(void) |
6353 | 508 { |
509 crypt_check_method(crypt_get_method_nr(curbuf)); | |
510 } | |
511 | |
512 /* | |
6122 | 513 * Ask the user for a crypt key. |
514 * When "store" is TRUE, the new key is stored in the 'key' option, and the | |
515 * 'key' option value is returned: Don't free it. | |
516 * When "store" is FALSE, the typed key is returned in allocated memory. | |
517 * Returns NULL on failure. | |
518 */ | |
519 char_u * | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
520 crypt_get_key( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
521 int store, |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
522 int twice) /* Ask for the key twice. */ |
6122 | 523 { |
524 char_u *p1, *p2 = NULL; | |
525 int round; | |
526 | |
527 for (round = 0; ; ++round) | |
528 { | |
529 cmdline_star = TRUE; | |
530 cmdline_row = msg_row; | |
531 p1 = getcmdline_prompt(NUL, round == 0 | |
532 ? (char_u *)_("Enter encryption key: ") | |
533 : (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING, | |
534 NULL); | |
535 cmdline_star = FALSE; | |
536 | |
537 if (p1 == NULL) | |
538 break; | |
539 | |
540 if (round == twice) | |
541 { | |
542 if (p2 != NULL && STRCMP(p1, p2) != 0) | |
543 { | |
544 MSG(_("Keys don't match!")); | |
545 crypt_free_key(p1); | |
546 crypt_free_key(p2); | |
547 p2 = NULL; | |
548 round = -1; /* do it again */ | |
549 continue; | |
550 } | |
551 | |
552 if (store) | |
553 { | |
554 set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL); | |
555 crypt_free_key(p1); | |
556 p1 = curbuf->b_p_key; | |
557 } | |
558 break; | |
559 } | |
560 p2 = p1; | |
561 } | |
562 | |
563 /* since the user typed this, no need to wait for return */ | |
564 if (msg_didout) | |
565 msg_putchar('\n'); | |
566 need_wait_return = FALSE; | |
567 msg_didout = FALSE; | |
568 | |
569 crypt_free_key(p2); | |
570 return p1; | |
571 } | |
572 | |
573 | |
574 /* | |
575 * Append a message to IObuff for the encryption/decryption method being used. | |
576 */ | |
577 void | |
7817
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
578 crypt_append_msg( |
83861277e6a3
commit https://github.com/vim/vim/commit/7454a06e2642d2b37afad1c5e71cec68081ca4ff
Christian Brabandt <cb@256bit.org>
parents:
6353
diff
changeset
|
579 buf_T *buf) |
6122 | 580 { |
581 if (crypt_get_method_nr(buf) == 0) | |
582 STRCAT(IObuff, _("[crypted]")); | |
583 else | |
584 { | |
585 STRCAT(IObuff, "["); | |
586 STRCAT(IObuff, *buf->b_p_cm == NUL ? p_cm : buf->b_p_cm); | |
587 STRCAT(IObuff, "]"); | |
588 } | |
589 } | |
590 | |
591 #endif /* FEAT_CRYPT */ |