Annotation of truecrypt/main/commandlineinterface.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.