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