1 /* ====================================================================
2 * Copyright (c) 2002 Johnny Shelley. All rights reserved.
3 *
4 * Bcrypt is licensed under the BSD software license. See the file
5 * called 'LICENSE' that you should have received with this software
6 * for details
7 * ====================================================================
8 */
9
10 #include "includes.h"
11 #include "defines.h"
12 #include "functions.h"
13 #include "config.h"
14
15 extern char *optarg;
16 extern int optind, optreset, opterr;
17
initoptions(BCoptions options)18 BCoptions initoptions(BCoptions options) {
19 options.remove = REMOVE;
20 options.standardout = STANDARDOUT;
21 options.compression = COMPRESS; /* leave this on by default */
22 options.type = 127;
23 options.origsize = 0;
24 options.securedelete = SECUREDELETE;
25 return(options);
26 }
27
usage(char * name)28 int usage(char *name) {
29 fprintf(stderr, "Usage is: %s -[orc][-sN] file1 file2..\n", name);
30 if (STANDARDOUT == 0)
31 fprintf(stderr, " -o Write output to standard out\n");
32 else
33 fprintf(stderr, " -o Don't write output to standard out\n");
34 if (REMOVE == 1)
35 fprintf(stderr, " -r Do NOT remove input files after processing\n");
36 else
37 fprintf(stderr, " -r Remove input files after processing\n");
38 if (COMPRESS == 1)
39 fprintf(stderr, " -c Do NOT compress files before encryption\n");
40 else
41 fprintf(stderr, " -c Compress files before encryption\n");
42
43 fprintf(stderr, " -sN How many times to overwrite input files with random\
44 data\n");
45
46 exit(1);
47 }
48
memerror()49 int memerror() {
50 fprintf(stderr, "Can't allocate enough memory. Bailing out\n");
51 exit(1);
52 }
53
parseArgs(int * argc,char ** argv,BCoptions * options)54 int parseArgs(int *argc, char **argv, BCoptions *options) {
55 signed char ch;
56 char *progname;
57
58 if ((progname = malloc(strlen(argv[0]) + 1)) == NULL)
59 memerror();
60 memcpy(progname, argv[0], strlen(argv[0]) + 1);
61
62 *options = initoptions(*options);
63
64 while ((ch = getopt(*argc, argv, "rocs:")) != -1) {
65
66 switch(ch) {
67 case 'r':
68 /* remove files after write (default on) */
69 if (options->remove == 1)
70 options->remove = 0;
71 else
72 options->remove = 1;
73
74 break;
75
76 case 'o':
77 /* write to stdout */
78 if (options->standardout == 0)
79 options->standardout = 1;
80 else
81 options->standardout = 0;
82
83 options->remove = 0;
84 break;
85
86 case 'c':
87 /* compress files (default on) */
88 if (options->compression == 1)
89 options->compression = 0;
90 else
91 options->compression = 1;
92 break;
93
94 case 's':
95 /* how many times to overwrite data (default 3) */
96 options->securedelete = atoi(optarg);
97 break;
98
99 default:
100 /* dump the usage message */
101 usage(progname);
102 }
103 }
104
105 *argc -= optind;
106
107 if (*argc < 1) {
108 usage(progname);
109 }
110
111 return(optind);
112 }
113
assignFiles(char * arg,char ** infile,char ** outfile,struct stat * statbuf,BCoptions * options,char * key)114 int assignFiles(char *arg, char **infile, char **outfile, struct stat *statbuf,
115 BCoptions *options, char *key) {
116
117 if (lstat(arg, statbuf) < 0)
118 return(1);
119 if (!S_ISREG(statbuf->st_mode))
120 return(1);
121
122 if ((*infile = realloc(*infile, strlen(arg) + 1)) == NULL)
123 memerror();
124 memset(*infile, 0, strlen(arg) + 1);
125 strcpy(*infile, arg);
126
127 if ((*outfile = realloc(*outfile, strlen(arg) + 5)) == NULL)
128 memerror();
129 memset(*outfile, 0, strlen(arg) + 5);
130 strcpy(*outfile, *infile);
131
132 if (strlen(*infile) > 4) {
133
134 if ((memcmp(*infile+(strlen(*infile) - 4), ".bfe", 4) == 0) &&
135 ((!key) || (options->type == DECRYPT))){
136
137 memset(*outfile+(strlen(*infile) - 4), 0, 4);
138 options->type = DECRYPT;
139
140 } else if ((!key) || (options->type == ENCRYPT)){
141 if (memcmp(*infile+(strlen(*infile) - 4), ".bfe", 4) == 0)
142 return(1);
143
144 strcat(*outfile, ".bfe");
145 options->type = ENCRYPT;
146
147 } else
148 return(1);
149
150 } else if ((!key) || (options->type == ENCRYPT)) {
151 strcat(*outfile, ".bfe");
152 options->type = ENCRYPT;
153 } else
154 return(1);
155 return(0);
156 }
157
main(int argc,char * argv[])158 int main(int argc, char *argv[]) {
159 uLong sz = 0;
160 char *input = NULL, *key = NULL, *key2 = NULL;
161 char *infile = NULL, *outfile = NULL;
162 struct stat statbuf;
163 BCoptions options;
164
165 argv += parseArgs(&argc, argv, &options);
166
167 for (; argc > 0; argc--, argv++) {
168
169 if (assignFiles(argv[0], &infile, &outfile, &statbuf, &options, key))
170 continue;
171
172 if (!key) {
173 key = getkey(options.type);
174 mutateKey(&key, &key2);
175 }
176
177 sz = readfile(infile, &input, options.type, key, statbuf);
178
179 if ((options.type == DECRYPT) && (testEndian(input)))
180 swapCompressed(&input, sz);
181
182 if ((options.compression == 1) && (options.type == ENCRYPT)) {
183 options.origsize = sz;
184 sz = docompress(&input, sz);
185 }
186
187 if (options.type == ENCRYPT) {
188 sz = attachKey(&input, key, sz);
189 sz = padInput(&input, sz);
190 }
191
192 if (options.type == ENCRYPT)
193 sz = BFEncrypt(&input, key, sz, &options);
194 else if (options.type == DECRYPT)
195 if ((sz = BFDecrypt(&input, key, key2, sz, &options)) == 0) {
196 fprintf(stderr, "Invalid encryption key for file: %s\n", infile);
197 exit(1);
198 }
199
200 if ((options.compression == 1) && (options.type == DECRYPT))
201 sz = douncompress(&input, sz, options);
202
203 writefile(outfile, input, sz, options, statbuf);
204
205 if ((input = realloc(input, sizeof(char *))) == NULL)
206 memerror();
207
208 if (options.remove == 1)
209 deletefile(infile, options, key, statbuf);
210
211 if (input != NULL)
212 free(input);
213 }
214
215 if(!sz)
216 fprintf(stderr, "No valid files found\n");
217
218 return(0);
219 }
220