|
|
1.1 ! root 1: /* ! 2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved. ! 3: ! 4: Governed by the TrueCrypt License 2.4 the full text of which is contained ! 5: in the file License.txt included in TrueCrypt binary and source code ! 6: distribution packages. ! 7: */ ! 8: ! 9: #include "System.h" ! 10: #include <wx/cmdline.h> ! 11: #include <wx/tokenzr.h> ! 12: #include "Core/Core.h" ! 13: #include "CommandLineInterface.h" ! 14: #include "LanguageStrings.h" ! 15: #include "UserInterfaceException.h" ! 16: ! 17: namespace TrueCrypt ! 18: { ! 19: CommandLineInterface::CommandLineInterface (wxCmdLineParser &parser, UserInterfaceType::Enum interfaceType) : ! 20: ArgCommand (CommandId::None), ! 21: StartBackgroundTask (false) ! 22: { ! 23: parser.SetSwitchChars (L"-"); ! 24: ! 25: parser.AddOption (L"", L"auto-mount", _("Auto mount device-hosted/favorite volumes")); ! 26: parser.AddSwitch (L"", L"background-task", _("Start Background Task")); ! 27: parser.AddSwitch (L"d", L"dismount", _("Dismount volume")); ! 28: parser.AddSwitch (L"", L"cache", _("Cache passwords and keyfiles")); ! 29: parser.AddSwitch (L"C", L"change", _("Change password or keyfiles")); ! 30: parser.AddSwitch (L"", L"explore", _("Open explorer window for mounted volume")); ! 31: parser.AddSwitch (L"f", L"force", _("Force mount/dismount/overwrite")); ! 32: parser.AddSwitch (L"h", L"help", _("Display help"), wxCMD_LINE_OPTION_HELP); ! 33: parser.AddOption (L"k", L"keyfiles", _("Keyfiles")); ! 34: parser.AddOption (L"", L"filesystem", _("Filesystem type")); ! 35: #if !defined(TC_WINDOWS) && !defined(TC_MACOSX) ! 36: parser.AddOption (L"", L"fs-options", _("Filesystem options")); ! 37: #endif ! 38: parser.AddSwitch (L"l", L"list", _("List mounted volumes")); ! 39: parser.AddOption (L"m", L"mount-options", _("Mount options")); ! 40: parser.AddOption (L"", L"new-keyfiles", _("New keyfiles")); ! 41: parser.AddOption (L"", L"new-password", _("New password")); ! 42: parser.AddSwitch (L"", L"non-interactive", _("Do not interact with user")); ! 43: parser.AddOption (L"p", L"password", _("Password")); ! 44: parser.AddSwitch (L"", L"load-preferences", _("Load user preferences")); ! 45: parser.AddSwitch (L"", L"protect-hidden", _("Protect hidden volume")); ! 46: parser.AddOption (L"", L"protection-keyfiles", _("Keyfiles for protected hidden volume")); ! 47: parser.AddOption (L"", L"protection-password", _("Password for protected hidden volume")); ! 48: parser.AddSwitch (L"v", L"verbose", _("Enable verbose output")); ! 49: parser.AddOption (L"", L"slot", _("Volume slot number")); ! 50: parser.AddSwitch (L"", L"test", _("Test internal algorithms")); ! 51: parser.AddSwitch (L"t", L"text", _("Use text user interface")); ! 52: parser.AddSwitch (L"", L"version", _("Display version information")); ! 53: parser.AddParam ( _("Volume path"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); ! 54: parser.AddParam ( _("Mount point"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); ! 55: ! 56: wxString str; ! 57: bool param1IsVolume = false; ! 58: bool param1IsMountedVolumeSpec = false; ! 59: bool param1IsMountPoint = false; ! 60: ! 61: if (parser.Parse () > 0) ! 62: throw_err (_("Incorrect command line specified.")); ! 63: ! 64: if (parser.Found (L"help")) ! 65: { ! 66: ArgCommand = CommandId::Help; ! 67: return; ! 68: } ! 69: ! 70: if (parser.Found (L"text") && interfaceType != UserInterfaceType::Text) ! 71: { ! 72: wstring msg = wstring (_("Option -t or --text must be specified as the first argument.")); ! 73: wcerr << msg << endl; ! 74: throw_err (msg); ! 75: } ! 76: ! 77: if (parser.Found (L"version")) ! 78: { ! 79: ArgCommand = CommandId::DisplayVersion; ! 80: return; ! 81: } ! 82: ! 83: // Preferences ! 84: if (parser.Found (L"load-preferences")) ! 85: { ! 86: // Load preferences first to allow command line options to override them ! 87: Preferences.Load(); ! 88: ArgMountOptions = Preferences.DefaultMountOptions; ! 89: } ! 90: ! 91: // Commands ! 92: if (parser.Found (L"auto-mount", &str)) ! 93: { ! 94: CheckCommandSingle(); ! 95: ! 96: wxStringTokenizer tokenizer (str, L","); ! 97: while (tokenizer.HasMoreTokens()) ! 98: { ! 99: wxString token = tokenizer.GetNextToken(); ! 100: ! 101: if (token == L"devices") ! 102: { ! 103: if (ArgCommand == CommandId::AutoMountFavorites) ! 104: ArgCommand = CommandId::AutoMountDevicesFavorites; ! 105: else ! 106: ArgCommand = CommandId::AutoMountDevices; ! 107: ! 108: param1IsMountPoint = true; ! 109: } ! 110: else if (token == L"favorites") ! 111: { ! 112: if (ArgCommand == CommandId::AutoMountDevices) ! 113: ArgCommand = CommandId::AutoMountDevicesFavorites; ! 114: else ! 115: ArgCommand = CommandId::AutoMountFavorites; ! 116: } ! 117: else ! 118: { ! 119: throw_err (LangString["UNKNOWN_OPTION"] + L": " + token); ! 120: } ! 121: } ! 122: } ! 123: ! 124: if (parser.Found (L"change")) ! 125: { ! 126: CheckCommandSingle(); ! 127: ArgCommand = CommandId::ChangePassword; ! 128: param1IsVolume = true; ! 129: } ! 130: ! 131: if (parser.Found (L"dismount")) ! 132: { ! 133: CheckCommandSingle(); ! 134: ArgCommand = CommandId::DismountVolumes; ! 135: param1IsMountedVolumeSpec = true; ! 136: } ! 137: ! 138: if (parser.Found (L"list")) ! 139: { ! 140: CheckCommandSingle(); ! 141: ArgCommand = CommandId::ListVolumes; ! 142: param1IsMountedVolumeSpec = true; ! 143: } ! 144: ! 145: if (parser.Found (L"test")) ! 146: { ! 147: CheckCommandSingle(); ! 148: ArgCommand = CommandId::Test; ! 149: } ! 150: ! 151: // Options ! 152: if (parser.Found (L"background-task")) ! 153: StartBackgroundTask = true; ! 154: ! 155: if (parser.Found (L"cache")) ! 156: ArgMountOptions.CachePassword = true; ! 157: ! 158: if (parser.Found (L"explore")) ! 159: Preferences.OpenExplorerWindowAfterMount = true; ! 160: ! 161: if (parser.Found (L"filesystem", &str)) ! 162: { ! 163: if (str.IsSameAs (L"none", false)) ! 164: ArgMountOptions.NoFilesystem = true; ! 165: else ! 166: ArgMountOptions.FilesystemType = wstring (str); ! 167: } ! 168: ! 169: if (parser.Found (L"force")) ! 170: ArgForce = true; ! 171: ! 172: if (parser.Found (L"keyfiles", &str)) ! 173: ArgKeyfiles = ToKeyfileList (str); ! 174: ! 175: if (parser.Found (L"mount-options", &str)) ! 176: { ! 177: wxStringTokenizer tokenizer (str, L","); ! 178: while (tokenizer.HasMoreTokens()) ! 179: { ! 180: wxString token = tokenizer.GetNextToken(); ! 181: ! 182: if (token == L"readonly" || token == L"ro") ! 183: ArgMountOptions.Protection = VolumeProtection::ReadOnly; ! 184: else if (token == L"timestamp" || token == L"ts") ! 185: ArgMountOptions.PreserveTimestamps = false; ! 186: #ifdef TC_WINDOWS ! 187: else if (token == L"removable" || token == L"rm") ! 188: ArgMountOptions.Removable = true; ! 189: #endif ! 190: else ! 191: throw_err (LangString["UNKNOWN_OPTION"] + L": " + token); ! 192: } ! 193: } ! 194: ! 195: if (parser.Found (L"new-keyfiles", &str)) ! 196: ArgNewKeyfiles = ToKeyfileList (str); ! 197: ! 198: if (parser.Found (L"new-password", &str)) ! 199: ArgNewPassword.reset (new VolumePassword (wstring (str))); ! 200: ! 201: if (parser.Found (L"non-interactive")) ! 202: Preferences.NonInteractive = true; ! 203: ! 204: if (parser.Found (L"password", &str)) ! 205: ArgPassword.reset (new VolumePassword (wstring (str))); ! 206: ! 207: if (parser.Found (L"protect-hidden") && ArgMountOptions.Protection != VolumeProtection::ReadOnly) ! 208: ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly; ! 209: ! 210: if (parser.Found (L"protection-keyfiles", &str)) ! 211: { ! 212: ArgMountOptions.ProtectionKeyfiles = ToKeyfileList (str); ! 213: ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly; ! 214: } ! 215: ! 216: if (parser.Found (L"protection-password", &str)) ! 217: { ! 218: ArgMountOptions.ProtectionPassword.reset (new VolumePassword (wstring (str))); ! 219: ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly; ! 220: } ! 221: ! 222: if (parser.Found (L"slot", &str)) ! 223: { ! 224: unsigned long number; ! 225: if (!str.ToULong (&number) || number < Core->GetFirstSlotNumber() || number > Core->GetLastSlotNumber()) ! 226: throw_err (LangString["PARAMETER_INCORRECT"] + L": " + str); ! 227: ! 228: ArgMountOptions.SlotNumber = number; ! 229: ! 230: if (param1IsMountedVolumeSpec) ! 231: { ! 232: shared_ptr <VolumeInfo> volume = Core->GetMountedVolume (number); ! 233: if (!volume) ! 234: throw_err (_("No such volume is mounted.")); ! 235: ! 236: ArgVolumes.push_back (volume); ! 237: param1IsMountedVolumeSpec = false; ! 238: } ! 239: } ! 240: ! 241: if (parser.Found (L"verbose")) ! 242: Preferences.Verbose = true; ! 243: ! 244: // Parameters ! 245: if (parser.GetParamCount() > 0) ! 246: { ! 247: if (ArgCommand == CommandId::None) ! 248: { ! 249: ArgCommand = CommandId::MountVolume; ! 250: param1IsVolume = true; ! 251: } ! 252: ! 253: if (param1IsVolume) ! 254: { ! 255: wxFileName volPath (parser.GetParam (0)); ! 256: ! 257: #ifdef TC_WINDOWS ! 258: if (!parser.GetParam (0).StartsWith (L"\\Device\\")) ! 259: #endif ! 260: volPath.Normalize (wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS); ! 261: ! 262: ArgVolumePath.reset (new VolumePath (wstring (volPath.GetFullPath()))); ! 263: } ! 264: ! 265: if (param1IsMountPoint || parser.GetParamCount() >= 2) ! 266: { ! 267: wstring s (parser.GetParam (param1IsMountPoint ? 0 : 1)); ! 268: wxFileName mountPoint (wstring (Directory::AppendSeparator (s))); ! 269: mountPoint.Normalize (wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS); ! 270: ArgMountPoint.reset (new DirectoryPath (wstring (mountPoint.GetPath()))); ! 271: } ! 272: } ! 273: ! 274: if (param1IsMountedVolumeSpec) ! 275: ArgVolumes = GetMountedVolumes (parser.GetParamCount() > 0 ? parser.GetParam (0) : wxString()); ! 276: } ! 277: ! 278: CommandLineInterface::~CommandLineInterface () ! 279: { ! 280: } ! 281: ! 282: void CommandLineInterface::CheckCommandSingle () const ! 283: { ! 284: if (ArgCommand != CommandId::None) ! 285: throw_err (_("Only a single command can be specified at a time.")); ! 286: } ! 287: ! 288: shared_ptr <KeyfileList> CommandLineInterface::ToKeyfileList (const wxString &arg) const ! 289: { ! 290: wxStringTokenizer tokenizer (arg, L",", wxTOKEN_RET_EMPTY_ALL); ! 291: ! 292: // Handle escaped separator ! 293: wxArrayString arr; ! 294: bool prevEmpty = false; ! 295: while (tokenizer.HasMoreTokens()) ! 296: { ! 297: wxString token = tokenizer.GetNextToken(); ! 298: ! 299: if (prevEmpty && token.empty() && tokenizer.HasMoreTokens()) ! 300: { ! 301: token = tokenizer.GetNextToken(); ! 302: if (!token.empty()) ! 303: { ! 304: arr.Add (token); ! 305: prevEmpty = true; ! 306: continue; ! 307: } ! 308: } ! 309: ! 310: if (token.empty() && !tokenizer.HasMoreTokens()) ! 311: break; ! 312: ! 313: if (prevEmpty || token.empty()) ! 314: { ! 315: if (arr.Count() < 1) ! 316: { ! 317: arr.Add (L""); ! 318: continue; ! 319: } ! 320: arr.Last() += token.empty() ? L',' : token; ! 321: } ! 322: else ! 323: arr.Add (token); ! 324: ! 325: prevEmpty = token.empty(); ! 326: } ! 327: ! 328: make_shared_auto (KeyfileList, keyfileList); ! 329: for (size_t i = 0; i < arr.GetCount(); i++) ! 330: { ! 331: if (!arr[i].empty()) ! 332: keyfileList->push_back (make_shared <Keyfile> (wstring (arr[i]))); ! 333: } ! 334: ! 335: return keyfileList; ! 336: } ! 337: ! 338: VolumeInfoList CommandLineInterface::GetMountedVolumes (const wxString &mountedVolumeSpec) const ! 339: { ! 340: VolumeInfoList volumes = Core->GetMountedVolumes (); ! 341: VolumeInfoList filteredVolumes; ! 342: ! 343: wxFileName pathFilter; ! 344: if (!mountedVolumeSpec.empty()) ! 345: { ! 346: pathFilter = mountedVolumeSpec; ! 347: pathFilter.Normalize (wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS); ! 348: } ! 349: else ! 350: return volumes; ! 351: ! 352: foreach (shared_ptr <VolumeInfo> volume, volumes) ! 353: { ! 354: if (mountedVolumeSpec.empty()) ! 355: { ! 356: filteredVolumes.push_back (volume); ! 357: } ! 358: else if (wxString (volume->Path) == pathFilter.GetFullPath()) ! 359: { ! 360: filteredVolumes.push_back (volume); ! 361: } ! 362: else if (wxString (volume->MountPoint) == pathFilter.GetFullPath() ! 363: || (wxString (volume->MountPoint) + wxFileName::GetPathSeparator()) == pathFilter.GetFullPath()) ! 364: { ! 365: filteredVolumes.push_back (volume); ! 366: } ! 367: } ! 368: ! 369: if (!mountedVolumeSpec.IsEmpty() && filteredVolumes.size() < 1) ! 370: throw_err (_("No such volume is mounted.")); ! 371: ! 372: return filteredVolumes; ! 373: } ! 374: ! 375: auto_ptr <CommandLineInterface> CmdLine; ! 376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.