Mercurial > vim
comparison src/memline.c @ 6817:cd47def2214a v7.4.730
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.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Tue, 09 Jun 2015 18:35:25 +0200 |
parents | 7347229a646a |
children | 30c9301f33ed |
comparison
equal
deleted
inserted
replaced
6816:ca3db36a6ed8 | 6817:cd47def2214a |
---|---|
486 */ | 486 */ |
487 void | 487 void |
488 ml_set_crypt_key(buf, old_key, old_cm) | 488 ml_set_crypt_key(buf, old_key, old_cm) |
489 buf_T *buf; | 489 buf_T *buf; |
490 char_u *old_key; | 490 char_u *old_key; |
491 int old_cm; | 491 char_u *old_cm; |
492 { | 492 { |
493 memfile_T *mfp = buf->b_ml.ml_mfp; | 493 memfile_T *mfp = buf->b_ml.ml_mfp; |
494 bhdr_T *hp; | 494 bhdr_T *hp; |
495 int page_count; | 495 int page_count; |
496 int idx; | 496 int idx; |
498 infoptr_T *ip; | 498 infoptr_T *ip; |
499 PTR_BL *pp; | 499 PTR_BL *pp; |
500 DATA_BL *dp; | 500 DATA_BL *dp; |
501 blocknr_T bnum; | 501 blocknr_T bnum; |
502 int top; | 502 int top; |
503 int old_method; | |
503 | 504 |
504 if (mfp == NULL) | 505 if (mfp == NULL) |
505 return; /* no memfile yet, nothing to do */ | 506 return; /* no memfile yet, nothing to do */ |
507 old_method = crypt_method_nr_from_name(old_cm); | |
508 | |
509 /* First make sure the swapfile is in a consistent state, using the old | |
510 * key and method. */ | |
511 { | |
512 char_u *new_key = buf->b_p_key; | |
513 char_u *new_buf_cm = buf->b_p_cm; | |
514 | |
515 buf->b_p_key = old_key; | |
516 buf->b_p_cm = old_cm; | |
517 ml_preserve(buf, FALSE); | |
518 buf->b_p_key = new_key; | |
519 buf->b_p_cm = new_buf_cm; | |
520 } | |
506 | 521 |
507 /* Set the key, method and seed to be used for reading, these must be the | 522 /* Set the key, method and seed to be used for reading, these must be the |
508 * old values. */ | 523 * old values. */ |
509 mfp->mf_old_key = old_key; | 524 mfp->mf_old_key = old_key; |
510 mfp->mf_old_cm = old_cm; | 525 mfp->mf_old_cm = old_method; |
511 if (old_cm > 0) | 526 if (old_method > 0 && *old_key != NUL) |
512 mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN); | 527 mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN); |
513 | 528 |
514 /* Update block 0 with the crypt flag and may set a new seed. */ | 529 /* Update block 0 with the crypt flag and may set a new seed. */ |
515 ml_upd_block0(buf, UB_CRYPT); | 530 ml_upd_block0(buf, UB_CRYPT); |
516 | 531 |
559 } | 574 } |
560 else if (idx < (int)pp->pb_count) /* go a block deeper */ | 575 else if (idx < (int)pp->pb_count) /* go a block deeper */ |
561 { | 576 { |
562 if (pp->pb_pointer[idx].pe_bnum < 0) | 577 if (pp->pb_pointer[idx].pe_bnum < 0) |
563 { | 578 { |
564 /* Skip data block with negative block number. */ | 579 /* Skip data block with negative block number. |
565 ++idx; /* get same block again for next index */ | 580 * Should not happen, because of the ml_preserve() |
581 * above. Get same block again for next index. */ | |
582 ++idx; | |
566 continue; | 583 continue; |
567 } | 584 } |
568 | 585 |
569 /* going one block deeper in the tree, new entry in | 586 /* going one block deeper in the tree, new entry in |
570 * stack */ | 587 * stack */ |
577 ip->ip_bnum = bnum; | 594 ip->ip_bnum = bnum; |
578 ip->ip_index = idx; | 595 ip->ip_index = idx; |
579 | 596 |
580 bnum = pp->pb_pointer[idx].pe_bnum; | 597 bnum = pp->pb_pointer[idx].pe_bnum; |
581 page_count = pp->pb_pointer[idx].pe_page_count; | 598 page_count = pp->pb_pointer[idx].pe_page_count; |
599 idx = 0; | |
582 continue; | 600 continue; |
583 } | 601 } |
584 } | 602 } |
585 else /* not a pointer block */ | 603 else /* not a pointer block */ |
586 { | 604 { |
603 ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]); | 621 ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]); |
604 bnum = ip->ip_bnum; | 622 bnum = ip->ip_bnum; |
605 idx = ip->ip_index + 1; /* go to next index */ | 623 idx = ip->ip_index + 1; /* go to next index */ |
606 page_count = 1; | 624 page_count = 1; |
607 } | 625 } |
626 if (hp != NULL) | |
627 mf_put(mfp, hp, FALSE, FALSE); /* release previous block */ | |
608 | 628 |
609 if (error > 0) | 629 if (error > 0) |
610 EMSG(_("E843: Error while updating swap file crypt")); | 630 EMSG(_("E843: Error while updating swap file crypt")); |
611 } | 631 } |
612 | 632 |
4857 cryptstate_T *state; | 4877 cryptstate_T *state; |
4858 | 4878 |
4859 if (dp->db_id != DATA_ID) | 4879 if (dp->db_id != DATA_ID) |
4860 return data; | 4880 return data; |
4861 | 4881 |
4882 state = ml_crypt_prepare(mfp, offset, FALSE); | |
4883 if (state == NULL) | |
4884 return data; | |
4885 | |
4862 new_data = (char_u *)alloc(size); | 4886 new_data = (char_u *)alloc(size); |
4863 if (new_data == NULL) | 4887 if (new_data == NULL) |
4864 return NULL; | 4888 return NULL; |
4865 head_end = (char_u *)(&dp->db_index[dp->db_line_count]); | 4889 head_end = (char_u *)(&dp->db_index[dp->db_line_count]); |
4866 text_start = (char_u *)dp + dp->db_txt_start; | 4890 text_start = (char_u *)dp + dp->db_txt_start; |
4868 | 4892 |
4869 /* Copy the header and the text. */ | 4893 /* Copy the header and the text. */ |
4870 mch_memmove(new_data, dp, head_end - (char_u *)dp); | 4894 mch_memmove(new_data, dp, head_end - (char_u *)dp); |
4871 | 4895 |
4872 /* Encrypt the text. */ | 4896 /* Encrypt the text. */ |
4873 state = ml_crypt_prepare(mfp, offset, FALSE); | |
4874 crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start); | 4897 crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start); |
4875 crypt_free_state(state); | 4898 crypt_free_state(state); |
4876 | 4899 |
4877 /* Clear the gap. */ | 4900 /* Clear the gap. */ |
4878 if (head_end < text_start) | 4901 if (head_end < text_start) |
4880 | 4903 |
4881 return new_data; | 4904 return new_data; |
4882 } | 4905 } |
4883 | 4906 |
4884 /* | 4907 /* |
4885 * Decrypt the text in "data" if it points to a data block. | 4908 * Decrypt the text in "data" if it points to an encrypted data block. |
4886 */ | 4909 */ |
4887 void | 4910 void |
4888 ml_decrypt_data(mfp, data, offset, size) | 4911 ml_decrypt_data(mfp, data, offset, size) |
4889 memfile_T *mfp; | 4912 memfile_T *mfp; |
4890 char_u *data; | 4913 char_u *data; |
4905 | 4928 |
4906 if (head_end > text_start || dp->db_txt_start > size | 4929 if (head_end > text_start || dp->db_txt_start > size |
4907 || dp->db_txt_end > size) | 4930 || dp->db_txt_end > size) |
4908 return; /* data was messed up */ | 4931 return; /* data was messed up */ |
4909 | 4932 |
4910 /* Decrypt the text in place. */ | |
4911 state = ml_crypt_prepare(mfp, offset, TRUE); | 4933 state = ml_crypt_prepare(mfp, offset, TRUE); |
4912 crypt_decode_inplace(state, text_start, text_len); | 4934 if (state != NULL) |
4913 crypt_free_state(state); | 4935 { |
4936 /* Decrypt the text in place. */ | |
4937 crypt_decode_inplace(state, text_start, text_len); | |
4938 crypt_free_state(state); | |
4939 } | |
4914 } | 4940 } |
4915 } | 4941 } |
4916 | 4942 |
4917 /* | 4943 /* |
4918 * Prepare for encryption/decryption, using the key, seed and offset. | 4944 * Prepare for encryption/decryption, using the key, seed and offset. |
4941 { | 4967 { |
4942 method_nr = crypt_get_method_nr(buf); | 4968 method_nr = crypt_get_method_nr(buf); |
4943 key = buf->b_p_key; | 4969 key = buf->b_p_key; |
4944 seed = mfp->mf_seed; | 4970 seed = mfp->mf_seed; |
4945 } | 4971 } |
4972 if (*key == NUL) | |
4973 return NULL; | |
4946 | 4974 |
4947 if (method_nr == CRYPT_M_ZIP) | 4975 if (method_nr == CRYPT_M_ZIP) |
4948 { | 4976 { |
4949 /* For PKzip: Append the offset to the key, so that we use a different | 4977 /* For PKzip: Append the offset to the key, so that we use a different |
4950 * key for every block. */ | 4978 * key for every block. */ |