Do not use backslash-b to select backspaces.
[mp-5.x.git] / mp_crypt.mpsl
blob20b45e5ad5d2b2aa258fbc73949fa6e340115b2e
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(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());
126                 if (c eq "\n") {
127                         /* end of line; push it and restart */
128                         push(lines, l);
129                         l = '';
130                 }
131                 else
132                         l = l ~ c;
133         }
135         push(lines, l);
137         return lines;
141 sub mp.crypt1_save(fd, lines, password)
142 /* saves the lines as a crypt1 encrypted file */
144         local nl = 0;
146         /* save first the signature */
147         write(fd, "mpcrypt1\n");
149         /* write a \0 */
150         putchar(fd, "");
152         /* init */
153         mp.arcfour_init(password);
155         /* loop the lines */
156         foreach (l, lines) {
157                 /* write a line separator if it's not the first line */
158                 if (nl)
159                         l = "\n" ~ l;
161                 /* split by chars */
162                 local lc = split(l);
164                 /* write each char xoring with next crypto-byte */
165                 foreach (c, lc)
166                         putchar(fd, chr(ord(c) ^ mp.arcfour_byte()));
168                 nl++;
169         }
171     close(fd);
173         return nl;
177 sub mp.crypt1_detect(fd)
178 /* detects if fd is an mpcrypt1-type file */
180         /* is it mpcrypt1\n followed by a 0? */
181         if (read(fd) eq "mpcrypt1\n" && ord(getchar(fd)) == 0)
182                 return 1;
184         /* no; file must be reopen */
185         return 0;