Version 5.0.0-rc3 started.
[mp-5.x.git] / mp_crypt.mpsl
blob589fa127c66738231f8981f9dd3d50a9687d3581
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         {
39                 if(r[0] ne r[1])
40                         mp.drv.alert(L("Passwords don't match."));
41                 else
42                 {
43                         d.password = r[0];
44                         d.txt.mod = 1;
45                 }
46         }
50 /* action descriptions */
52 mp.actdesc['set_password'] = LL("Password protect...");
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) return;
82         /* split as an array of characters */
83         local k = split(NULL, key);
85         /* init structures */
86         mp.arcfour = {};
87         mp.arcfour.S = [ 0 .. 255 ];
88         mp.arcfour.i = 0;
89         mp.arcfour.j = 0;
91         local i;
92         local j = 0;
94         /* scramble */
95         foreach(i, [ 0 .. 255 ])
96         {
97                 local t = mp.arcfour.S[i];
99                 j = (j + t + ord(k[i % size(k)])) & 0xff;
101                 mp.arcfour.S[i] = mp.arcfour.S[j];
102                 mp.arcfour.S[j] = t;
103         }
105         /* discard 256 bytes (as recommended in many sources) */
106         foreach(i, [ 0 .. 255 ])
107                 mp.arcfour_byte();
111 sub mp.crypt1_load(fd, password)
112 /* loads a crypt1 encrypted file into lines */
114         local c;
115         local l = '';
116         local lines = [];
118         /* the mpcrypt1\n\0 signature has already been read */
120         /* init */
121         mp.arcfour_init(password);
123         while((c = getchar(fd)) != NULL)
124         {
125                 /* decrypt byte and concat */
126                 c = chr(ord(c) ^ mp.arcfour_byte());
127                 l = l ~ c;
129                 if(c eq "\n")
130                 {
131                         /* end of line; chomp l and push it */
132                         push(lines, mp.chomp(l));
133                         l = '';
134                 }
135         }
137         push(lines, mp.chomp(l));
139         return(lines);
143 sub mp.crypt1_save(fd, lines, password)
144 /* saves the lines as a crypt1 encrypted file */
146         local nl = 0;
148         /* save first the signature */
149         write(fd, "mpcrypt1\n");
151         /* write a \0 */
152         putchar(fd, "");
154         /* init */
155         mp.arcfour_init(password);
157         /* loop the lines */
158         foreach(local l, lines)
159         {
160                 /* write a line separator if it's not the first line */
161                 if(nl) l = mp.config.eol ~ l;
163                 /* split by chars */
164                 local lc = split(NULL, l);
166                 /* write each char xoring with next crypto-byte */
167                 foreach(local c, lc)
168                         putchar(fd, chr(ord(c) ^ mp.arcfour_byte()));
170                 nl++;
171         }
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; rewind file and say it */
185         fseek(fd, 0, 0);
186         return(0);