Changeset 94660 in vbox for trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
- Timestamp:
- Apr 21, 2022 8:38:34 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
r94234 r94660 59 59 DECLARE_TRANSLATION_CONTEXT(Misc); 60 60 61 static const RTGETOPTDEF g_aRegisterVMOptions[] = 62 { 63 { "--password", 'p', RTGETOPT_REQ_STRING }, 64 }; 65 61 66 RTEXITCODE handleRegisterVM(HandlerArg *a) 62 67 { 63 68 HRESULT rc; 64 65 if (a->argc != 1) 66 return errorSyntax(Misc::tr("Incorrect number of parameters")); 69 const char *VMName = NULL; 70 71 Bstr bstrVMName; 72 Bstr bstrPasswordFile; 73 74 int c; 75 RTGETOPTUNION ValueUnion; 76 RTGETOPTSTATE GetState; 77 // start at 0 because main() has hacked both the argc and argv given to us 78 RTGetOptInit(&GetState, a->argc, a->argv, g_aRegisterVMOptions, RT_ELEMENTS(g_aRegisterVMOptions), 79 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 80 while ((c = RTGetOpt(&GetState, &ValueUnion))) 81 { 82 switch (c) 83 { 84 case 'p': // --password 85 bstrPasswordFile = ValueUnion.psz; 86 break; 87 88 case VINF_GETOPT_NOT_OPTION: 89 if (bstrVMName.isEmpty()) 90 VMName = ValueUnion.psz; 91 else 92 return errorSyntax(Misc::tr("Invalid parameter '%s'"), ValueUnion.psz); 93 break; 94 95 default: 96 if (c > 0) 97 { 98 if (RT_C_IS_PRINT(c)) 99 return errorSyntax(Misc::tr("Invalid option -%c"), c); 100 return errorSyntax(Misc::tr("Invalid option case %i"), c); 101 } 102 if (c == VERR_GETOPT_UNKNOWN_OPTION) 103 return errorSyntax(Misc::tr("unknown option: %s\n"), ValueUnion.psz); 104 if (ValueUnion.pDef) 105 return errorSyntax("%s: %Rrs", ValueUnion.pDef->pszLong, c); 106 return errorSyntax(Misc::tr("error: %Rrs"), c); 107 } 108 } 109 110 Utf8Str strPassword; 111 112 if (bstrPasswordFile.isNotEmpty()) 113 { 114 if (bstrPasswordFile == "-") 115 { 116 /* Get password from console. */ 117 RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, Misc::tr("Enter password:")); 118 if (rcExit == RTEXITCODE_FAILURE) 119 return rcExit; 120 } 121 else 122 { 123 RTEXITCODE rcExit = readPasswordFile(a->argv[3], &strPassword); 124 if (rcExit == RTEXITCODE_FAILURE) 125 return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Failed to read password from file")); 126 } 127 } 67 128 68 129 ComPtr<IMachine> machine; … … 71 132 * has been redesigned. */ 72 133 rc = a->virtualBox->OpenMachine(Bstr(a->argv[0]).raw(), 134 Bstr(strPassword).raw(), 73 135 machine.asOutParam()); 74 136 if (rc == VBOX_E_FILE_ERROR) … … 80 142 a->argv[0], vrc); 81 143 CHECK_ERROR(a->virtualBox, OpenMachine(Bstr(szVMFileAbs).raw(), 144 Bstr(strPassword).raw(), 82 145 machine.asOutParam())); 83 146 } 84 147 else if (FAILED(rc)) 85 148 CHECK_ERROR(a->virtualBox, OpenMachine(Bstr(a->argv[0]).raw(), 149 Bstr(strPassword).raw(), 86 150 machine.asOutParam())); 87 151 if (SUCCEEDED(rc)) … … 194 258 { "--default", 'd', RTGETOPT_REQ_NOTHING }, 195 259 { "-default", 'd', RTGETOPT_REQ_NOTHING }, 260 { "--cipher", 'c', RTGETOPT_REQ_STRING }, 261 { "-cipher", 'c', RTGETOPT_REQ_STRING }, 262 { "--password-id", 'i', RTGETOPT_REQ_STRING }, 263 { "-password-id", 'i', RTGETOPT_REQ_STRING }, 264 { "--password", 'w', RTGETOPT_REQ_STRING }, 265 { "-password", 'w', RTGETOPT_REQ_STRING }, 196 266 }; 197 267 … … 208 278 Bstr bstrDefaultFlags; 209 279 com::SafeArray<BSTR> groups; 280 Bstr bstrCipher; 281 Bstr bstrPasswordId; 282 const char *pszPassword = NULL; 210 283 211 284 int c; … … 245 318 case 'd': // --default 246 319 fDefault = true; 320 break; 321 322 case 'c': // --cipher 323 bstrCipher = ValueUnion.psz; 324 break; 325 326 case 'i': // --password-id 327 bstrPasswordId = ValueUnion.psz; 328 break; 329 330 case 'w': // --password 331 pszPassword = ValueUnion.psz; 247 332 break; 248 333 … … 271 356 bstrBaseFolder.raw(), 272 357 bstrSettingsFile.asOutParam())); 358 Utf8Str strPassword; 359 if (pszPassword) 360 { 361 if (!RTStrCmp(pszPassword, "-")) 362 { 363 /* Get password from console. */ 364 RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:"); 365 if (rcExit == RTEXITCODE_FAILURE) 366 return rcExit; 367 } 368 else 369 { 370 RTEXITCODE rcExit = readPasswordFile(pszPassword, &strPassword); 371 if (rcExit == RTEXITCODE_FAILURE) 372 { 373 RTMsgError("Failed to read new password from file"); 374 return rcExit; 375 } 376 } 377 } 273 378 ComPtr<IMachine> machine; 274 379 CHECK_ERROR_BREAK(a->virtualBox, … … 278 383 bstrOsTypeId.raw(), 279 384 createFlags.raw(), 385 bstrCipher.raw(), 386 bstrPasswordId.raw(), 387 Bstr(strPassword).raw(), 280 388 machine.asOutParam())); 281 389 … … 583 691 NULL, 584 692 createFlags.raw(), 693 NULL, 694 NULL, 695 NULL, 585 696 trgMachine.asOutParam()), 586 697 RTEXITCODE_FAILURE); … … 612 723 Bstr sessionType; 613 724 com::SafeArray<IN_BSTR> aBstrEnv; 725 const char *pszPassword = NULL; 726 const char *pszPasswordId = NULL; 727 Utf8Str strPassword; 614 728 615 729 #if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) … … 630 744 { "-type", 't', RTGETOPT_REQ_STRING }, // deprecated 631 745 { "--putenv", 'E', RTGETOPT_REQ_STRING }, 746 { "--password", 'p', RTGETOPT_REQ_STRING }, 747 { "--password-id", 'i', RTGETOPT_REQ_STRING } 632 748 }; 633 749 int c; … … 673 789 break; 674 790 791 case 'p': // --password 792 pszPassword = ValueUnion.psz; 793 break; 794 795 case 'i': // --password-id 796 pszPasswordId = ValueUnion.psz; 797 break; 798 675 799 case VINF_GETOPT_NOT_OPTION: 676 800 VMs.push_back(ValueUnion.psz); … … 698 822 return errorSyntax(Misc::tr("at least one VM name or uuid required")); 699 823 824 if (!RTStrCmp(pszPassword, "-")) 825 { 826 /* Get password from console. */ 827 RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:"); 828 if (rcExit == RTEXITCODE_FAILURE) 829 return rcExit; 830 } 831 else 832 { 833 RTEXITCODE rcExit = readPasswordFile(pszPassword, &strPassword); 834 if (rcExit == RTEXITCODE_FAILURE) 835 { 836 RTMsgError("Failed to read new password from file"); 837 return rcExit; 838 } 839 } 840 700 841 for (std::list<const char *>::const_iterator it = VMs.begin(); 701 842 it != VMs.end(); … … 709 850 if (machine) 710 851 { 711 ComPtr<IProgress> progress; 712 CHECK_ERROR(machine, LaunchVMProcess(a->session, sessionType.raw(), 713 ComSafeArrayAsInParam(aBstrEnv), progress.asOutParam())); 714 if (SUCCEEDED(rc) && !progress.isNull()) 852 if (pszPasswordId && strPassword.isNotEmpty()) 715 853 { 716 RTPrintf(Misc::tr("Waiting for VM \"%s\" to power on...\n"), pszVM); 717 CHECK_ERROR(progress, WaitForCompletion(-1)); 718 if (SUCCEEDED(rc)) 854 CHECK_ERROR(machine, AddEncryptionPassword(Bstr(pszPasswordId).raw(), Bstr(strPassword).raw())); 855 if (rc == VBOX_E_PASSWORD_INCORRECT) 856 RTMsgError("Password incorrect!"); 857 } 858 if (SUCCEEDED(rc)) 859 { 860 ComPtr<IProgress> progress; 861 CHECK_ERROR(machine, LaunchVMProcess(a->session, sessionType.raw(), 862 ComSafeArrayAsInParam(aBstrEnv), progress.asOutParam())); 863 if (SUCCEEDED(rc) && !progress.isNull()) 719 864 { 720 BOOL completed = true;721 CHECK_ERROR(progress, COMGETTER(Completed)(&completed));865 RTPrintf("Waiting for VM \"%s\" to power on...\n", pszVM); 866 CHECK_ERROR(progress, WaitForCompletion(-1)); 722 867 if (SUCCEEDED(rc)) 723 868 { 724 ASSERT(completed); 725 726 LONG iRc; 727 CHECK_ERROR(progress, COMGETTER(ResultCode)(&iRc)); 869 BOOL completed = true; 870 CHECK_ERROR(progress, COMGETTER(Completed)(&completed)); 728 871 if (SUCCEEDED(rc)) 729 872 { 730 if (SUCCEEDED(iRc)) 731 RTPrintf(Misc::tr("VM \"%s\" has been successfully started.\n"), pszVM); 732 else 873 ASSERT(completed); 874 875 LONG iRc; 876 CHECK_ERROR(progress, COMGETTER(ResultCode)(&iRc)); 877 if (SUCCEEDED(rc)) 733 878 { 734 ProgressErrorInfo info(progress); 735 com::GluePrintErrorInfo(info); 879 if (SUCCEEDED(iRc)) 880 RTPrintf("VM \"%s\" has been successfully started.\n", pszVM); 881 else 882 { 883 ProgressErrorInfo info(progress); 884 com::GluePrintErrorInfo(info); 885 } 886 rc = iRc; 736 887 } 737 rc = iRc;738 888 } 739 889 } … … 752 902 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 753 903 } 904 905 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 906 static const RTGETOPTDEF g_aSetVMEncryptionOptions[] = 907 { 908 { "--new-password", 'n', RTGETOPT_REQ_STRING }, 909 { "--old-password", 'o', RTGETOPT_REQ_STRING }, 910 { "--cipher", 'c', RTGETOPT_REQ_STRING }, 911 { "--new-password-id", 'i', RTGETOPT_REQ_STRING }, 912 { "--force", 'f', RTGETOPT_REQ_NOTHING}, 913 }; 914 915 RTEXITCODE handleSetVMEncryption(HandlerArg *a, const char *pszFilenameOrUuid) 916 { 917 HRESULT rc; 918 ComPtr<IMachine> machine; 919 const char *pszPasswordNew = NULL; 920 const char *pszPasswordOld = NULL; 921 const char *pszCipher = NULL; 922 const char *pszNewPasswordId = NULL; 923 BOOL fForce = FALSE; 924 Utf8Str strPasswordNew; 925 Utf8Str strPasswordOld; 926 927 int c; 928 RTGETOPTUNION ValueUnion; 929 RTGETOPTSTATE GetState; 930 // start at 0 because main() has hacked both the argc and argv given to us 931 RTGetOptInit(&GetState, a->argc, a->argv, g_aSetVMEncryptionOptions, RT_ELEMENTS(g_aSetVMEncryptionOptions), 932 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 933 while ((c = RTGetOpt(&GetState, &ValueUnion))) 934 { 935 switch (c) 936 { 937 case 'n': // --new-password 938 pszPasswordNew = ValueUnion.psz; 939 break; 940 941 case 'o': // --old-password 942 pszPasswordOld = ValueUnion.psz; 943 break; 944 945 case 'c': // --cipher 946 pszCipher = ValueUnion.psz; 947 break; 948 949 case 'i': // --new-password-id 950 pszNewPasswordId = ValueUnion.psz; 951 break; 952 953 case 'f': // --force 954 fForce = TRUE; 955 break; 956 957 default: 958 if (c > 0) 959 { 960 if (RT_C_IS_PRINT(c)) 961 return errorSyntax(Misc::tr("Invalid option -%c"), c); 962 else 963 return errorSyntax(Misc::tr("Invalid option case %i"), c); 964 } 965 else if (c == VERR_GETOPT_UNKNOWN_OPTION) 966 return errorSyntax(Misc::tr("unknown option: %s\n"), ValueUnion.psz); 967 else if (ValueUnion.pDef) 968 return errorSyntax(Misc::tr("%s: %Rrs"), ValueUnion.pDef->pszLong, c); 969 else 970 return errorSyntax(Misc::tr("error: %Rrs"), c); 971 } 972 } 973 974 if (!pszFilenameOrUuid) 975 return errorSyntax(Misc::tr("VM name or UUID required")); 976 977 if (!pszPasswordNew && !pszPasswordOld) 978 return errorSyntax(Misc::tr("No password specified")); 979 980 if ( (pszPasswordNew && !pszNewPasswordId) 981 || (!pszPasswordNew && pszNewPasswordId)) 982 return errorSyntax(Misc::tr("A new password must always have a valid identifier set at the same time")); 983 984 if (pszPasswordOld) 985 { 986 if (!RTStrCmp(pszPasswordOld, "-")) 987 { 988 /* Get password from console. */ 989 RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordOld, "Enter old password:"); 990 if (rcExit == RTEXITCODE_FAILURE) 991 return rcExit; 992 } 993 else 994 { 995 RTEXITCODE rcExit = readPasswordFile(pszPasswordOld, &strPasswordOld); 996 if (rcExit == RTEXITCODE_FAILURE) 997 { 998 RTMsgError("Failed to read old password from file"); 999 return rcExit; 1000 } 1001 } 1002 } 1003 if (pszPasswordNew) 1004 { 1005 if (!RTStrCmp(pszPasswordNew, "-")) 1006 { 1007 /* Get password from console. */ 1008 RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordNew, "Enter new password:"); 1009 if (rcExit == RTEXITCODE_FAILURE) 1010 return rcExit; 1011 } 1012 else 1013 { 1014 RTEXITCODE rcExit = readPasswordFile(pszPasswordNew, &strPasswordNew); 1015 if (rcExit == RTEXITCODE_FAILURE) 1016 { 1017 RTMsgError("Failed to read new password from file"); 1018 return rcExit; 1019 } 1020 } 1021 } 1022 1023 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszFilenameOrUuid).raw(), 1024 machine.asOutParam())); 1025 if (machine) 1026 { 1027 ComPtr<IProgress> progress; 1028 CHECK_ERROR(machine, ChangeEncryption(Bstr(strPasswordOld).raw(), Bstr(pszCipher).raw(), 1029 Bstr(strPasswordNew).raw(), Bstr(pszNewPasswordId).raw(), 1030 fForce, progress.asOutParam())); 1031 if (SUCCEEDED(rc)) 1032 rc = showProgress(progress); 1033 if (FAILED(rc)) 1034 { 1035 if (rc == E_NOTIMPL) 1036 RTMsgError("Encrypt VM operation is not implemented!"); 1037 else if (rc == VBOX_E_NOT_SUPPORTED) 1038 RTMsgError("Encrypt VM operation for this cipher is not implemented yet!"); 1039 else if (!progress.isNull()) 1040 CHECK_PROGRESS_ERROR(progress, ("Failed to encrypt the VM")); 1041 else 1042 RTMsgError("Failed to encrypt the VM!"); 1043 } 1044 } 1045 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 1046 } 1047 1048 RTEXITCODE handleCheckVMPassword(HandlerArg *a, const char *pszFilenameOrUuid) 1049 { 1050 HRESULT rc; 1051 ComPtr<IMachine> machine; 1052 Utf8Str strPassword; 1053 1054 if (a->argc != 1) 1055 return errorSyntax(Misc::tr("Invalid number of arguments: %d"), a->argc); 1056 1057 if (!RTStrCmp(a->argv[0], "-")) 1058 { 1059 /* Get password from console. */ 1060 RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:"); 1061 if (rcExit == RTEXITCODE_FAILURE) 1062 return rcExit; 1063 } 1064 else 1065 { 1066 RTEXITCODE rcExit = readPasswordFile(a->argv[0], &strPassword); 1067 if (rcExit == RTEXITCODE_FAILURE) 1068 { 1069 RTMsgError("Failed to read password from file"); 1070 return rcExit; 1071 } 1072 } 1073 1074 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszFilenameOrUuid).raw(), 1075 machine.asOutParam())); 1076 if (machine) 1077 { 1078 CHECK_ERROR(machine, CheckEncryptionPassword(Bstr(strPassword).raw())); 1079 if (SUCCEEDED(rc)) 1080 RTPrintf("The given password is correct\n"); 1081 } 1082 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 1083 } 1084 1085 static const RTGETOPTDEF g_aAddVMOptions[] = 1086 { 1087 { "--password", 'p', RTGETOPT_REQ_STRING }, 1088 { "--password-id", 'i', RTGETOPT_REQ_STRING } 1089 }; 1090 1091 RTEXITCODE handleAddVMPassword(HandlerArg *a, const char *pszFilenameOrUuid) 1092 { 1093 HRESULT rc; 1094 ComPtr<IMachine> machine; 1095 const char *pszPassword = NULL; 1096 const char *pszPasswordId = NULL; 1097 Utf8Str strPassword; 1098 1099 int c; 1100 RTGETOPTUNION ValueUnion; 1101 RTGETOPTSTATE GetState; 1102 // start at 0 because main() has hacked both the argc and argv given to us 1103 RTGetOptInit(&GetState, a->argc, a->argv, g_aAddVMOptions, RT_ELEMENTS(g_aAddVMOptions), 1104 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 1105 while ((c = RTGetOpt(&GetState, &ValueUnion))) 1106 { 1107 switch (c) 1108 { 1109 case 'p': // --password 1110 pszPassword = ValueUnion.psz; 1111 break; 1112 1113 case 'i': // --password-id 1114 pszPasswordId = ValueUnion.psz; 1115 break; 1116 1117 default: 1118 if (c > 0) 1119 { 1120 if (RT_C_IS_PRINT(c)) 1121 return errorSyntax(Misc::tr("Invalid option -%c"), c); 1122 else 1123 return errorSyntax(Misc::tr("Invalid option case %i"), c); 1124 } 1125 else if (c == VERR_GETOPT_UNKNOWN_OPTION) 1126 return errorSyntax(Misc::tr("unknown option: %s\n"), ValueUnion.psz); 1127 else if (ValueUnion.pDef) 1128 return errorSyntax(Misc::tr("%s: %Rrs"), ValueUnion.pDef->pszLong, c); 1129 else 1130 return errorSyntax(Misc::tr("error: %Rrs"), c); 1131 } 1132 } 1133 1134 if (!pszFilenameOrUuid) 1135 return errorSyntax(Misc::tr("VM name or UUID required")); 1136 1137 if (!pszPassword) 1138 return errorSyntax(Misc::tr("No password specified")); 1139 1140 if (!pszPasswordId) 1141 return errorSyntax(Misc::tr("No password identifier specified")); 1142 1143 if (!RTStrCmp(pszPassword, "-")) 1144 { 1145 /* Get password from console. */ 1146 RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter the password:"); 1147 if (rcExit == RTEXITCODE_FAILURE) 1148 return rcExit; 1149 } 1150 else 1151 { 1152 RTEXITCODE rcExit = readPasswordFile(pszPassword, &strPassword); 1153 if (rcExit == RTEXITCODE_FAILURE) 1154 { 1155 RTMsgError("Failed to read new password from file"); 1156 return rcExit; 1157 } 1158 } 1159 1160 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszFilenameOrUuid).raw(), 1161 machine.asOutParam())); 1162 if (machine) 1163 { 1164 ComPtr<IProgress> progress; 1165 CHECK_ERROR(machine, AddEncryptionPassword(Bstr(pszPasswordId).raw(), Bstr(strPassword).raw())); 1166 if (rc == VBOX_E_PASSWORD_INCORRECT) 1167 RTMsgError("Password incorrect!"); 1168 } 1169 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 1170 } 1171 1172 RTEXITCODE handleRemoveVMPassword(HandlerArg *a, const char *pszFilenameOrUuid) 1173 { 1174 HRESULT rc; 1175 ComPtr<IMachine> machine; 1176 1177 if (a->argc != 1) 1178 return errorSyntax(Misc::tr("Invalid number of arguments: %d"), a->argc); 1179 1180 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszFilenameOrUuid).raw(), 1181 machine.asOutParam())); 1182 if (machine) 1183 { 1184 CHECK_ERROR(machine, RemoveEncryptionPassword(Bstr(a->argv[0]).raw())); 1185 if (rc == VBOX_E_INVALID_VM_STATE) 1186 RTMsgError("The machine is in online or transient state\n"); 1187 } 1188 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 1189 } 1190 1191 RTEXITCODE handleEncryptVM(HandlerArg *a) 1192 { 1193 if (a->argc < 2) 1194 return errorSyntax(Misc::tr("subcommand required")); 1195 1196 HandlerArg handlerArg; 1197 handlerArg.argc = a->argc - 2; 1198 handlerArg.argv = &a->argv[2]; 1199 handlerArg.virtualBox = a->virtualBox; 1200 handlerArg.session = a->session; 1201 if (!strcmp(a->argv[1], "setencryption")) 1202 return handleSetVMEncryption(&handlerArg, a->argv[0]); 1203 if (!strcmp(a->argv[1], "checkpassword")) 1204 return handleCheckVMPassword(&handlerArg, a->argv[0]); 1205 if (!strcmp(a->argv[1], "addpassword")) 1206 return handleAddVMPassword(&handlerArg, a->argv[0]); 1207 if (!strcmp(a->argv[1], "removepassword")) 1208 return handleRemoveVMPassword(&handlerArg, a->argv[0]); 1209 return errorSyntax(Misc::tr("unknown subcommand")); 1210 } 1211 #endif /* !VBOX_WITH_FULL_VM_ENCRYPTION */ 754 1212 755 1213 RTEXITCODE handleDiscardState(HandlerArg *a)
Note:
See TracChangeset
for help on using the changeset viewer.