summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2015-06-09 18:35:25 +0200
committerBram Moolenaar <Bram@vim.org>2015-06-09 18:35:25 +0200
commitbc56336bb4501884257352446abb60713cef6452 (patch)
treebf4f55292e2e42533ceadfbd769aab281868a290
parent0481fee48800817bee206bb2f958fe04be4d8db6 (diff)
downloadvim-bc56336bb4501884257352446abb60713cef6452.zip
patch 7.4.730
Problem: When setting the crypt key and using a swap file, text may be encrypted twice or unencrypted text remains in the swap file. (Issue 369) Solution: Call ml_preserve() before re-encrypting. Set correct index for next pointer block.
-rw-r--r--src/memfile.c4
-rw-r--r--src/memline.c48
-rw-r--r--src/option.c9
-rw-r--r--src/proto/memline.pro2
-rw-r--r--src/version.c2
5 files changed, 48 insertions, 17 deletions
diff --git a/src/memfile.c b/src/memfile.c
index 57c9d92fd..a21b7076a 100644
--- a/src/memfile.c
+++ b/src/memfile.c
@@ -811,6 +811,8 @@ mf_rem_used(mfp, hp)
*
* Return the block header to the caller, including the memory block, so
* it can be re-used. Make sure the page_count is right.
+ *
+ * Returns NULL if no block is released.
*/
static bhdr_T *
mf_release(mfp, page_count)
@@ -1219,7 +1221,7 @@ mf_trans_add(mfp, hp)
}
/*
- * Lookup a translation from the trans lists and delete the entry
+ * Lookup a translation from the trans lists and delete the entry.
*
* Return the positive new number when found, the old number when not found
*/
diff --git a/src/memline.c b/src/memline.c
index 730496c18..e80936087 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -488,7 +488,7 @@ ml_set_b0_crypt(buf, b0p)
ml_set_crypt_key(buf, old_key, old_cm)
buf_T *buf;
char_u *old_key;
- int old_cm;
+ char_u *old_cm;
{
memfile_T *mfp = buf->b_ml.ml_mfp;
bhdr_T *hp;
@@ -500,15 +500,30 @@ ml_set_crypt_key(buf, old_key, old_cm)
DATA_BL *dp;
blocknr_T bnum;
int top;
+ int old_method;
if (mfp == NULL)
return; /* no memfile yet, nothing to do */
+ old_method = crypt_method_nr_from_name(old_cm);
+
+ /* First make sure the swapfile is in a consistent state, using the old
+ * key and method. */
+ {
+ char_u *new_key = buf->b_p_key;
+ char_u *new_buf_cm = buf->b_p_cm;
+
+ buf->b_p_key = old_key;
+ buf->b_p_cm = old_cm;
+ ml_preserve(buf, FALSE);
+ buf->b_p_key = new_key;
+ buf->b_p_cm = new_buf_cm;
+ }
/* Set the key, method and seed to be used for reading, these must be the
* old values. */
mfp->mf_old_key = old_key;
- mfp->mf_old_cm = old_cm;
- if (old_cm > 0)
+ mfp->mf_old_cm = old_method;
+ if (old_method > 0 && *old_key != NUL)
mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN);
/* Update block 0 with the crypt flag and may set a new seed. */
@@ -561,8 +576,10 @@ ml_set_crypt_key(buf, old_key, old_cm)
{
if (pp->pb_pointer[idx].pe_bnum < 0)
{
- /* Skip data block with negative block number. */
- ++idx; /* get same block again for next index */
+ /* Skip data block with negative block number.
+ * Should not happen, because of the ml_preserve()
+ * above. Get same block again for next index. */
+ ++idx;
continue;
}
@@ -579,6 +596,7 @@ ml_set_crypt_key(buf, old_key, old_cm)
bnum = pp->pb_pointer[idx].pe_bnum;
page_count = pp->pb_pointer[idx].pe_page_count;
+ idx = 0;
continue;
}
}
@@ -605,6 +623,8 @@ ml_set_crypt_key(buf, old_key, old_cm)
idx = ip->ip_index + 1; /* go to next index */
page_count = 1;
}
+ if (hp != NULL)
+ mf_put(mfp, hp, FALSE, FALSE); /* release previous block */
if (error > 0)
EMSG(_("E843: Error while updating swap file crypt"));
@@ -4859,6 +4879,10 @@ ml_encrypt_data(mfp, data, offset, size)
if (dp->db_id != DATA_ID)
return data;
+ state = ml_crypt_prepare(mfp, offset, FALSE);
+ if (state == NULL)
+ return data;
+
new_data = (char_u *)alloc(size);
if (new_data == NULL)
return NULL;
@@ -4870,7 +4894,6 @@ ml_encrypt_data(mfp, data, offset, size)
mch_memmove(new_data, dp, head_end - (char_u *)dp);
/* Encrypt the text. */
- state = ml_crypt_prepare(mfp, offset, FALSE);
crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start);
crypt_free_state(state);
@@ -4882,7 +4905,7 @@ ml_encrypt_data(mfp, data, offset, size)
}
/*
- * Decrypt the text in "data" if it points to a data block.
+ * Decrypt the text in "data" if it points to an encrypted data block.
*/
void
ml_decrypt_data(mfp, data, offset, size)
@@ -4907,10 +4930,13 @@ ml_decrypt_data(mfp, data, offset, size)
|| dp->db_txt_end > size)
return; /* data was messed up */
- /* Decrypt the text in place. */
state = ml_crypt_prepare(mfp, offset, TRUE);
- crypt_decode_inplace(state, text_start, text_len);
- crypt_free_state(state);
+ if (state != NULL)
+ {
+ /* Decrypt the text in place. */
+ crypt_decode_inplace(state, text_start, text_len);
+ crypt_free_state(state);
+ }
}
}
@@ -4943,6 +4969,8 @@ ml_crypt_prepare(mfp, offset, reading)
key = buf->b_p_key;
seed = mfp->mf_seed;
}
+ if (*key == NUL)
+ return NULL;
if (method_nr == CRYPT_M_ZIP)
{
diff --git a/src/option.c b/src/option.c
index 56d94934d..7bcb26abc 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6163,7 +6163,8 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
# endif
if (STRCMP(curbuf->b_p_key, oldval) != 0)
/* Need to update the swapfile. */
- ml_set_crypt_key(curbuf, oldval, crypt_get_method_nr(curbuf));
+ ml_set_crypt_key(curbuf, oldval,
+ *curbuf->b_p_cm == NUL ? p_cm : curbuf->b_p_cm);
}
else if (gvarp == &p_cm)
@@ -6207,8 +6208,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
else
p = curbuf->b_p_cm;
if (STRCMP(s, p) != 0)
- ml_set_crypt_key(curbuf, curbuf->b_p_key,
- crypt_method_nr_from_name(s));
+ ml_set_crypt_key(curbuf, curbuf->b_p_key, s);
/* If the global value changes need to update the swapfile for all
* buffers using that value. */
@@ -6218,8 +6218,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
if (buf != curbuf && *buf->b_p_cm == NUL)
- ml_set_crypt_key(buf, buf->b_p_key,
- crypt_method_nr_from_name(oldval));
+ ml_set_crypt_key(buf, buf->b_p_key, oldval);
}
}
}
diff --git a/src/proto/memline.pro b/src/proto/memline.pro
index 62a3ce640..ff5d24a7c 100644
--- a/src/proto/memline.pro
+++ b/src/proto/memline.pro
@@ -1,6 +1,6 @@
/* memline.c */
int ml_open __ARGS((buf_T *buf));
-void ml_set_crypt_key __ARGS((buf_T *buf, char_u *old_key, int old_cm));
+void ml_set_crypt_key __ARGS((buf_T *buf, char_u *old_key, char_u *old_cm));
void ml_setname __ARGS((buf_T *buf));
void ml_open_files __ARGS((void));
void ml_open_file __ARGS((buf_T *buf));
diff --git a/src/version.c b/src/version.c
index 355aa06f2..6b8b15e8e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 730,
+/**/
729,
/**/
728,