1 /*
2 * steghide 0.5.1 - a steganography program
3 * Copyright (C) 1999-2003 Stefan Hetzl <shetzl@chello.at>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21 #include <cstring>
22 #include <iostream>
23 #include <string>
24
25 #include "MCryptPP.h"
26 #include "Terminal.h"
27 #include "common.h"
28 #include "error.h"
29 #include "msg.h"
30
31 // the global Arguments object
32 Arguments Args ;
33
Arguments(int argc,char * argv[])34 Arguments::Arguments (int argc, char* argv[])
35 {
36 bool delete_next = false ;
37 for (int i = 1 ; i < argc ; ++i) {
38 TheArguments.push_back (std::string(argv[i])) ;
39
40 if (delete_next) {
41 // overwrite passphrase in argv in order to avoid that it can be read with the ps command
42 unsigned int len = strlen(argv[i]) ;
43 for (unsigned int j = 0 ; j < len ; j++) {
44 argv[i][j] = ' ' ;
45 }
46 delete_next = false ;
47 }
48
49 if (std::string(argv[i]) == "-p" || std::string(argv[i]) == "--passphrase") {
50 delete_next = true ;
51 }
52 }
53 }
54
parse()55 void Arguments::parse ()
56 {
57 // if there are no arguments -> show help
58 if (TheArguments.empty()) {
59 Command.setValue (SHOWHELP) ;
60 return ;
61 }
62
63 ArgIt curarg = TheArguments.begin() ;
64
65 parse_Command (curarg) ;
66
67 // parse rest of arguments
68 while (curarg != TheArguments.end()) {
69 if (parse_EmbFn(curarg)) continue ;
70 if (parse_ExtFn(curarg)) continue ;
71 if (parse_CvrFn(curarg)) continue ;
72 if (parse_StgFn(curarg)) continue ;
73 if (parse_Passphrase(curarg)) continue ;
74 if (parse_Checksum(curarg)) continue ;
75 if (parse_Compression(curarg)) continue ;
76 if (parse_EmbedEmbFn(curarg)) continue ;
77 if (parse_Encryption(curarg)) continue ;
78 if (parse_Radius(curarg)) continue ;
79 if (parse_Goal(curarg)) continue ;
80 if (parse_Force(curarg)) continue ;
81 if (parse_Verbosity(curarg)) continue ;
82 if (parse_Debug(curarg)) continue ; // TODO - rename Debug -> Undocumented
83
84 throw ArgError (_("unknown argument \"%s\"."), curarg->c_str()) ;
85 }
86
87 // (command-specific) argument post-processing
88 if (Command.getValue() == EMBED) {
89 if ((CvrFn.getValue() == "") && (EmbFn.getValue() == "")) {
90 throw ArgError (_("standard input cannot be used for cover data AND data to be embedded.")) ;
91 }
92 if (!StgFn.is_set() && CvrFn.is_set()) {
93 StgFn.setValue (CvrFn.getValue()) ;
94 Force.setValue (true) ;
95 }
96 }
97
98 if (Command.getValue() == EMBED || Command.getValue() == EXTRACT) {
99 if (!Passphrase.is_set()) {
100 // prompt for passphrase
101 if (Command.getValue() == EMBED) {
102 if ((CvrFn.getValue() == "") || (EmbFn.getValue() == "")) {
103 throw ArgError (_("if standard input is used, the passphrase must be specified on the command line.")) ;
104 }
105 Passphrase.setValue (getPassphrase (true)) ;
106 }
107 else if (Command.getValue() == EXTRACT) {
108 if (StgFn.getValue() == "") {
109 throw ArgError (_("if standard input is used, the passphrase must be specified on the command line.")) ;
110 }
111 Passphrase.setValue (getPassphrase()) ;
112 }
113 }
114 }
115 }
116
parse_Command(ArgIt & curarg)117 void Arguments::parse_Command (ArgIt& curarg)
118 {
119 CommandString = *curarg ;
120
121 if (*curarg == "embed" || *curarg == "--embed") {
122 Command.setValue (EMBED) ;
123 setDefaults () ;
124 ++curarg ;
125 }
126 else if (*curarg == "extract" || *curarg == "--extract") {
127 Command.setValue (EXTRACT) ;
128 setDefaults () ;
129 ++curarg ;
130 }
131 else if (*curarg == "info" || *curarg == "--info") {
132 Command.setValue (INFO) ;
133 setDefaults() ;
134
135 ++curarg ;
136
137 if (curarg == TheArguments.end()) {
138 throw ArgError (_("you have to suppy a filename to the \"%s\" command."), CommandString.c_str()) ;
139 }
140 else {
141 parse_Passphrase (curarg) ; // try: maybe -p is first argument
142
143 if (*curarg == "-") {
144 CvrFn.setValue ("") ;
145 }
146 else {
147 CvrFn.setValue (*curarg) ;
148 }
149 ++curarg ;
150
151 if (curarg != TheArguments.end()) {
152 parse_Passphrase (curarg) ;
153 }
154 }
155 }
156 else if (*curarg == "encinfo" || *curarg == "--encinfo") {
157 Command.setValue (ENCINFO) ;
158 if (TheArguments.size() > 1) {
159 throw ArgError (_("you cannot use arguments with the \"%s\" command."), CommandString.c_str()) ;
160 }
161 ++curarg ;
162 }
163 else if (*curarg == "version" || *curarg == "--version") {
164 Command.setValue (SHOWVERSION) ;
165 if (TheArguments.size() > 1) {
166 throw ArgError (_("you cannot use arguments with the \"%s\" command."), CommandString.c_str()) ;
167 }
168 ++curarg ;
169 }
170 else if (*curarg == "license" || *curarg == "--license") {
171 Command.setValue (SHOWLICENSE) ;
172 if (TheArguments.size() > 1) {
173 throw ArgError (_("you cannot use arguments with the \"%s\" command."), CommandString.c_str()) ;
174 }
175 ++curarg ;
176 }
177 else if (*curarg == "help" || *curarg == "--help") {
178 Command.setValue (SHOWHELP) ;
179 if (TheArguments.size() > 1) {
180 throw ArgError (_("you cannot use arguments with the \"%s\" command."), CommandString.c_str()) ;
181 }
182 ++curarg ;
183 }
184 #ifdef DEBUG
185 else if (*curarg == "printfreqs" || *curarg == "--printfreqs") {
186 Command.setValue (PRINTFREQS) ;
187 std::list<std::string> flist ;
188 while ((++curarg) != TheArguments.end()) {
189 flist.push_back (*curarg) ;
190 }
191 FileList.setValue (flist) ;
192 }
193 #endif
194 else {
195 throw ArgError (_("unknown command \"%s\"."), CommandString.c_str()) ;
196 }
197 }
198
parse_EmbFn(ArgIt & curarg)199 bool Arguments::parse_EmbFn (ArgIt& curarg)
200 {
201 bool found = false ;
202
203 if (*curarg == "-ef" || *curarg == "--embedfile") {
204 if (Command.getValue() != EMBED) {
205 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" command."), curarg->c_str(), "embed") ;
206 }
207
208 if (EmbFn.is_set()) {
209 throw ArgError (_("the \"%s\" argument can be used only once."), (curarg - 1)->c_str()) ;
210 }
211
212 if (++curarg == TheArguments.end()) {
213 throw ArgError (_("the \"%s\" argument must be followed by the embed file name."), (curarg - 1)->c_str()) ;
214 }
215
216 if (*curarg == "-") {
217 EmbFn.setValue ("") ;
218 }
219 else {
220 EmbFn.setValue (*curarg) ;
221 }
222
223 found = true ;
224 curarg++ ;
225 }
226
227 return found ;
228 }
229
parse_ExtFn(ArgIt & curarg)230 bool Arguments::parse_ExtFn (ArgIt& curarg)
231 {
232 bool found = false ;
233
234 if (*curarg == "-xf" || *curarg == "--extractfile") {
235 if (Command.getValue() != EXTRACT) {
236 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" command."), curarg->c_str(), "extract") ;
237 }
238
239 if (ExtFn.is_set()) {
240 throw ArgError (_("the \"%s\" argument can be used only once."), (curarg - 1)->c_str()) ;
241 }
242
243 if (++curarg == TheArguments.end()) {
244 throw ArgError (_("the \"%s\" argument must be followed by the extract file name."), (curarg - 1)->c_str()) ;
245 }
246
247 if (*curarg == "-") {
248 ExtFn.setValue ("") ;
249 }
250 else {
251 ExtFn.setValue (*curarg) ;
252 }
253
254 found = true ;
255 curarg++ ;
256 }
257
258 return found ;
259 }
260
parse_CvrFn(ArgIt & curarg)261 bool Arguments::parse_CvrFn (ArgIt& curarg)
262 {
263 bool found = false ;
264
265 if (*curarg == "-cf" || *curarg == "--coverfile") {
266 if (Command.getValue() != EMBED) {
267 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" command."), curarg->c_str(), "embed") ;
268 }
269
270 if (CvrFn.is_set()) {
271 throw ArgError (_("the cover file name argument can be used only once.")) ;
272 }
273
274 if (++curarg == TheArguments.end()) {
275 throw ArgError (_("the \"%s\" argument must be followed by the cover file name."), (curarg - 1)->c_str()) ;
276 }
277
278 if (*curarg == "-") {
279 CvrFn.setValue ("") ;
280 }
281 else {
282 CvrFn.setValue (*curarg) ;
283 }
284
285 found = true ;
286 curarg++ ;
287 }
288
289 return found ;
290 }
291
parse_StgFn(ArgIt & curarg)292 bool Arguments::parse_StgFn (ArgIt& curarg)
293 {
294 bool found = false ;
295
296 if (*curarg == "-sf" || *curarg == "--stegofile") {
297 if (Command.getValue() != EMBED && Command.getValue() != EXTRACT) {
298 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" and \"%s\" commands."), curarg->c_str(), "embed", "extract") ;
299 }
300
301 if (StgFn.is_set()) {
302 throw ArgError (_("the \"%s\" argument can be used only once."), (curarg - 1)->c_str()) ;
303 }
304
305 if (++curarg == TheArguments.end()) {
306 throw ArgError (_("the \"%s\" argument must be followed by the stego file name."), (curarg - 1)->c_str()) ;
307 }
308
309 if (*curarg == "-") {
310 StgFn.setValue ("") ;
311 }
312 else {
313 StgFn.setValue (*curarg) ;
314 }
315
316 found = true ;
317 curarg++ ;
318 }
319
320 return found ;
321 }
322
parse_Passphrase(ArgIt & curarg)323 bool Arguments::parse_Passphrase (ArgIt& curarg)
324 {
325 bool found = false ;
326
327 if (*curarg == "-p" || *curarg == "--passphrase") {
328 if (Passphrase.is_set()) {
329 throw ArgError (_("the passphrase argument can be used only once.")) ;
330 }
331
332 if (++curarg == TheArguments.end()) {
333 throw ArgError (_("the \"%s\" argument must be followed by the passphrase."), (curarg - 1)->c_str());
334 }
335
336 Passphrase.setValue (*curarg) ;
337
338 found = true ;
339 curarg++ ;
340 }
341
342 return found ;
343 }
344
parse_Checksum(ArgIt & curarg)345 bool Arguments::parse_Checksum (ArgIt& curarg)
346 {
347 bool found = false ;
348
349 if (*curarg == "-K" || *curarg == "--nochecksum") {
350 if (Command.getValue() != EMBED) {
351 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" command."), curarg->c_str(), "embed") ;
352 }
353
354 if (Checksum.is_set()) {
355 throw ArgError (_("the checksum argument can be used only once.")) ;
356 }
357
358 Checksum.setValue (false) ;
359
360 found = true ;
361 curarg++ ;
362 }
363
364 return found ;
365 }
366
parse_Compression(ArgIt & curarg)367 bool Arguments::parse_Compression (ArgIt& curarg)
368 {
369 bool found = false ;
370
371 if (*curarg == "-z" || *curarg == "--compress") {
372 if (Command.getValue() != EMBED) {
373 throw ArgError (_("the argument \"%s\" can only be used with the \"embed\" command."), curarg->c_str()) ;
374 }
375
376 if (Compression.is_set()) {
377 throw ArgError (_("the compression argument can be used only once.")) ;
378 }
379
380 if (++curarg == TheArguments.end()) {
381 throw ArgError (_("the \"%s\" argument must be followed by the compression level."), (curarg - 1)->c_str()) ;
382 }
383
384 int tmp = 0 ;
385 sscanf (curarg->c_str(), "%d", &tmp) ;
386 if (tmp < 1 || tmp > 9) {
387 throw ArgError (_("\"%s\" is not a valid compression level."), curarg->c_str()) ;
388 }
389 Compression.setValue (tmp) ;
390
391 found = true ;
392 curarg++ ;
393 }
394 else if (*curarg == "-Z" || *curarg == "--dontcompress") {
395 if (Command.getValue() != EMBED) {
396 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" command."), curarg->c_str(), "embed") ;
397 }
398
399 if (Compression.is_set()) {
400 throw ArgError (_("the compression argument can be used only once.")) ;
401 }
402
403 Compression.setValue (NoCompression) ;
404
405 found = true ;
406 curarg++ ;
407 }
408
409 return found ;
410 }
411
parse_EmbedEmbFn(ArgIt & curarg)412 bool Arguments::parse_EmbedEmbFn (ArgIt& curarg)
413 {
414 bool found = false ;
415
416 if (*curarg == "-N" || *curarg == "--dontembedname") {
417 if (Command.getValue() != EMBED) {
418 throw ArgError (_("the argument \"%s\" can only be used with the \"embed\" command."), curarg->c_str()) ;
419 }
420
421 if (EmbedEmbFn.is_set()) {
422 throw ArgError (_("the file name embedding argument can be used only once.")) ;
423 }
424
425 EmbedEmbFn.setValue (false) ;
426
427 found = true ;
428 curarg++ ;
429 }
430
431 return found ;
432 }
433
parse_Encryption(ArgIt & curarg)434 bool Arguments::parse_Encryption (ArgIt& curarg)
435 {
436 bool found = false ;
437
438 if (*curarg == "-e" || *curarg == "--encryption") {
439 if (Command.getValue() != EMBED) {
440 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" command."), curarg->c_str(), "embed") ;
441 }
442
443 if (EncAlgo.is_set() || EncMode.is_set()) {
444 throw ArgError (_("the encryption argument can be used only once.")) ;
445 }
446
447 if (++curarg == TheArguments.end()) {
448 throw ArgError (_("the \"%s\" argument must be followed by encryption parameters."), (curarg - 1)->c_str()) ;
449 }
450
451 std::string s1, s2 ;
452 if ((*curarg)[0] == '-') {
453 throw ArgError (_("the \"%s\" argument must be followed by encryption parameters."), (curarg - 1)->c_str()) ;
454 }
455 else {
456 s1 = *curarg ;
457 if (curarg + 1 == TheArguments.end()) {
458 s2 = "" ;
459 }
460 else {
461 if ((*(curarg + 1))[0] == '-') {
462 s2 = "" ;
463 }
464 else {
465 ++curarg ; // set to second encryption specifier
466 s2 = *curarg ;
467 }
468 }
469 }
470
471 if (s1 == "none" && s2 == "") {
472 EncAlgo.setValue (s1) ;
473 }
474 #ifdef USE_LIBMCRYPT
475 else {
476 bool s1_isalgo = false, s1_ismode = false ;
477 bool s2_isalgo = false, s2_ismode = false ;
478
479 if (s1 != "") {
480 s1_isalgo = EncryptionAlgorithm::isValidStringRep (s1) ;
481 s1_ismode = EncryptionMode::isValidStringRep (s1) ;
482
483 myassert (!(s1_isalgo && s1_ismode)) ;
484 if (!(s1_isalgo || s1_ismode)) {
485 throw SteghideError (_("\"%s\" is neither an algorithm nor a mode supported by libmcrypt."), s1.c_str()) ;
486 }
487 }
488 if (s2 != "") {
489 s2_isalgo = EncryptionAlgorithm::isValidStringRep (s2) ;
490 s2_ismode = EncryptionMode::isValidStringRep (s2) ;
491
492 myassert (!(s2_isalgo && s2_ismode)) ;
493 if (!(s2_isalgo || s2_ismode)) {
494 throw SteghideError (_("\"%s\" is neither an algorithm nor a mode supported by libmcrypt."), s2.c_str()) ;
495 }
496 }
497
498 if (s1_isalgo && s2_isalgo) {
499 throw SteghideError (_("\"%s\" and \"%s\" are both libmcrypt algorithms. please specify only one."), s1.c_str(), s2.c_str()) ;
500 }
501 if (s1_ismode && s2_ismode) {
502 throw SteghideError (_("\"%s\" and \"%s\" are both libmcrypt modes. please specify only one."), s1.c_str(), s2.c_str()) ;
503 }
504
505 if (s1_isalgo) {
506 EncAlgo.setValue (s1) ;
507 }
508 if (s1_ismode) {
509 EncMode.setValue (s1) ;
510 }
511 if (s2_isalgo) {
512 EncAlgo.setValue (s2) ;
513 }
514 if (s2_ismode) {
515 EncMode.setValue (s2) ;
516 }
517
518 if (!MCryptPP::AlgoSupportsMode (EncAlgo.getValue(), EncMode.getValue())) {
519 throw SteghideError (_("the encryption algorithm \"%s\" can not be used with the mode \"%s\"."),
520 EncAlgo.getValue().getStringRep().c_str(), EncMode.getValue().getStringRep().c_str()) ;
521 }
522 }
523 #else
524 else {
525 throw SteghideError (_("steghide has been compiled without support for encryption.")) ;
526 }
527 #endif // def USE_LIBMCRYPT
528
529 found = true ;
530 curarg++ ;
531 }
532
533 return found ;
534 }
535
parse_Radius(ArgIt & curarg)536 bool Arguments::parse_Radius (ArgIt& curarg)
537 {
538 bool found = false ;
539
540 if (*curarg == "-r" || *curarg == "--radius") {
541 if (Command.getValue() != EMBED) {
542 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" command."), curarg->c_str(), "embed") ;
543 }
544
545 if (Radius.is_set()) {
546 throw ArgError (_("the radius argument can be used only once.")) ;
547 }
548
549 if (++curarg == TheArguments.end()) {
550 throw ArgError (_("the \"%s\" argument must be followed by the neighbourhood radius."), (curarg - 1)->c_str()) ;
551 }
552
553 unsigned long tmp = 0 ;
554 sscanf (curarg->c_str(), "%lu", &tmp) ;
555 Radius.setValue (tmp) ;
556
557 found = true ;
558 curarg++ ;
559 }
560
561 return found ;
562 }
563
parse_Goal(ArgIt & curarg)564 bool Arguments::parse_Goal (ArgIt& curarg)
565 {
566 bool found = false ;
567
568 if (*curarg == "-g" || *curarg == "--goal") {
569 if (Command.getValue() != EMBED) {
570 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" command."), curarg->c_str(), "embed") ;
571 }
572
573 if (Goal.is_set()) {
574 throw ArgError (_("the goal argument can be used only once.")) ;
575 }
576
577 if (++curarg == TheArguments.end()) {
578 throw ArgError (_("the \"%s\" argument must be followed by a number between 0 and 100."), (curarg - 1)->c_str()) ;
579 }
580
581 float tmp = 0 ;
582 sscanf (curarg->c_str(), "%f", &tmp) ;
583 if (tmp < 0 || tmp > 100) {
584 throw ArgError (_("the \"%s\" argument must be followed by a number between 0 and 100."), (curarg - 1)->c_str()) ;
585 }
586 Goal.setValue (tmp) ;
587
588 found = true ;
589 curarg++ ;
590 }
591
592 return found ;
593 }
594
parse_Force(ArgIt & curarg)595 bool Arguments::parse_Force (ArgIt& curarg)
596 {
597 bool found = false ;
598
599 if (*curarg == "-f" || *curarg == "--force") {
600 if (Command.getValue() != EMBED && Command.getValue() != EXTRACT) {
601 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" and \"%s\" commands."), curarg->c_str(), "embed", "extract") ;
602 }
603
604 if (Force.is_set()) {
605 throw ArgError (_("the force argument can be used only once.")) ;
606 }
607
608 Force.setValue (true);
609
610 found = true ;
611 curarg++ ;
612 }
613
614 return found ;
615 }
616
parse_Verbosity(ArgIt & curarg)617 bool Arguments::parse_Verbosity (ArgIt& curarg)
618 {
619 bool found = false ;
620
621 if (*curarg == "-q" || *curarg == "--quiet") {
622 found = true ;
623
624 if (Command.getValue() != EMBED && Command.getValue() != EXTRACT) {
625 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" and \"%s\" commands."), curarg->c_str(), "embed", "extract") ;
626 }
627
628 if (Verbosity.is_set()) {
629 throw ArgError (_("the \"%s\" argument cannot be used here because the verbosity has already been set."), curarg->c_str()) ;
630 }
631
632 Verbosity.setValue (QUIET) ;
633 curarg++ ;
634 }
635 else if (*curarg == "-v" || *curarg == "--verbose") {
636 found = true ;
637
638 if (Command.getValue() != EMBED && Command.getValue() != EXTRACT) {
639 throw ArgError (_("the argument \"%s\" can only be used with the \"%s\" and \"%s\" commands."), curarg->c_str(), "embed", "extract") ;
640 }
641
642 if (Verbosity.is_set()) {
643 throw ArgError (_("the \"%s\" argument cannot be used here because the verbosity has already been set."), curarg->c_str()) ;
644 }
645
646 Verbosity.setValue (VERBOSE) ;
647 curarg++ ;
648 }
649
650 return found ;
651 }
652
parse_Debug(ArgIt & curarg)653 bool Arguments::parse_Debug (ArgIt& curarg)
654 {
655 bool found = false ;
656
657 if (*curarg == "--printgraph") {
658 if (DebugCommand.is_set()) {
659 throw SteghideError (_("you cannot use more than one debug command at a time.")) ;
660 }
661
662 DebugCommand.setValue (PRINTGRAPH) ;
663
664 found = true ;
665 curarg++ ;
666 }
667 else if (*curarg == "--printgmlgraph") {
668 if (DebugCommand.is_set()) {
669 throw SteghideError (_("you cannot use more than one debug command at a time.")) ;
670 }
671
672 DebugCommand.setValue (PRINTGMLGRAPH) ;
673
674 found = true ;
675 curarg++ ;
676 }
677 else if (*curarg == "--printgmlvertex") {
678 if (DebugCommand.is_set()) {
679 throw SteghideError (_("you cannot use more than one debug command at a time.")) ;
680 }
681
682 DebugCommand.setValue (PRINTGMLVERTEX) ;
683 curarg++ ;
684
685 int tmp = 0 ;
686 sscanf (curarg->c_str(), "%d", &tmp) ;
687 GmlGraphRecDepth.setValue (tmp) ;
688 curarg++ ;
689 sscanf (curarg->c_str(), "%d", &tmp) ;
690 GmlStartVertex.setValue (tmp) ;
691
692 found = true ;
693 curarg++ ;
694 }
695 else if (*curarg == "--printstats") {
696 if (DebugCommand.is_set()) {
697 throw SteghideError (_("you cannot use more than one debug command at a time.")) ;
698 }
699
700 if (Verbosity.is_set()) {
701 throw ArgError (_("the \"%s\" argument cannot be used here because the verbosity has already been set."), curarg->c_str()) ;
702 }
703
704 Verbosity.setValue (STATS) ;
705
706 found = true ;
707 ++curarg ;
708 }
709 else if (*curarg == "--debuglevel") {
710 if (DebugLevel.is_set()) {
711 throw ArgError (_("the debug level argument can be used only once.")) ;
712 }
713
714 if (++curarg == TheArguments.end()) {
715 throw ArgError (_("the \"%s\" argument must be followed by the debug level."), (curarg - 1)->c_str()) ;
716 }
717
718 unsigned int tmp = 0 ;
719 sscanf (curarg->c_str(), "%u", &tmp) ;
720 DebugLevel.setValue (tmp) ;
721
722 found = true ;
723 ++curarg ;
724 }
725 else if (*curarg == "--check") {
726 // TODO usual error checking (omitted due to message freeze)
727 Check.setValue (true) ;
728
729 found = true ;
730 ++curarg ;
731 }
732
733 return found ;
734 }
735
getPassphrase(bool doublecheck)736 std::string Arguments::getPassphrase (bool doublecheck)
737 {
738 int c = EOF ;
739
740 #ifndef HAVE_TERMIOS_H
741 Warning w (_("unknown terminal. the passphrase you type now will be visible.")) ;
742 w.printMessage() ;
743 #endif
744
745 std::cerr << _("Enter passphrase: ") ;
746 Terminal term ;
747 term.EchoOff() ;
748
749 std::string s1 = "" ;
750 while ((c = std::cin.get()) != '\n') {
751 s1 += c ;
752 }
753
754 term.reset() ;
755 std::cerr << std::endl ;
756
757 if (doublecheck) {
758 std::cerr << _("Re-Enter passphrase: ") ;
759 term.EchoOff() ;
760
761 std::string s2 = "" ;
762 while ((c = std::cin.get()) != '\n') {
763 s2 += c ;
764 }
765
766 term.reset() ;
767 std::cerr << std::endl ;
768
769 if (s1 != s2) {
770 throw SteghideError (_("the passphrases do not match.")) ;
771 }
772 }
773
774 return s1 ;
775 }
776
stdin_isused() const777 bool Arguments::stdin_isused () const
778 {
779 bool retval = false ;
780 if (Command.getValue() == EMBED && (EmbFn.getValue() == "" || CvrFn.getValue() == "")) {
781 retval = true ;
782 }
783 else if (Command.getValue() == EXTRACT && StgFn.getValue() == "") {
784 retval = true ;
785 }
786 else if (Command.getValue() == INFO && CvrFn.getValue() == "") {
787 retval = true ;
788 }
789 return retval ;
790 }
791
setDefaults(void)792 void Arguments::setDefaults (void)
793 {
794 myassert (Command.is_set()) ;
795
796 EmbFn.setValue ("", false) ;
797 CvrFn.setValue ("", false) ;
798 EncAlgo.setValue (Default_EncAlgo, false) ;
799 EncMode.setValue (Default_EncMode, false) ;
800 Checksum.setValue (Default_Checksum, false) ;
801 Compression.setValue (Default_Compression, false) ;
802 EmbedEmbFn.setValue (Default_EmbedEmbFn, false) ;
803 ExtFn.setValue ("", false) ;
804 Passphrase.setValue ("", false) ;
805 StgFn.setValue ("", false) ;
806 Force.setValue (Default_Force, false) ;
807 Verbosity.setValue (Default_Verbosity, false) ;
808 Radius.setValue (Default_Radius, false) ;
809 Goal.setValue (Default_Goal, false) ;
810 Check.setValue (Default_Check, false) ;
811 DebugCommand.setValue (Default_DebugCommand, false) ;
812 DebugLevel.setValue (Default_DebugLevel, false) ;
813 GmlGraphRecDepth.setValue (Default_GmlGraphRecDepth, false) ;
814 GmlStartVertex.setValue (Default_GmlStartVertex, false) ;
815 }
816
817 #ifdef USE_LIBMCRYPT
818 const EncryptionAlgorithm Arguments::Default_EncAlgo = EncryptionAlgorithm (EncryptionAlgorithm::RIJNDAEL128) ;
819 const EncryptionMode Arguments::Default_EncMode = EncryptionMode (EncryptionMode::CBC) ;
820 #else
821 const EncryptionAlgorithm Arguments::Default_EncAlgo = EncryptionAlgorithm (EncryptionAlgorithm::NONE) ;
822 const EncryptionMode Arguments::Default_EncMode = EncryptionMode (EncryptionMode::ECB) ; // is ignored
823 #endif
824