Improved algorithm in mp.repeated_words().
[mp-5.x.git] / mp_crypt.mpsl
blob53b9a2574eebf7c2302d11e0aeae811756f866b0
1 /*
3     Minimum Profit 5.x
4     A Programmer's Text Editor
6     Encrypting functions.
8     Copyright (C) 1991-2007 Angel Ortega <angel@triptico.com>
10     This program is free software; you can redistribute it and/or
11     modify it under the terms of the GNU General Public License
12     as published by the Free Software Foundation; either version 2
13     of the License, or (at your option) any later version.
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24     http://www.triptico.com
28 /** editor actions **/
30 mp.actions['set_password'] = sub(d) {
31         local r = mp.form( [
32                 { 'type' => 'password', 'label' => L("Password:") },
33                 { 'type' => 'password', 'label' => L("Password (again):") }
34                 ]
35         );
37         if (r != NULL) {
38                 if (r[0] ne r[1])
39                         mp.drv.alert(L("Passwords don't match."));
40                 else {
41                         d.password = r[0];
42                         d.txt.mod = 1;
43                 }
44         }
48 /** action descriptions **/
50 mp.actdesc['set_password'] = LL("Password protect...");
52 /** code **/
54 sub mp.arcfour_byte()
55 /* gets next ARCFOUR byte */
56 /* next char is chr(ord(getchar(l)) ^ mp.arcfour_byte()) */
58         local i, j, S;
60         i = mp.arcfour.i;
61         j = mp.arcfour.j;
62         S = mp.arcfour.S;
64         i = (i + 1) & 0xff;
65         j = (j + S[i]) & 0xff;
67         mp.arcfour.i = i; mp.arcfour.j = j;
69         /* swap */
70         local t = S[i]; S[i] = S[j]; S[j] = t;
72         return S[(S[i] + S[j]) & 0xff];
76 sub mp.arcfour_init(key)
77 /* initializes an ARCFOUR cypher */
79         /* no key? nothing to do */
80         if (key == NULL)
81                 return;
83         /* split as an array of characters */
84         local k = split(NULL, key);
86         /* init structures */
87         mp.arcfour = {};
88         mp.arcfour.S = [ 0 .. 255 ];
89         mp.arcfour.i = 0;
90         mp.arcfour.j = 0;
92         local j = 0;
94         /* scramble */
95         foreach (i, [ 0 .. 255 ]) {
96                 local t = mp.arcfour.S[i];
98                 j = (j + t + ord(k[i % size(k)])) & 0xff;
100                 mp.arcfour.S[i] = mp.arcfour.S[j];
101                 mp.arcfour.S[j] = t;
102         }
104         /* discard 256 bytes (as recommended in many sources) */
105         foreach (i, [ 0 .. 255 ])
106                 mp.arcfour_byte();
110 sub mp.crypt1_load(fd, password)
111 /* loads a crypt1 encrypted file into lines */
113         local c;
114         local l = '';
115         local lines = [];
117         /* the mpcrypt1\n\0 signature has already been read */
119         /* init */
120         mp.arcfour_init(password);
122         while ((c = getchar(fd)) != NULL) {
123                 /* decrypt byte and concat */
124                 c = chr(ord(c) ^ mp.arcfour_byte());
125                 l = l ~ c;
127                 if (c eq "\n") {
128                         /* end of line; chomp l and push it */
129                         push(lines, mp.chomp(l));
130                         l = '';
131                 }
132         }
134         push(lines, mp.chomp(l));
136         return lines;
140 sub mp.crypt1_save(fd, lines, password)
141 /* saves the lines as a crypt1 encrypted file */
143         local nl = 0;
145         /* save first the signature */
146         write(fd, "mpcrypt1\n");
148         /* write a \0 */
149         putchar(fd, "");
151         /* init */
152         mp.arcfour_init(password);
154         /* loop the lines */
155         foreach (l, lines) {
156                 /* write a line separator if it's not the first line */
157                 if (nl)
158                         l = mp.config.eol ~ l;
160                 /* split by chars */
161                 local lc = split(NULL, l);
163                 /* write each char xoring with next crypto-byte */
164                 foreach (c, lc)
165                         putchar(fd, chr(ord(c) ^ mp.arcfour_byte()));
167                 nl++;
168         }
170         return nl;
174 sub mp.crypt1_detect(fd)
175 /* detects if fd is an mpcrypt1-type file */
177         /* is it mpcrypt1\n followed by a 0? */
178         if (read(fd) eq "mpcrypt1\n" && ord(getchar(fd)) == 0)
179                 return 1;
181         /* no; file must be reopen */
182         return 0;