~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to lib/foundryMsg/foundryMsg.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-03-31 14:20:05 UTC
  • mfrom: (1.4.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110331142005-3n9red91p7ogkweo
Tags: 2011.03.28-387002-0ubuntu1
* Merge latest upstream git tag.  This has the unlocked_ioctl change
  needed to fix dkms build failures (LP: #727342)
* Changes in debian/rules:
  - work around a bug in toolbox/Makefile, where install-exec-hook is
    not happening.  This needs to get fixed the right way.
  - don't install 'vmware-user' which seems to no longer exist
  - move /etc/xdg into open-vm-toolbox (which should be done using .install)
* debian/open-vm-tools.init: add 'modprobe [-r] vmblock'. (LP: #332323)
* debian/rules and debian/open-vm-toolbox.lintian-overrides:
  - Make vmware-user-suid-wrapper suid-root (LP: #332323)

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 
34
34
#include "vixOpenSource.h"
35
35
#include "vixCommands.h"
 
36
#include "unicodeBase.h"
36
37
 
37
38
static char PlainToObfuscatedCharMap[256];
38
39
static char ObfuscatedToPlainCharMap[256];
125
126
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
126
127
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_UPGRADE_VIRTUAL_HARDWARE,
127
128
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
128
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_NIC_BANDWIDTH,
129
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
130
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_DISK,
131
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
132
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_FLOPPY,
133
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
 
129
   VIX_DEFINE_UNUSED_COMMAND,
 
130
   VIX_DEFINE_UNUSED_COMMAND,
 
131
   VIX_DEFINE_UNUSED_COMMAND,
134
132
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_RELOAD_VM,
135
133
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
136
134
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_VM,
137
135
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
138
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SYNCDRIVER_FREEZE,
139
 
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
140
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SYNCDRIVER_THAW,
141
 
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
136
   VIX_DEFINE_UNUSED_COMMAND,
 
137
   VIX_DEFINE_UNUSED_COMMAND,
142
138
   VIX_DEFINE_UNUSED_COMMAND,
143
139
   VIX_DEFINE_UNUSED_COMMAND,
144
140
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_GUEST_PRINTER,
317
313
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VM_UNPAUSE,
318
314
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
319
315
   VIX_DEFINE_UNUSED_COMMAND,
320
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_REPLAY_SPEED,
321
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
 
316
   VIX_DEFINE_UNUSED_COMMAND,
322
317
   VIX_DEFINE_UNUSED_COMMAND,
323
318
   VIX_DEFINE_UNUSED_COMMAND,
324
319
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_PERFORMANCE_DATA,
325
320
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
326
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REFRESH_RUNTIME_PROPERTIES,
327
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
 
321
   VIX_DEFINE_UNUSED_COMMAND,
328
322
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_SNAPSHOT_SCREENSHOT,
329
323
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
330
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ADD_TIMEMARKER,
331
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
 
324
   VIX_DEFINE_UNUSED_COMMAND,
332
325
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_WAIT_FOR_USER_ACTION_IN_GUEST,
333
326
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
334
327
   VIX_DEFINE_UNUSED_COMMAND,
349
342
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
350
343
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DEBUGGER_SEND_COMMAND,
351
344
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
352
 
 
353
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_RECORD_STATE,
354
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
355
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_RECORD_STATE,
356
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
357
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_RECORD_STATE,
358
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
359
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_REPLAY_STATE,
360
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
361
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_REPLAY_STATE,
362
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
363
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_REPLAY_STATE,
364
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
 
345
   VIX_DEFINE_UNUSED_COMMAND,
 
346
   VIX_DEFINE_UNUSED_COMMAND,
 
347
   VIX_DEFINE_UNUSED_COMMAND,
 
348
   VIX_DEFINE_UNUSED_COMMAND,
 
349
   VIX_DEFINE_UNUSED_COMMAND,
 
350
   VIX_DEFINE_UNUSED_COMMAND,
365
351
   VIX_DEFINE_UNUSED_COMMAND,
366
352
   VIX_DEFINE_UNUSED_COMMAND,
367
353
   /* GET_VMX_DEVICE_STATE is needed for the initial handshake. */   
368
354
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_VMX_DEVICE_STATE,
369
355
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
370
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_NUM_TIMEMARKERS,
371
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
372
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_GET_TIMEMARKER,
373
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
374
 
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_REMOVE_TIMEMARKER,
375
 
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
 
356
   VIX_DEFINE_UNUSED_COMMAND,
 
357
   VIX_DEFINE_UNUSED_COMMAND,
 
358
   VIX_DEFINE_UNUSED_COMMAND,
376
359
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_SNAPSHOT_INFO,
377
360
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
378
361
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SNAPSHOT_SET_MRU,
427
410
 
428
411
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_QUERY_CHILDREN,
429
412
                           VIX_COMMAND_CATEGORY_PRIVILEGED),
 
413
 
430
414
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_FILES,
431
415
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
416
 
 
417
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_DIRECTORY_EX,
 
418
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
419
 
 
420
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_MOVE_GUEST_FILE_EX,
 
421
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
422
 
 
423
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_MOVE_GUEST_DIRECTORY,
 
424
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
425
 
 
426
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_TEMPORARY_FILE_EX,
 
427
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
428
 
 
429
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_CREATE_TEMPORARY_DIRECTORY,
 
430
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
431
 
 
432
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_SET_GUEST_FILE_ATTRIBUTES,
 
433
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
434
 
 
435
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_COPY_FILE_FROM_GUEST_TO_READER,
 
436
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
437
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_START_PROGRAM,
 
438
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
439
 
 
440
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_LIST_PROCESSES_EX,
 
441
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
442
 
 
443
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_READ_ENV_VARIABLES,
 
444
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
445
 
 
446
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_INITIATE_FILE_TRANSFER_FROM_GUEST,
 
447
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
448
 
 
449
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_INITIATE_FILE_TRANSFER_TO_GUEST,
 
450
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
451
 
 
452
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_ACQUIRE_CREDENTIALS,
 
453
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
454
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_RELEASE_CREDENTIALS,
 
455
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
456
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_VALIDATE_CREDENTIALS,
 
457
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
458
 
 
459
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_TERMINATE_PROCESS,
 
460
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
461
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_GUEST_FILE_EX,
 
462
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
463
   VIX_DEFINE_COMMAND_INFO(VIX_COMMAND_DELETE_GUEST_DIRECTORY_EX,
 
464
                           VIX_COMMAND_CATEGORY_ALWAYS_ALLOWED),
 
465
 
432
466
};
433
467
 
434
468
 
436
470
 
437
471
static void VixMsgInitializeObfuscationMapping(void);
438
472
 
439
 
static char *VixMsgEncodeBuffer(const uint8 *buffer,
440
 
                                size_t bufferLength,
441
 
                                Bool includeEncodingId);
442
 
 
443
 
static char *VixMsgDecodeBuffer(const char *str,
444
 
                                Bool nullTerminateResult,
445
 
                                size_t *bufferLength);
 
473
static VixError VixMsgEncodeBuffer(const uint8 *buffer,
 
474
                                   size_t bufferLength,
 
475
                                   Bool includeEncodingId,
 
476
                                   char **result);
 
477
 
 
478
static VixError VixMsgDecodeBuffer(const char *str,
 
479
                                   Bool nullTerminateResult,
 
480
                                   char **result,
 
481
                                   size_t *bufferLength);
 
482
 
 
483
static VixError VMAutomationMsgParserInit(const char *caller,
 
484
                                          unsigned int line,
 
485
                                          VMAutomationMsgParser *state,
 
486
                                          const VixMsgHeader *msg,
 
487
                                          size_t headerLength,
 
488
                                          size_t fixedLength,
 
489
                                          size_t miscDataLength,
 
490
                                          const char *packetType);
446
491
 
447
492
 
448
493
/*
584
629
 
585
630
VixCommandRequestHeader *
586
631
VixMsg_AllocRequestMsg(size_t msgHeaderAndBodyLength,    // IN
587
 
                       int opCode,                    // IN
588
 
                       uint64 cookie,                 // IN
589
 
                       int credentialType,            // IN
590
 
                       const char *userNamePassword)  // IN
 
632
                       int opCode,                       // IN
 
633
                       uint64 cookie,                    // IN
 
634
                       int credentialType,               // IN
 
635
                       const char *credential)           // IN
591
636
{
592
637
   size_t totalMessageSize;
593
638
   VixCommandRequestHeader *commandRequest = NULL;
594
 
   size_t credentialLength = 0;
595
 
   size_t namePasswordLength = 0;
 
639
   size_t providedCredentialLength = 0;
 
640
   size_t totalCredentialLength = 0;
596
641
   char *destPtr;
597
642
 
598
 
   if ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType) 
 
643
   if ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType)
599
644
      || (VIX_USER_CREDENTIAL_HOST_CONFIG_SECRET == credentialType)
600
 
      || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType)) {
 
645
      || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType)
 
646
      || (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType)
 
647
      || (VIX_USER_CREDENTIAL_SSPI == credentialType)) {
601
648
      /*
602
 
       * Both of these are optional.
 
649
       * All of these are optional.
603
650
       */
604
 
      if (NULL != userNamePassword) {
605
 
         namePasswordLength = strlen(userNamePassword);
606
 
         credentialLength += namePasswordLength;
 
651
      if (NULL != credential) {
 
652
         providedCredentialLength = strlen(credential);
 
653
         totalCredentialLength += providedCredentialLength;
607
654
      }
608
655
      /*
609
656
       * Add 1 to each string to include '\0' for the end of the string.
610
657
       */
611
 
      credentialLength += 1;
 
658
      totalCredentialLength += 1;
612
659
   } else {
613
 
      credentialLength = 0;
 
660
      totalCredentialLength = 0;
614
661
   }
615
662
 
616
 
   totalMessageSize = msgHeaderAndBodyLength + credentialLength;
 
663
   totalMessageSize = msgHeaderAndBodyLength + totalCredentialLength;
617
664
   if (totalMessageSize > VIX_COMMAND_MAX_REQUEST_SIZE) {
618
665
      /*
619
666
       * We don't want to allocate any requests larger than
631
678
   commandRequest->commonHeader.magic = VIX_COMMAND_MAGIC_WORD;
632
679
   commandRequest->commonHeader.messageVersion = VIX_COMMAND_MESSAGE_VERSION;
633
680
   commandRequest->commonHeader.totalMessageLength =
634
 
      msgHeaderAndBodyLength + credentialLength;
 
681
      msgHeaderAndBodyLength + totalCredentialLength;
635
682
   commandRequest->commonHeader.headerLength = sizeof(VixCommandRequestHeader);
636
683
   commandRequest->commonHeader.bodyLength = msgHeaderAndBodyLength -
637
684
      sizeof(VixCommandRequestHeader);
638
 
   commandRequest->commonHeader.credentialLength = credentialLength;
 
685
   commandRequest->commonHeader.credentialLength = totalCredentialLength;
639
686
   commandRequest->commonHeader.commonFlags = VIX_COMMAND_REQUEST;
640
687
 
641
688
   commandRequest->opCode = opCode;
647
694
 
648
695
   if ((VIX_USER_CREDENTIAL_NAME_PASSWORD == credentialType)
649
696
         || (VIX_USER_CREDENTIAL_HOST_CONFIG_SECRET == credentialType)
650
 
         || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType)) {
 
697
         || (VIX_USER_CREDENTIAL_HOST_CONFIG_HASHED_SECRET == credentialType)
 
698
         || (VIX_USER_CREDENTIAL_TICKETED_SESSION == credentialType)
 
699
         || (VIX_USER_CREDENTIAL_SSPI == credentialType)) {
651
700
      destPtr = (char *) commandRequest;
652
701
      destPtr += commandRequest->commonHeader.headerLength;
653
702
      destPtr += commandRequest->commonHeader.bodyLength;
654
 
      if (NULL != userNamePassword) {
655
 
         Str_Strcpy(destPtr, userNamePassword, namePasswordLength + 1);
656
 
         destPtr += namePasswordLength;
 
703
      if (NULL != credential) {
 
704
         Str_Strcpy(destPtr, credential, providedCredentialLength + 1);
 
705
         destPtr += providedCredentialLength;
657
706
      }
658
707
      *(destPtr++) = 0;
659
708
   }
984
1033
 *-----------------------------------------------------------------------------
985
1034
 */
986
1035
 
987
 
char *
 
1036
VixError
988
1037
VixMsg_ObfuscateNamePassword(const char *userName,      // IN
989
 
                             const char *password)      // IN
 
1038
                             const char *password,      // IN
 
1039
                             char **result)             // OUT
990
1040
{
 
1041
   VixError err = VIX_OK;
991
1042
   char *packedBuffer = NULL;
992
1043
   char *resultString = NULL;
993
1044
   char *destPtr;
1005
1056
    * Leave space for null terminating characters.
1006
1057
    */
1007
1058
   packedBufferLength = nameLength + 1 + passwordLength + 1;
1008
 
   packedBuffer = Util_SafeMalloc(packedBufferLength);
 
1059
   packedBuffer = VixMsg_MallocClientData(packedBufferLength);
 
1060
   if (packedBuffer == NULL) {
 
1061
      err = VIX_E_OUT_OF_MEMORY;
 
1062
      goto abort;
 
1063
   }
 
1064
 
1009
1065
   destPtr = packedBuffer;
1010
1066
   if (NULL != userName) {
1011
1067
      Str_Strcpy(destPtr, userName, nameLength + 1);
1018
1074
   }
1019
1075
   *(destPtr++) = 0;
1020
1076
 
1021
 
   resultString = VixMsgEncodeBuffer(packedBuffer, packedBufferLength, FALSE);
 
1077
   err = VixMsgEncodeBuffer(packedBuffer, packedBufferLength, FALSE,
 
1078
                            &resultString);
 
1079
   if (err != VIX_OK) {
 
1080
      goto abort;
 
1081
   }
1022
1082
 
 
1083
abort:
1023
1084
   Util_ZeroFree(packedBuffer, packedBufferLength);
1024
1085
 
1025
 
   return(resultString);
 
1086
   if (err == VIX_OK) {
 
1087
      *result = resultString;
 
1088
   }
 
1089
 
 
1090
   return err;
1026
1091
} // VixMsg_ObfuscateNamePassword
1027
1092
 
1028
1093
 
1035
1100
 *      See the notes for that procedure.
1036
1101
 *
1037
1102
 * Results:
1038
 
 *      Bool. TRUE on success, FALSE otherwise.
 
1103
 *      VixError. VIX_OK if successful.
1039
1104
 *
1040
1105
 * Side effects:
1041
1106
 *      None.
1043
1108
 *-----------------------------------------------------------------------------
1044
1109
 */
1045
1110
 
1046
 
Bool
 
1111
VixError
1047
1112
VixMsg_DeObfuscateNamePassword(const char *packagedName,   // IN
1048
1113
                               char **userNameResult,      // OUT
1049
1114
                               char **passwordResult)      // OUT
1050
1115
{
1051
 
   Bool success = FALSE;
 
1116
   VixError err;
1052
1117
   char *packedString = NULL;
1053
1118
   char *srcPtr;
1054
1119
   size_t packedStringLength;
 
1120
   char *userName = NULL;
 
1121
   char *passwd = NULL;
1055
1122
 
1056
 
   packedString = VixMsgDecodeBuffer(packagedName, FALSE, &packedStringLength);
1057
 
   if (NULL == packedString) {
 
1123
   err = VixMsgDecodeBuffer(packagedName, FALSE,
 
1124
                            &packedString, &packedStringLength);
 
1125
   if (err != VIX_OK) {
1058
1126
      goto abort;
1059
1127
   }
1060
1128
 
1061
1129
   srcPtr = packedString;
1062
1130
   if (NULL != userNameResult) {
1063
 
      *userNameResult = Util_SafeStrdup(srcPtr);
 
1131
      Bool allocateFailed;
 
1132
      userName = VixMsg_StrdupClientData(srcPtr, &allocateFailed);
 
1133
      if (allocateFailed) {
 
1134
         err = VIX_E_OUT_OF_MEMORY;
 
1135
         goto abort;
 
1136
      }
1064
1137
   }
1065
1138
   srcPtr = srcPtr + strlen(srcPtr);
1066
1139
   srcPtr++;
1067
1140
   if (NULL != passwordResult) {
1068
 
      *passwordResult = Util_SafeStrdup(srcPtr);
 
1141
      Bool allocateFailed;
 
1142
      passwd = VixMsg_StrdupClientData(srcPtr, &allocateFailed);
 
1143
      if (allocateFailed) {
 
1144
         err = VIX_E_OUT_OF_MEMORY;
 
1145
         goto abort;
 
1146
      }
1069
1147
   }
1070
 
   success = TRUE;
 
1148
 
 
1149
   *userNameResult = userName;
 
1150
   userName = NULL;
 
1151
   *passwordResult = passwd;
 
1152
   passwd = NULL;
1071
1153
 
1072
1154
abort:
1073
1155
   Util_ZeroFree(packedString, packedStringLength);
 
1156
   Util_ZeroFreeString(userName);
 
1157
   Util_ZeroFreeString(passwd);
1074
1158
 
1075
 
   return(success);
 
1159
   return err;
1076
1160
} // VixMsg_DeObfuscateNamePassword
1077
1161
 
1078
1162
 
1095
1179
 *-----------------------------------------------------------------------------
1096
1180
 */
1097
1181
 
1098
 
char *
1099
 
VixMsg_EncodeString(const char *str)  // IN
 
1182
VixError
 
1183
VixMsg_EncodeString(const char *str,  // IN
 
1184
                    char **result)    // OUT
1100
1185
{
1101
1186
   if (NULL == str) {
1102
1187
      str = "";
1103
1188
   }
1104
1189
 
1105
 
   return VixMsgEncodeBuffer(str, strlen(str), TRUE);
 
1190
   return VixMsgEncodeBuffer(str, strlen(str), TRUE, result);
1106
1191
} // VixMsg_EncodeString
1107
1192
 
1108
1193
 
1125
1210
 *-----------------------------------------------------------------------------
1126
1211
 */
1127
1212
 
1128
 
char *
 
1213
VixError
1129
1214
VixMsgEncodeBuffer(const uint8 *buffer,     // IN
1130
1215
                   size_t bufferLength,     // IN
1131
 
                   Bool includeEncodingId)  // IN: Add 'a' (ASCII) at start of output
 
1216
                   Bool includeEncodingId,  // IN: Add 'a' (ASCII) at start of output
 
1217
                   char ** result)          // OUT
1132
1218
{
 
1219
   VixError err = VIX_OK;
1133
1220
   char *base64String = NULL;
1134
1221
   char *resultString = NULL;
1135
1222
   size_t resultBufferLength = 0;
1140
1227
   
1141
1228
   base64Length = Base64_EncodedLength((uint8 const *) buffer,
1142
1229
                                       bufferLength);
1143
 
   base64String = Util_SafeMalloc(base64Length);
 
1230
   base64String = VixMsg_MallocClientData(base64Length);
 
1231
   if (base64String == NULL) {
 
1232
      err = VIX_E_OUT_OF_MEMORY;
 
1233
      goto abort;
 
1234
   }
 
1235
 
1144
1236
   if (!(Base64_Encode((uint8 const *) buffer,
1145
1237
                       bufferLength,
1146
1238
                       base64String, 
1147
1239
                       base64Length,
1148
1240
                       &base64Length))) {
 
1241
      err = VIX_E_FAIL;
1149
1242
      goto abort;
1150
1243
   }
1151
1244
 
1159
1252
      resultBufferLength++;
1160
1253
   }
1161
1254
 
1162
 
   resultString = Util_SafeMalloc(resultBufferLength + 1);
 
1255
   resultString = VixMsg_MallocClientData(resultBufferLength + 1);
 
1256
   if (resultString == NULL) {
 
1257
      err = VIX_E_OUT_OF_MEMORY;
 
1258
      goto abort;
 
1259
   }
 
1260
 
1163
1261
   destPtr = resultString;
1164
1262
   srcPtr = base64String;
1165
1263
   endSrcPtr = base64String + base64Length;
1193
1291
abort:
1194
1292
   free(base64String);
1195
1293
 
1196
 
   return resultString;
 
1294
   if (err == VIX_OK) {
 
1295
      *result = resultString;
 
1296
   }
 
1297
 
 
1298
   return err;
1197
1299
} // VixMsgEncodeBuffer
1198
1300
 
1199
1301
/*
1205
1307
 *       See the notes for that procedure.
1206
1308
 *
1207
1309
 * Results:
1208
 
 *      A pointer to the decoded string, or NULL on failure.
 
1310
 *      VixError. VIX_OK if successful.
1209
1311
 *
1210
1312
 * Side effects:
1211
1313
 *      None.
1213
1315
 *-----------------------------------------------------------------------------
1214
1316
 */
1215
1317
 
1216
 
char *
1217
 
VixMsg_DecodeString(const char *str)   // IN
 
1318
VixError
 
1319
VixMsg_DecodeString(const char *str,   // IN
 
1320
                    char **result)     // OUT
1218
1321
{
1219
1322
   /*
1220
1323
    * Check the character set. 
1221
1324
    *   'a' means ASCII.
1222
1325
    */
1223
1326
   if ((NULL == str) || ('a' != *str)) {
1224
 
      return(NULL);
 
1327
      *result = NULL;
 
1328
      return VIX_E_INVALID_ARG;
1225
1329
   }
1226
1330
 
1227
 
   return VixMsgDecodeBuffer(str + 1, TRUE, NULL);
 
1331
   return VixMsgDecodeBuffer(str + 1, TRUE, result, NULL);
1228
1332
} // VixMsg_DecodeString
1229
1333
 
1230
1334
 
1237
1341
 *      See the notes for that procedure.
1238
1342
 *
1239
1343
 * Results:
1240
 
 *      A pointer to the decoded string, or NULL on failure.
 
1344
 *      VixError. VIX_OK if successful.
1241
1345
 *
1242
1346
 * Side effects:
1243
1347
 *      None.
1245
1349
 *-----------------------------------------------------------------------------
1246
1350
 */
1247
1351
 
1248
 
char *
 
1352
VixError
1249
1353
VixMsgDecodeBuffer(const char *str,           // IN
1250
1354
                   Bool nullTerminateResult,  // OUT
 
1355
                   char **result,             // OUT
1251
1356
                   size_t *bufferLength)      // OUT: Optional
1252
1357
{
 
1358
   VixError err = VIX_OK;
1253
1359
   char *base64String = NULL;
1254
1360
   char *resultStr = NULL;
1255
1361
   char *srcPtr;
1256
1362
   char *destPtr;
1257
1363
   size_t resultStrAllocatedLength;
1258
1364
   size_t resultStrLogicalLength;
 
1365
   Bool allocateFailed;
1259
1366
 
1260
1367
   if (NULL != bufferLength) {
1261
1368
      *bufferLength = 0;
1266
1373
    * Do this in a private copy because we will change the string in place.
1267
1374
    */
1268
1375
   VixMsgInitializeObfuscationMapping();
1269
 
   base64String = Util_SafeStrdup(str);
 
1376
   base64String = VixMsg_StrdupClientData(str, &allocateFailed);
 
1377
   if (allocateFailed) {
 
1378
      err = VIX_E_OUT_OF_MEMORY;
 
1379
      goto abort;
 
1380
   }
1270
1381
   destPtr = base64String;
1271
1382
   srcPtr = base64String;
1272
1383
 
1322
1433
abort:
1323
1434
   free(base64String);
1324
1435
 
1325
 
   return(resultStr);
 
1436
   if (err == VIX_OK) {
 
1437
      *result = resultStr;
 
1438
   }
 
1439
 
 
1440
   return err;
1326
1441
} // VixMsgDecodeBuffer
1327
1442
 
1328
1443
 
1626
1741
 
1627
1742
      err = VixPropertyList_Deserialize(propertyList,
1628
1743
                                        serializedBuffer,
1629
 
                                        request->propertyListSize);
 
1744
                                        request->propertyListSize,
 
1745
                                        VIX_PROPERTY_LIST_BAD_ENCODING_ERROR);
1630
1746
      if (VIX_OK != err) {
1631
1747
         goto abort;
1632
1748
      }
1641
1757
} // VixMsg_ParseGenericRequestMsg
1642
1758
 
1643
1759
 
 
1760
 
 
1761
/*
 
1762
 *-----------------------------------------------------------------------------
 
1763
 *
 
1764
 * VixMsg_ParseSimpleResponseWithString --
 
1765
 *
 
1766
 *      Takes a response packet that consists of a VixCommandResponseHeader
 
1767
 *      followed by a string containing the response data, validates
 
1768
 *      the packet, and then passes out a pointer to that string.
 
1769
 *
 
1770
 * Results:
 
1771
 *      VixError
 
1772
 *
 
1773
 * Side effects:
 
1774
 *      None
 
1775
 *
 
1776
 *-----------------------------------------------------------------------------
 
1777
 */
 
1778
 
 
1779
VixError
 
1780
VixMsg_ParseSimpleResponseWithString(const VixCommandResponseHeader *response,  // IN
 
1781
                                     const char **result)                       // OUT
 
1782
{
 
1783
   VixError err;
 
1784
   VMAutomationMsgParser parser;
 
1785
 
 
1786
   err = VMAutomationMsgParserInitResponse(&parser, response, sizeof *response);
 
1787
   if (VIX_OK != err) {
 
1788
      goto abort;
 
1789
   }
 
1790
 
 
1791
   err = VMAutomationMsgParserGetOptionalString(&parser,
 
1792
                                                response->commonHeader.bodyLength,
 
1793
                                                result);
 
1794
 
 
1795
abort:
 
1796
   return err;
 
1797
}
 
1798
 
 
1799
 
1644
1800
/*
1645
1801
 *-----------------------------------------------------------------------------
1646
1802
 *
1731
1887
abort:
1732
1888
   return newString;
1733
1889
} // VixMsg_StrdupClientData
 
1890
 
 
1891
 
 
1892
/*
 
1893
 *-----------------------------------------------------------------------------
 
1894
 *
 
1895
 * __VMAutomationValidateString --
 
1896
 *
 
1897
 *      Verifies that string at specified address is NUL terminated within
 
1898
 *      specified number of bytes, and is valid UTF-8.
 
1899
 *
 
1900
 * Results:
 
1901
 *      VixError.  VIX_OK on success.  Some other VIX_* code if message is malformed.
 
1902
 *
 
1903
 * Side effects:
 
1904
 *      None.
 
1905
 *
 
1906
 *-----------------------------------------------------------------------------
 
1907
 */
 
1908
 
 
1909
static VixError
 
1910
__VMAutomationValidateString(const char  *caller,              // IN
 
1911
                             unsigned int line,                // IN
 
1912
                             const char  *buffer,              // IN
 
1913
                             size_t       available)           // IN
 
1914
{
 
1915
   size_t stringLength;
 
1916
 
 
1917
   /*
 
1918
    * NUL terminated string needs at least one byte - NUL one.
 
1919
    */
 
1920
   if (available < 1) {
 
1921
      Log("%s(%u): Message body too short to contain string.\n", caller, line);
 
1922
      return VIX_E_INVALID_MESSAGE_BODY;
 
1923
   }
 
1924
 
 
1925
   /*
 
1926
    * Reject message if there is no NUL before request end.  There must
 
1927
    * be one...
 
1928
    */
 
1929
 
 
1930
   stringLength = Str_Strlen(buffer, available);
 
1931
   if (stringLength >= available) {
 
1932
      Log("%s(%u): Variable string is not NUL terminated "
 
1933
          "before message end.\n", caller, line);
 
1934
      return VIX_E_INVALID_MESSAGE_BODY;
 
1935
   }
 
1936
 
 
1937
   /*
 
1938
    * If string is shorter than expected, complain.  Maybe it is too strict,
 
1939
    * but clients seems to not send malformed messages, so keep doing this.
 
1940
    */
 
1941
 
 
1942
   if (stringLength + 1 != available) {
 
1943
      Log("%s(%u): Retrieved fixed string \"%s\" with "
 
1944
          "trailing garbage.\n", caller, line, buffer);
 
1945
      return VIX_E_INVALID_MESSAGE_BODY;
 
1946
   }
 
1947
 
 
1948
   /*
 
1949
    * If string is not UTF-8, reject it.  We do not want to pass non-UTF-8
 
1950
    * strings through vmx bowels - they could hit some ASSERT somewhere...
 
1951
    */
 
1952
 
 
1953
   if (!Unicode_IsBufferValid(buffer, stringLength, STRING_ENCODING_UTF8)) {
 
1954
      Log("%s(%u): Variable string is not an UTF8 string.\n", caller, line);
 
1955
      return VIX_E_INVALID_UTF8_STRING;
 
1956
   }
 
1957
 
 
1958
   return VIX_OK;
 
1959
}
 
1960
 
 
1961
 
 
1962
/*
 
1963
 *-----------------------------------------------------------------------------
 
1964
 *
 
1965
 * __VMAutomationValidateStringInBuffer --
 
1966
 *
 
1967
 *      Verifies that string at specified address is NUL terminated within
 
1968
 *      specified number of bytes, and is valid UTF-8.
 
1969
 *      String does not have to occupy the entire buffer.
 
1970
 *
 
1971
 * Results:
 
1972
 *      VixError.  VIX_OK on success.
 
1973
 *      Some other VIX_* code if message is malformed.
 
1974
 *
 
1975
 * Side effects:
 
1976
 *      None.
 
1977
 *
 
1978
 *-----------------------------------------------------------------------------
 
1979
 */
 
1980
 
 
1981
static VixError
 
1982
__VMAutomationValidateStringInBuffer(const char  *caller,              // IN
 
1983
                                     unsigned int line,                // IN
 
1984
                                     const char  *buffer,              // IN
 
1985
                                     size_t       available,           // IN
 
1986
                                     size_t      *strLen)              // IN
 
1987
{
 
1988
   size_t stringLength;
 
1989
 
 
1990
   /*
 
1991
    * NUL terminated string needs at least one byte - NUL one.
 
1992
    */
 
1993
   if (available < 1) {
 
1994
      Log("%s(%u): Message body too short to contain string.\n", caller, line);
 
1995
      return VIX_E_INVALID_MESSAGE_BODY;
 
1996
   }
 
1997
 
 
1998
   /*
 
1999
    * Reject message if there is no NUL before request end.  There must
 
2000
    * be one...
 
2001
    */
 
2002
 
 
2003
   stringLength = Str_Strlen(buffer, available);
 
2004
   *strLen = stringLength;
 
2005
 
 
2006
   if (stringLength >= available) {
 
2007
      Log("%s(%u): Variable string is not NUL terminated "
 
2008
          "before message end.\n", caller, line);
 
2009
      return VIX_E_INVALID_MESSAGE_BODY;
 
2010
   }
 
2011
 
 
2012
   /*
 
2013
    * If string is not UTF-8, reject it.  We do not want to pass non-UTF-8
 
2014
    * strings through vmx bowels - they could hit some ASSERT somewhere...
 
2015
    */
 
2016
 
 
2017
   if (!Unicode_IsBufferValid(buffer, stringLength, STRING_ENCODING_UTF8)) {
 
2018
      Log("%s(%u): Variable string is not an UTF8 string.\n", caller, line);
 
2019
      return VIX_E_INVALID_UTF8_STRING;
 
2020
   }
 
2021
 
 
2022
   return VIX_OK;
 
2023
}
 
2024
 
 
2025
 
 
2026
/*
 
2027
 *-----------------------------------------------------------------------------
 
2028
 *
 
2029
 * __VMAutomationMsgParserInitRequest --
 
2030
 * VMAutomationMsgParserInitRequest --
 
2031
 *
 
2032
 *      Initializes request parser, and performs basic message validation
 
2033
 *      not performed elsewhere.
 
2034
 *
 
2035
 * Results:
 
2036
 *      VixError.  VIX_OK on success.  Some other VIX_* code if message is malformed.
 
2037
 *
 
2038
 * Side effects:
 
2039
 *      None.
 
2040
 *
 
2041
 *-----------------------------------------------------------------------------
 
2042
 */
 
2043
 
 
2044
VixError
 
2045
__VMAutomationMsgParserInitRequest(const char *caller,                  // IN
 
2046
                                   unsigned int line,                   // IN
 
2047
                                   VMAutomationMsgParser *state,        // OUT (opt)
 
2048
                                   const VixCommandRequestHeader *msg,  // IN
 
2049
                                   size_t fixedLength)                  // IN
 
2050
{
 
2051
   size_t miscDataLength = 0;
 
2052
 
 
2053
   /*
 
2054
    * If the VM is encrypted, there is additional data factored into
 
2055
    * the total message size that needs to be accounted for.
 
2056
    */
 
2057
 
 
2058
   if (VIX_REQUESTMSG_INCLUDES_AUTH_DATA_V1 & msg->requestFlags) {
 
2059
      miscDataLength = sizeof(VixMsgAuthDataV1);
 
2060
   } else {
 
2061
      miscDataLength = 0;
 
2062
   }
 
2063
 
 
2064
   return VMAutomationMsgParserInit(caller, line, state, &msg->commonHeader,
 
2065
                                    sizeof *msg, fixedLength, miscDataLength, "request");
 
2066
}
 
2067
 
 
2068
 
 
2069
/*
 
2070
 *-----------------------------------------------------------------------------
 
2071
 *
 
2072
 * __VMAutomationMsgParserInitResponse --
 
2073
 * VMAutomationMsgParserInitResponse --
 
2074
 *
 
2075
 *      Initializes response parser, and performs basic message validation
 
2076
 *      not performed elsewhere.
 
2077
 *
 
2078
 * Results:
 
2079
 *      VixError.  VIX_OK on success.  Some other VIX_* code if message is malformed.
 
2080
 *
 
2081
 * Side effects:
 
2082
 *      None.
 
2083
 *
 
2084
 *-----------------------------------------------------------------------------
 
2085
 */
 
2086
 
 
2087
VixError
 
2088
__VMAutomationMsgParserInitResponse(const char *caller,                  // IN
 
2089
                                    unsigned int line,                   // IN
 
2090
                                    VMAutomationMsgParser *state,        // OUT (opt)
 
2091
                                    const VixCommandResponseHeader *msg, // IN
 
2092
                                    size_t fixedLength)                  // IN
 
2093
{
 
2094
   return VMAutomationMsgParserInit(caller, line, state, &msg->commonHeader,
 
2095
                                    sizeof *msg, fixedLength, 0, "response");
 
2096
}
 
2097
 
 
2098
 
 
2099
/*
 
2100
 *-----------------------------------------------------------------------------
 
2101
 *
 
2102
 * VMAutomationMsgParserInit --
 
2103
 *
 
2104
 *      Initializes message parser, and performs basic message validation
 
2105
 *      not performed elsewhere.
 
2106
 *
 
2107
 * Results:
 
2108
 *      VixError. VIX_OK on success. Some other VIX_* code if message is malformed.
 
2109
 *
 
2110
 * Side effects:
 
2111
 *      None
 
2112
 *
 
2113
 *-----------------------------------------------------------------------------
 
2114
 */
 
2115
 
 
2116
static VixError
 
2117
VMAutomationMsgParserInit(const char *caller,              // IN
 
2118
                          unsigned int line,               // IN
 
2119
                          VMAutomationMsgParser *state,    // OUT (opt)
 
2120
                          const VixMsgHeader *msg,         // IN
 
2121
                          size_t headerLength,             // IN
 
2122
                          size_t fixedLength,              // IN
 
2123
                          size_t miscDataLength,           // IN
 
2124
                          const char *packetType)          // IN
 
2125
{
 
2126
   uint32 headerAndBodyLength;
 
2127
   // use int64 to prevent overflow
 
2128
   int64 computedTotalLength = (int64)msg->headerLength +
 
2129
      (int64)msg->bodyLength + (int64)msg->credentialLength +
 
2130
      (int64)miscDataLength;
 
2131
 
 
2132
   int64 extBodySize = (int64)msg->headerLength + (int64)msg->bodyLength -
 
2133
      (int64)fixedLength;
 
2134
 
 
2135
   if (computedTotalLength != (int64)msg->totalMessageLength) {
 
2136
      Log("%s:%d, header information mismatch.\n", __FILE__, __LINE__);
 
2137
      return VIX_E_INVALID_MESSAGE_HEADER;
 
2138
   }
 
2139
 
 
2140
   if (extBodySize < 0) {
 
2141
      Log("%s:%d, %s too short.\n", __FILE__, __LINE__, packetType);
 
2142
      return VIX_E_INVALID_MESSAGE_HEADER;
 
2143
   }
 
2144
 
 
2145
   /*
 
2146
    * Protocol allows for headerLength expansion, but predefined structures
 
2147
    * do not anticipate that even a bit. So give up if header length is
 
2148
    * incompatible with our structures.
 
2149
    */
 
2150
 
 
2151
   if (msg->headerLength != headerLength) {
 
2152
      Log("%s(%u): %s header length %u is not supported "
 
2153
          "(%"FMTSZ"u is required).\n",
 
2154
          caller, line, packetType, msg->headerLength, headerLength);
 
2155
      return VIX_E_INVALID_MESSAGE_HEADER;
 
2156
   }
 
2157
 
 
2158
   /*
 
2159
    * Message looks reasonable.  Skip over fixed part.
 
2160
    */
 
2161
 
 
2162
   headerAndBodyLength = msg->headerLength + msg->bodyLength;
 
2163
 
 
2164
   if (state) {
 
2165
      state->currentPtr = (const char *)msg + fixedLength;
 
2166
      state->endPtr = (const char *)msg + headerAndBodyLength;
 
2167
   }
 
2168
   return VIX_OK;
 
2169
}
 
2170
 
 
2171
 
 
2172
/*
 
2173
 *-----------------------------------------------------------------------------
 
2174
 *
 
2175
 * VMAutomation_VerifyRequestLength --
 
2176
 *
 
2177
 *      Ensures that request contains at least fixedLength bytes in
 
2178
 *      header and body.
 
2179
 *
 
2180
 * Results:
 
2181
 *      VixError.  VIX_OK on success.  Some other VIX_* code if message is malformed.
 
2182
 *
 
2183
 * Side effects:
 
2184
 *      None.
 
2185
 *
 
2186
 *-----------------------------------------------------------------------------
 
2187
 */
 
2188
 
 
2189
VixError
 
2190
VMAutomation_VerifyRequestLength(const VixCommandRequestHeader *request, // IN
 
2191
                                 size_t fixedLength)                     // IN
 
2192
{
 
2193
   return VMAutomationMsgParserInitRequest(NULL, request, fixedLength);
 
2194
}
 
2195
 
 
2196
 
 
2197
/*
 
2198
 *-----------------------------------------------------------------------------
 
2199
 *
 
2200
 * VMAutomationMsgParserGetRemainingData --
 
2201
 *
 
2202
 *      Fetches all data remaining in the request.
 
2203
 *
 
2204
 * Results:
 
2205
 *      Pointer to the data.
 
2206
 *
 
2207
 * Side effects:
 
2208
 *      None.
 
2209
 *
 
2210
 *-----------------------------------------------------------------------------
 
2211
 */
 
2212
 
 
2213
const void *
 
2214
VMAutomationMsgParserGetRemainingData(VMAutomationMsgParser *state,   // IN/OUT
 
2215
                                      size_t *length)                 // OUT
 
2216
{
 
2217
   const void *data;
 
2218
 
 
2219
   *length = state->endPtr - state->currentPtr;
 
2220
   data = state->currentPtr;
 
2221
   state->currentPtr = state->endPtr;
 
2222
 
 
2223
   return data;
 
2224
}
 
2225
 
 
2226
 
 
2227
/*
 
2228
 *-----------------------------------------------------------------------------
 
2229
 *
 
2230
 * VMAutomationMsgParserGetData --
 
2231
 * __VMAutomationMsgParserGetData --
 
2232
 *
 
2233
 *      Fetches specified number of bytes.
 
2234
 *
 
2235
 * Results:
 
2236
 *      VixError.  VIX_OK on success.  Some other VIX_* code if message is malformed.
 
2237
 *
 
2238
 * Side effects:
 
2239
 *      None.
 
2240
 *
 
2241
 *-----------------------------------------------------------------------------
 
2242
 */
 
2243
 
 
2244
VixError
 
2245
__VMAutomationMsgParserGetData(const char *caller,             // IN
 
2246
                               unsigned int line,              // IN
 
2247
                               VMAutomationMsgParser *state,   // IN/OUT
 
2248
                               size_t length,                  // IN
 
2249
                               const char **result)            // OUT (opt)
 
2250
{
 
2251
   size_t available;
 
2252
 
 
2253
   available = state->endPtr - state->currentPtr;
 
2254
 
 
2255
   /* If message is too short, return an error. */
 
2256
   if (available < length) {
 
2257
      Log("%s(%u): Message has only %"FMTSZ"u bytes available when "
 
2258
          "looking for %"FMTSZ"u bytes od data.\n",
 
2259
          caller, line, available, length);
 
2260
      return VIX_E_INVALID_MESSAGE_BODY;
 
2261
   }
 
2262
 
 
2263
   if (result) {
 
2264
      *result = state->currentPtr;
 
2265
   }
 
2266
   state->currentPtr += length;
 
2267
   return VIX_OK;
 
2268
}
 
2269
 
 
2270
 
 
2271
/*
 
2272
 *-----------------------------------------------------------------------------
 
2273
 *
 
2274
 * VMAutomationMsgParserGetOptionalString --
 
2275
 * __VMAutomationMsgParserGetOptionalString --
 
2276
 *
 
2277
 *      Fetches string of specified length from the request.  Length includes
 
2278
 *      terminating NUL byte, which must be present.  Length of zero results
 
2279
 *      in NULL being returned.
 
2280
 *
 
2281
 * Results:
 
2282
 *      VixError.  VIX_OK on success.  Some other VIX_* code if message is malformed.
 
2283
 *
 
2284
 * Side effects:
 
2285
 *      None.
 
2286
 *
 
2287
 *-----------------------------------------------------------------------------
 
2288
 */
 
2289
 
 
2290
VixError
 
2291
__VMAutomationMsgParserGetOptionalString(const char *caller,           // IN
 
2292
                                         unsigned int line,            // IN
 
2293
                                         VMAutomationMsgParser *state, // IN/OUT
 
2294
                                         size_t length,                // IN
 
2295
                                         const char **result)          // OUT
 
2296
{
 
2297
   if (length) {
 
2298
      VixError err;
 
2299
      const char *string;
 
2300
 
 
2301
      err = __VMAutomationMsgParserGetData(caller, line, state, length,
 
2302
                                           &string);
 
2303
      if (VIX_OK != err) {
 
2304
         return err;
 
2305
      }
 
2306
      err = __VMAutomationValidateString(caller, line, string, length);
 
2307
      if (VIX_OK != err) {
 
2308
         return err;
 
2309
      }
 
2310
      *result = string;
 
2311
   } else {
 
2312
      *result = NULL;
 
2313
   }
 
2314
   return VIX_OK;
 
2315
}
 
2316
 
 
2317
 
 
2318
/*
 
2319
 *-----------------------------------------------------------------------------
 
2320
 *
 
2321
 * VMAutomationMsgParserGetOptionalStrings --
 
2322
 * __VMAutomationMsgParserGetOptionalStrings --
 
2323
 *
 
2324
 *      Fetches an array of strings from the request.  Length includes the
 
2325
 *      terminating NUL byte of each string.
 
2326
 *
 
2327
 * Results:
 
2328
 *      VixError.  VIX_OK on success.
 
2329
 *      Some other VIX_* code if message is malformed.
 
2330
 *
 
2331
 * Side effects:
 
2332
 *      None.
 
2333
 *
 
2334
 *-----------------------------------------------------------------------------
 
2335
 */
 
2336
 
 
2337
VixError
 
2338
__VMAutomationMsgParserGetOptionalStrings(const char *caller,   // IN
 
2339
                                          unsigned int line,    // IN
 
2340
                                VMAutomationMsgParser *state,   // IN/OUT
 
2341
                                          uint32 count,         // IN
 
2342
                                          size_t length,        // IN
 
2343
                                          const char **result) // OUT
 
2344
{
 
2345
   VixError err = VIX_OK;
 
2346
   const char *buffer;
 
2347
   const char *theResult;
 
2348
   int i;
 
2349
   size_t strLen;
 
2350
 
 
2351
   if (0 == count) {
 
2352
      *result = NULL;
 
2353
      goto abort;
 
2354
   }
 
2355
 
 
2356
   err = __VMAutomationMsgParserGetData(caller, line, state, length,
 
2357
                                        &buffer);
 
2358
   if (VIX_OK != err) {
 
2359
      return err;
 
2360
   }
 
2361
 
 
2362
   theResult = buffer;
 
2363
 
 
2364
   for (i = 0; i < count; ++i) {
 
2365
      err = __VMAutomationValidateStringInBuffer(caller, line,
 
2366
                                                 buffer, length, &strLen);
 
2367
      if (VIX_OK != err) {
 
2368
         return err;
 
2369
      }
 
2370
      ASSERT(strLen < length);
 
2371
      buffer += (strLen + 1);
 
2372
      length -= (strLen + 1);
 
2373
   }
 
2374
 
 
2375
   /*
 
2376
    * If string is shorter than expected, complain.  Maybe it is too strict,
 
2377
    * but clients seems to not send malformed messages, so keep doing this.
 
2378
    */
 
2379
 
 
2380
   if (length != 0) {
 
2381
      Log("%s(%u): Retrieved an array of string with trailing garbage.\n",
 
2382
          caller, line);
 
2383
      return VIX_E_INVALID_MESSAGE_BODY;
 
2384
   }
 
2385
 
 
2386
   *result = theResult;
 
2387
 
 
2388
abort:
 
2389
 
 
2390
   return err;
 
2391
}
 
2392
 
 
2393
 
 
2394
/*
 
2395
 *-----------------------------------------------------------------------------
 
2396
 *
 
2397
 * VMAutomationMsgParserGetString --
 
2398
 * __VMAutomationMsgParserGetString --
 
2399
 *
 
2400
 *      Fetches string of specified length from the request.  Length of
 
2401
 *      string is specified in number of usable characters: function consumes
 
2402
 *      length + 1 bytes from request, and first length bytes must be non-NUL,
 
2403
 *      while length+1st byte must be NUL.
 
2404
 *
 
2405
 * Results:
 
2406
 *      VixError.  VIX_OK on success.  Some other VIX_* code if message is malformed.
 
2407
 *
 
2408
 * Side effects:
 
2409
 *      None.
 
2410
 *
 
2411
 *-----------------------------------------------------------------------------
 
2412
 */
 
2413
 
 
2414
VixError
 
2415
__VMAutomationMsgParserGetString(const char *caller,            // IN
 
2416
                                 unsigned int line,             // IN
 
2417
                                 VMAutomationMsgParser *state,  // IN/OUT
 
2418
                                 size_t length,                 // IN
 
2419
                                 const char **result)           // OUT
 
2420
{
 
2421
   VixError err;
 
2422
   const char *string;
 
2423
 
 
2424
   length++;
 
2425
   if (!length) {
 
2426
      Log("%s(%u): String is too long.\n", caller, line);
 
2427
      return VIX_E_INVALID_ARG;
 
2428
   }
 
2429
   err = __VMAutomationMsgParserGetData(caller, line, state, length,
 
2430
                                        &string);
 
2431
   if (VIX_OK != err) {
 
2432
      return err;
 
2433
   }
 
2434
   err = __VMAutomationValidateString(caller, line, string, length);
 
2435
   if (VIX_OK != err) {
 
2436
      return err;
 
2437
   }
 
2438
 
 
2439
   *result = string;
 
2440
   return VIX_OK;
 
2441
}
 
2442
 
 
2443
 
 
2444
/*
 
2445
 *-----------------------------------------------------------------------------
 
2446
 *
 
2447
 * VMAutomationMsgParserGetPropertyList --
 
2448
 * __VMAutomationMsgParserGetPropertyList --
 
2449
 *
 
2450
 *      Fetches specified number of bytes.
 
2451
 *
 
2452
 * Results:
 
2453
 *      VixError.  VIX_OK on success.  Some other VIX_* code if message is malformed.
 
2454
 *
 
2455
 * Side effects:
 
2456
 *      None.
 
2457
 *
 
2458
 *-----------------------------------------------------------------------------
 
2459
 */
 
2460
 
 
2461
VixError
 
2462
__VMAutomationMsgParserGetPropertyList(const char *caller,            // IN
 
2463
                                       unsigned int line,             // IN
 
2464
                                       VMAutomationMsgParser *state,  // IN/OUT
 
2465
                                       size_t length,                 // IN
 
2466
                                       VixPropertyListImpl *propList) // IN/OUT
 
2467
{
 
2468
   VixError err;
 
2469
 
 
2470
   err = VIX_OK;
 
2471
   if (length) {
 
2472
      const char *data;
 
2473
 
 
2474
      err = __VMAutomationMsgParserGetData(caller, line, state, length,
 
2475
                                           &data);
 
2476
      if (VIX_OK == err) {
 
2477
         err = VixPropertyList_Deserialize(propList, data, length,
 
2478
                                           VIX_PROPERTY_LIST_BAD_ENCODING_ERROR);
 
2479
      }
 
2480
   }
 
2481
 
 
2482
   return err;
 
2483
}