Panda3D
Loading...
Searching...
No Matches
pencrypt.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file pencrypt.cxx
10 * @author drose
11 * @date 2004-09-01
12 */
13
14#include "filename.h"
15#include "encrypt_string.h"
16#include "pnotify.h"
17#include "panda_getopt.h"
18#include "preprocess_argv.h"
19
20using std::cerr;
21using std::endl;
22
23std::string password;
24bool got_password = false;
25std::string algorithm;
26bool got_algorithm = false;
27int key_length = -1;
28bool got_key_length = false;
29int iteration_count = -1;
30bool got_iteration_count = false;
31
32void
33usage() {
34 cerr
35 << "\nUsage:\n"
36 << " pencrypt [opts] file [file2 file3 ...]\n"
37 << " pencrypt -o dest_file file\n\n"
38
39 << "This program will apply an encryption algorithm to a file (or multiple files),\n"
40 << "creating an encrypted version of each file which can only be recovered using\n"
41 << "pdecrypt and the same password that was supplied to pencrypt. The compressed\n"
42 << "versions are written to a file with the same name as the original, but the\n"
43 << "extension .pe added to the filename, and the original file is removed\n"
44 << "(unless the version with -o is used, in which case you can encrypt only one\n"
45 << "file, you specify the destination file name, and the original file is not\n"
46 << "removed).\n\n"
47
48
49 << "Note that if you are adding files to a Panda multifile (.mf file) with\n"
50 << "the multify command, it is not necessary to encrypt them separately;\n"
51 << "multify has an inline encryption option.\n\n"
52
53 << "Options:\n\n"
54
55 << " -p \"password\"\n"
56 << " Specifies the password to use for encryption. There are no\n"
57 << " restrictions on the password length or contents, but longer passwords\n"
58 << " are more secure. If this is not specified, the user is prompted from\n"
59 << " standard input.\n\n"
60
61 << " -t Read the file as a text file. This will automatically convert\n"
62 << " universal end-of-line characters into a newline character, ascii\n"
63 << " 10.\n\n"
64
65 << " -a \"algorithm\"\n"
66 << " Specifies the particular encryption algorithm to use. The complete\n"
67 << " set of available algorithms is defined by the current version of\n"
68 << " OpenSSL. The default algorithm is taken from the encryption-\n"
69 << " algorithm config variable.\n\n"
70
71 << " -k key_length\n"
72 << " Specifies the key length, in bits, for the selected encryption\n"
73 << " algorithm. This only makes sense for those algorithms that support\n"
74 << " a variable key length. The default value is taken from the\n"
75 << " encryption-key-length config variable.\n\n"
76
77 << " -i iteration_count\n"
78 << " Specifies the number of times the password is hashed to generate\n"
79 << " a key. The only purpose of this is to make it computationally\n"
80 << " more expensive for an attacker to search the key space exhaustively.\n"
81 << " This should be a multiple of 1,000 and should not exceed about 65\n"
82 << " million; the value 0 indicates just one application of the hashing\n"
83 << " algorithm. The default value is taken from the encryption-iteration-\n"
84 << " count config variable.\n\n";
85}
86
87int
88main(int argc, char **argv) {
89 extern char *optarg;
90 extern int optind;
91 const char *optstr = "o:p:ta:k:i:h";
92
93 Filename dest_filename;
94 bool got_dest_filename = false;
95 bool text_file = false;
96
97 preprocess_argv(argc, argv);
98 int flag = getopt(argc, argv, optstr);
99
100 while (flag != EOF) {
101 switch (flag) {
102 case 'o':
103 dest_filename = Filename::from_os_specific(optarg);
104 got_dest_filename = true;
105 break;
106
107 case 't':
108 text_file = true;
109 break;
110
111 case 'p':
112 password = optarg;
113 got_password = true;
114 break;
115
116 case 'a':
117 algorithm = optarg;
118 got_algorithm = true;
119 break;
120
121 case 'k':
122 key_length = atoi(optarg);
123 got_key_length = true;
124 break;
125
126 case 'i':
127 iteration_count = atoi(optarg);
128 got_iteration_count = true;
129 break;
130
131 case 'h':
132 case '?':
133 default:
134 usage();
135 return 1;
136 }
137 flag = getopt(argc, argv, optstr);
138 }
139
140 argc -= (optind-1);
141 argv += (optind-1);
142
143 if (argc < 2) {
144 usage();
145 return 1;
146 }
147
148 if (got_dest_filename && argc > 2) {
149 cerr << "Only one input file allowed in conjunction with -o.\n";
150 return 1;
151 }
152
153 bool all_ok = true;
154 for (int i = 1; i < argc; i++) {
155 Filename source_file = Filename::from_os_specific(argv[i]);
156 if (source_file.get_extension() == "pe") {
157 cerr << source_file << " already ends .pe; skipping.\n";
158 } else {
159 Filename dest_file = dest_filename;
160 if (!got_dest_filename) {
161 dest_file = source_file.get_fullpath() + ".pe";
162 }
163
164 // Open source file
165 pifstream read_stream;
166 if (text_file) {
167 source_file.set_text();
168 } else {
169 source_file.set_binary();
170 }
171 if (!source_file.open_read(read_stream)) {
172 cerr << "Couldn't read: " << source_file << endl;
173 all_ok = false;
174
175 } else {
176 // Open destination file
177 pofstream write_stream;
178 dest_file.set_binary();
179 if (!dest_file.open_write(write_stream, true)) {
180 cerr << "Failed to open: " << dest_file << endl;
181 all_ok = false;
182
183 } else {
184 // Prompt for password.
185 if (!got_password) {
186 cerr << "Enter password: ";
187 std::getline(std::cin, password);
188 got_password = true;
189 }
190
191 cerr << dest_file << "\n";
192 bool success = encrypt_stream(read_stream, write_stream, password,
193 algorithm, key_length, iteration_count);
194
195 read_stream.close();
196 write_stream.close();
197
198 if (!success) {
199 cerr << "Failure writing " << dest_file << "\n";
200 all_ok = false;
201 dest_file.unlink();
202
203 } else {
204 if (!got_dest_filename) {
205 source_file.unlink();
206 }
207 }
208 }
209 }
210 }
211 }
212
213 if (all_ok) {
214 return 0;
215 } else {
216 return 1;
217 }
218}
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
bool unlink() const
Permanently deletes the file associated with the filename, if possible.
void set_binary()
Indicates that the filename represents a binary file.
Definition filename.I:414
void set_text()
Indicates that the filename represents a text file.
Definition filename.I:424
std::string get_fullpath() const
Returns the entire filename: directory, basename, extension.
Definition filename.I:338
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
Definition filename.cxx:328
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
std::string get_extension() const
Returns the file extension.
Definition filename.I:400
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void preprocess_argv(int &argc, char **&argv)
Processes the argc, argv pair as needed before passing it to getopt().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.