move files and directories into pcucontrol module
[monitor.git] / pcucontrol / models / intelamt / Utils.cpp
1 //----------------------------------------------------------------------------
2 //
3 //  Copyright (C) Intel Corporation, 2004 - 2006.
4 //
5 //  File:       Utils.h
6 //
7 //  Contents:   Sample code for an Intel® AMT Network client.
8 //
9 //  Notes:      This file contains the function implementations 
10 //              used throughout the code of the all sample applications.
11 //
12 //----------------------------------------------------------------------------
13
14 #include <stdio.h> 
15 #include <string.h>
16 #include <stdlib.h>
17 #include "CommonDefinitions.h"
18
19 #ifdef _WIN32   
20 #define strncasecmp _strnicmp
21 #endif
22
23 // Constant definitions
24 static const char *URL_SEPARATOR = "://";
25 static const int NUM_OF_BYTES = 4;
26 static const int IP_BYTE_MASK = 0xFF;
27 static const int IP_BYTE_SHIFT = 0x8;
28
29 /*
30  * Gets command line parameter that describes type of action to perform
31  * Arguments:
32  *      commandLineLength - number of the command line parameters
33  *      argv - array of strings that holds command line parameters
34  *      numOfArgs - minimal number of command line parameters
35  *      option - pointer to the string that will hold command line
36  *                       parameter that describes type of action to perform
37  *      commandLine - pointer to the array of strings that will hold 
38  *                                command line parameters without application name 
39  *                                and parameter that describes type of action to perform
40  * Return Value:
41  *  true    - on success
42  *  false   - on failure
43  */
44 bool GetOption(int *commandLineLength, char *argv[], int numOfArgs,
45                            char **option, char **commandLine[])
46 {
47         if( !argv || 
48                 *commandLineLength < numOfArgs)
49         {
50                 return false;
51         }
52
53         *option = NULL;
54         *commandLine = &argv[1];
55         // Skip the application name
56         (*commandLineLength) --;
57
58         if( argv[1][0] == '-')
59         {
60                 if(strcmp(argv[1],CERT_NAME) && strcmp(argv[1],USER) && 
61            strcmp(argv[1],VERBOSE)
62 #ifdef _WIN32
63            && strcmp(argv[1],LOCAL)
64 #endif
65            )
66                 {
67                         *option = argv[1];
68                         *commandLine = &argv[2];
69             (*commandLineLength) --;
70                 }
71         }
72         
73         return true;
74 }
75
76 #ifdef _WIN32
77 /*
78  * Parses the user input text
79  * Arguments:
80  *  commandLineLength - number of arguments
81  *  commandLine       - command line arguments received
82  *  target   - pointer to the string that will hold the target url
83  *  certName - pointer to the string that will hold client certificate's name 
84  *  verbose - pointer to the verbose flag
85  *  username - pointer to the string that will hold the username
86  *  password - pointer to the string that will hold the password
87  * Return Value:
88  *  true    - on success
89  *  false   - on failure
90  */
91 bool ParseCommandLine(int commandLineLength,char* commandLine[],char **target,
92                                           char **certName, bool *local, bool *krb, bool *verbose,  
93                       char **username, char **password)
94 {
95 #else
96 /*
97  * Parses the user input text
98  * Arguments:
99  *  commandLineLength     - number of arguments
100  *  commandLine     - command line arguments received
101  *  target - pointer to the string that will hold the target url
102  *  certName - pointer to the string that will hold client certificate's name*  
103  *      certPass - pointer to the string that will hold passphrase for decryption
104  *             the file that contains private key associated with the given
105  *             client certificate
106  *  verbose - pointer to the verbose flag
107  *  username - pointer to the string that will hold the username
108  *  password - pointer to the string that will hold the password
109  * Return Value:
110  *  true    - on success
111  *  false   - on failure
112  */
113 bool ParseCommandLine(int commandLineLength,char* commandLine[],char **target, 
114                                           char **certName,char **certPass, bool *verbose, 
115                                           char **username, char **password)
116 {
117         *certPass = NULL;
118 #endif
119         *certName = NULL;
120         *target = NULL;
121         *password = NULL;
122         *username = NULL;
123
124         if (verbose != NULL) {
125                 *verbose = false;
126         }
127
128         for(int i = 0; i < commandLineLength; i++)
129     {           
130         if( !strcmp(commandLine[i], CERT_NAME) )
131         {
132             if( i+1 < commandLineLength && ! *certName )
133             {
134                 *certName = commandLine[++i];
135             }
136             else
137             {
138                 return false;
139             }
140         }
141 #ifndef _WIN32
142                 else if( !strcmp(commandLine[i], CERT_PASS) )
143                 {
144                         if( i+1 < commandLineLength && ! *certPass )
145                         {
146                                 *certPass = commandLine[++i];
147                         }
148                         else
149                         {
150                                 return false;
151                         }
152                 }
153 #endif
154                 else if( !strcmp(commandLine[i], VERBOSE) && verbose != NULL)
155                 {
156                         *verbose = true;
157                 }
158 #ifdef _WIN32
159         else if( !strcmp(commandLine[i], LOCAL) && local != NULL)
160                 {
161                         *local = true;
162                 }
163 #endif
164                 else if( !strcmp(commandLine[i], USER) )
165                 {
166         
167                         if( i+1 < commandLineLength && ! *username )
168                         {
169                                 *username = commandLine[++i];
170                         }
171                         else
172                         {
173                                 return false;
174                         }
175                 }
176                 else if( !strcmp(commandLine[i], PASS) )
177                 {
178          
179                         if( i+1 < commandLineLength && ! *password )
180                         {
181                                 *password = commandLine[++i];
182                         }
183                         else
184                         {
185                                 return false;
186                         }
187                 }
188                 else
189                 {
190                         //this is a target URL argument
191                         if( !ValidateIP(commandLine[i]) )
192                         {
193                                 return false;
194                         }
195                         *target = commandLine[i];
196                 }
197         }
198         if( !*target || (!strncasecmp(*target, "http:", 5) && *certName != 0 ))
199         {
200                 return false;
201         }
202         if( (*username && !*password) || (!*username && *password)) 
203         {
204                 return false;
205         }
206 #ifdef _WIN32
207         else if(*username && *password)
208         {
209                 *krb = false;
210         }
211 #else
212         else if(!*username)
213         {
214                 return false;
215         }
216 #endif
217         return true;
218 }
219
220 /*
221  * Checks if IP address exists in the URI
222  * Arguments:
223  *  uri - pointer to the string that represents the URI
224  * Return value:
225  *  true  - on success
226  *  false - on failure
227  */
228 bool ValidateIP(const char *uri)
229 {
230         if( strncasecmp(uri, "http:", 5 ) && strncasecmp(uri, "https:", 6 ) )
231         {
232                 return false;
233         }
234     bool retVal = true;
235     
236     // pointer to the start of the IP address
237     const char *start = strstr(uri,URL_SEPARATOR);
238     if(start != NULL)
239     {
240         start += (sizeof(URL_SEPARATOR) - 1);
241
242         // pointer to the end of the IP address
243         const char *end = strchr(start,':');
244
245         if(end != NULL && start != end)
246         {
247             retVal = true;
248         }
249         else
250         {
251             retVal = false;
252         }
253     }
254     else
255     {
256         retVal = false;
257     }
258
259     return retVal;
260 }
261
262 /*
263  * Gets an input string from the user
264  * Assumptions: caller pre-allocates string, and user must not overflow (!)
265  * Arguments:
266  *  msg         - message string
267  *  s           - pre-allocated input string that will represent the binary data
268  *  hidden      - echo input string (true / false)
269  */
270 void GetString(char *msg, char *s, bool hidden)
271 {
272
273         // Output informative message
274         if(msg != NULL)
275         {
276                 printf ("%s", msg);
277         }
278         fflush(NULL);
279
280 #ifdef _WIN32
281         char c; // for the next input character
282         int count = 0; // number of characters
283
284         // Get input string character by character
285         do 
286         {
287                 c = _getch();
288
289                 count ++;
290
291                 if (c == '\r' || // carriage return
292                         c == '\n' || // new line
293                         c == '\t' || // TAB
294                         count == MAX_LINE_LEN ) // maximal line length
295                 {
296                         *s=0;
297                         break;
298                 }
299                 else if ( c==3 ) // <CTRL> + C
300                 {
301                         exit(0);
302                 }
303         else if ( c == '\b' ) // backspace
304         {
305                         count --;
306                         if(count > 0)
307                         {
308                                 printf("%c", c);
309                                 printf("%c", ' ');
310                                 printf("%c", c);
311                                 count --;
312                                 s --;
313                         }
314             continue;
315         }
316
317                 // The password should be hidden
318                 if ( hidden )
319                 {
320                         printf("*");
321                 }
322                 else
323                 {
324                         printf("%c", c);
325                 }
326                 *s = c;
327                 s++;
328         }
329         while ( true );
330         printf("\n");
331 #else
332
333         if(hidden == false)
334         {
335                 if(fgets(s,MAX_LINE_LEN,stdin))
336                 {
337                         char *tmp = strchr(s,'\n');
338                         if(tmp != NULL)
339                         {
340                                 *tmp = '\0';
341                         }
342                 }
343         }
344         else
345         {
346                 strcpy(s,getpass(""));
347         }
348 #endif
349 }
350
351 /*
352  * Receives yes or no answer from the user.
353  * Arguments:
354  *      msg     - pointer to the string that holds a question
355  * Return value:
356  *  true    - if answer is 'y' (yes)
357  *  false   - otherwise
358  */
359 bool DisplayWarning(const char *msg)
360 {
361     printf("%s",msg);
362     char c;
363     scanf("%c",&c);
364     
365         if(c != 'y' && c != 'n')
366         {
367                 printf("Illegal choice. Aborting.\n");
368                 return false;
369         }
370         else if(c == 'n')
371         {
372                 return false;
373         }
374     scanf("%c",&c);
375
376     return true;
377 }
378
379 /*
380  * Gets a number from the user
381  * Arguments:
382  *  number - pointer to the variable that will be hold a number
383  * Return value:
384  *  true  - on success
385  *  false - on failure
386  */
387 bool GetNumber(int *number)
388 {
389     scanf("%d",number);
390     int c = getchar();
391         if(c != '\n' && c != '\r')
392         {
393                 return false;
394         }
395     return true;
396 }
397
398 /*
399  * Checks the exit status of the SOAP query
400  * Arguments:
401  *  res - exit statis of the gSOAP function call 
402  *  status      - status codes that are returned by 
403  *                              Intel(R) AMT network API
404  *  message     - string that holds the function name
405  * Return value:
406  *      true - if the query succeed
407  *      false - if the query failed
408  */
409 bool CheckReturnStatus(unsigned int res, unsigned long status, 
410                                            const char *message)
411 {
412         if (res || status)
413         {
414                 printf("\nError: failed while calling %s\n", message);
415                 if(res == 0)
416                 {
417 #ifndef _WIN32
418             printf("Status = %lu\n", status);
419 #else
420             wchar_t err[MAX_LINE_LEN];
421             GetStatusString(status,err,MAX_LINE_LEN);
422             wprintf(err);
423             printf("\n");
424 #endif
425                 }
426                 else
427                 {
428             printf("SOAP failure: error code = %u\n", res);
429                 }
430                 return false;
431         }
432         return true;
433 }
434
435 /*
436  * Changes the service name at the URI
437  * Arguments:
438  *      uri     - null-terminated string which holds the whole URI as supplied 
439  *                at the command line
440  *  newService  - string which represents the new service name
441  *  newUri      - pre-allocated string which will hold the new service URI
442  */
443 bool ChangeService(const char *uri, const char *newService, char *newUri)
444 {
445     const char *tmp = strrchr(uri,'/');
446     if(tmp == NULL)
447     {
448        return false;
449     }
450
451     int n = tmp - uri + 1;
452     
453     strncpy(newUri,uri,n);
454     newUri[strlen(uri) - strlen(tmp) + 1] = '\0';
455         //check new Uri allocated 
456     if(&(newUri[n]) == NULL)
457     {
458         return false;
459     }
460     //copy newService to end of string instead '\o' 
461     strcpy(&(newUri[n]),newService);
462  
463     return true;
464 }
465
466 /*
467  * Replaces substring within given string
468  * Arguments:
469  *      oldString       - pointer to the old null-terminated string
470  *  oldSubstr   - substring that will be replaced
471  *  newSubstr   - string which represents the new substring
472  *  newString   - pre-allocated buffer which will hold the new string
473  */
474 void ReplaceSubstring(const char *oldString,const char *oldSubstr, 
475                                         const char *newSubstr, char *newString)
476 {
477         // Locate substring
478         const char *tmp = strstr(oldString,oldSubstr);
479
480         if(tmp == NULL)
481         {
482                 printf("Error: cannot find '%s' within '%s'\n",oldSubstr,oldString);
483                 exit(1);
484         }
485
486         int len1 = strlen(oldSubstr);
487         int len2 = strlen(newSubstr);
488         int i,k,j;
489
490         // Copy string to the buffer with appropriate change
491         for(i = 0, k = 0; oldString[i] != '\0'; i ++, k ++)
492         {
493                 if(tmp == &oldString[i])
494                 {
495                         for(j = 0; j < len2; k ++, j ++)
496                         {
497                                 newString[k] = newSubstr[j];
498                         }
499                         i += len1;
500                 }
501                 newString[k] = oldString[i];
502         }
503         newString[k] = oldString[i];
504 }
505
506 /*
507  * Converts the IP address from the dot-separated format
508  * to the usigned long number
509  * Arguments:
510  *  address     - number that will hold a converted IP address 
511  *  bytes       - array for IP address's bytes
512  */
513 void SetIPAddress(unsigned long &address, unsigned long bytes[])
514 {
515         address = 0;
516         int i;
517         for(i = 0; i < NUM_OF_BYTES - 1; i ++)
518         {
519                 address += bytes[i];
520                 address <<= 8;
521         }
522         address += bytes[i];
523 }
524
525 /*
526  * Extracts bytes from the IP address for the dot-separated representation
527  * Arguments:
528  *  address     - number that holds a IP address 
529  *  bytes       - array that will hold IP address bytes
530  */
531 void NumberToIP(unsigned long address, unsigned long bytes[])
532 {
533         int i;
534         for(i = NUM_OF_BYTES - 1; i > 0; i --)
535         {
536                 bytes[i] = address & IP_BYTE_MASK;
537                 address >>= IP_BYTE_SHIFT;
538         }
539         bytes[i] = address & IP_BYTE_MASK;
540 }
541
542
543 /*
544  * Converts a number to a string
545  * Arguments & Return values:
546  *      number  - number which will convert
547  *      string  - string which will hold the converted number
548  */
549 void NumberToString(unsigned long number, char *string)
550 {
551         div_t res;
552         int i = 0;
553         char tmp[MAX_LINE_LEN];
554         do
555         {
556                 res = div(number,10);
557                 tmp[i++] = (char)('0' + res.rem);
558                 number = res.quot;
559         }while(number != 0);
560
561         for(i --; i >= 0; i --)
562         {
563                 *string = tmp[i];
564                 string ++;
565         }
566         *string = '\0';
567 }
568
569 /*
570  * Converts the IP address to the dot-separated string form
571  * Arguments & Return values:
572  *      address - number which holds the IP address
573  *      string  - string which will represent the IP address in
574  *                        the dot-separated format
575  */
576 void IpToString(unsigned long address, char *string)
577 {
578         unsigned long bytes[NUM_OF_BYTES];
579         NumberToIP(address,bytes);//one,two,three,four);
580
581         char tmp[MAX_LINE_LEN];
582         char *ptr = string;
583
584         for(int i = 0; i < NUM_OF_BYTES; i ++)
585         {
586                 NumberToString(bytes[i],tmp);
587                 strcpy(ptr,tmp);
588                 ptr += strlen(tmp);
589                 *ptr = '.';
590                 ptr ++;
591         }
592         ptr --;
593         *ptr = '\0';    
594 }
595
596 /*
597  * Converts the string that represents dot-separated 
598  * format of the IP address to the number
599  * Arguments:
600  *      string  - string which represents IP address in
601  *                        the dot-separated format
602  *      address - number which will hold the converted IP address
603  */
604 void StringToIP(const char *string, unsigned long &address)
605 {
606         // local copy of the string
607         char tmpStr[MAX_LINE_LEN];
608         strncpy(tmpStr,string,MAX_LINE_LEN - 1);
609         tmpStr[MAX_LINE_LEN - 1] = '\0';
610
611         char *tmpPtr1 = NULL;
612         char *tmpPtr2 = tmpStr;
613         unsigned long bytes[NUM_OF_BYTES];
614         int i; 
615
616         for(i = 0; i < NUM_OF_BYTES - 1; i ++)
617         {
618                 if((tmpPtr1 = strstr(tmpPtr2,".")) == NULL)
619                 {
620                         goto FAULT_EXIT;
621                 }
622
623                 *tmpPtr1 = '\0';
624                 bytes[i] = atol(tmpPtr2);
625                 tmpPtr2 = tmpPtr1 + 1;
626         }
627         bytes[i] = atol(tmpPtr2);
628
629         SetIPAddress(address,bytes);//one,two,three,four);
630
631         return;
632
633         FAULT_EXIT:
634         printf("Error: invalid format\n");
635         exit(1);
636 }
637
638 /* 
639  * Converts the bunary guid to a string according to the representation
640  * described in the CDE 1.1 RPC specification
641  * Arguments & Return values:
642  *      guid    - a pointer to the 16 byte guid
643  *      string  - string which will hold the guid string
644  */
645 void GuidToString(const unsigned char* guid, char* string)
646 {          
647         if(guid != NULL && string != NULL)
648         {
649                 int j = sprintf(string, "%02X%02X%02X%02X", guid[3], guid[2], guid[1], guid[0]);
650                 j += sprintf(string + j, "-%02X%02X", guid[5], guid[4]);
651                 j += sprintf(string + j, "-%02X%02X", guid[7], guid[6]);
652                 j += sprintf(string + j, "-%02X%02X-", guid[8], guid[9]);               
653                 for(int i = 10; i <= 15; i ++)
654                 {
655                         j += sprintf(string + j, "%02X", guid[i]);
656                 }
657         }
658 }
659
660 /*
661  * Extracts IP address from the URI
662  * Arguments:
663  *  uri - pointer to the string that represents the URI
664  * Return value:
665  *  true  - on success
666  *  false - on failure
667  */
668 bool ExtractIPFromUri(const char *uri, char *baseUrl)
669 {
670     char *ip = baseUrl;
671     bool retVal = true;
672     
673     // pointer to the start of the IP address
674     const char *start = strstr(uri,URL_SEPARATOR);
675     if(start != NULL)
676     {
677         start += (sizeof(URL_SEPARATOR) - 1);
678
679         // pointer to the end of the IP address
680         const char *end = strchr(start,':');
681
682         if(end != NULL && start != end)
683         {
684             while(start != end)
685             {
686                 *ip = *start;
687                 ip ++;
688                 start ++;
689             }
690                         *ip = '\0'; // NULL termination
691         }
692         else
693         {
694             retVal = false;
695         }
696     }
697     else
698     {
699         retVal = false;
700     }
701
702     return retVal;
703 }
704
705 /* 
706  * prints "success" to output
707  * Argument: 
708  *  printS - prints only if true
709  */
710 void PrintSuccess(bool printS)
711 {       
712         if(printS)
713         {
714                 printf("success\n");
715         }
716 }
717
718 /* 
719  * prints function call to output
720  * Argument: 
721  *  message - name of function
722  */
723 void FunctionCall(const char *message)
724 {
725         printf("\nCalling function %s...   ", message);
726 }
727
728 /*
729  * Performs testing of the URL
730  * Arguments:
731  *      targetUrl - string that represents URL of the target machine
732  *      isEmulator - pointer to the variable that will be 1 if the targetUrl 
733  *                               points to the Intel® AMT device or 0 if the targetUrl
734  *                               points to the Intel® AMT Emulator
735  */
736 void IsEmulator(const char *targetUrl, int *isEmulator)
737 {
738         *isEmulator = 1;
739
740         if((strstr(targetUrl,".asmx")) == (targetUrl + strlen(targetUrl) - 5))
741         {
742                 *isEmulator = 0;
743         }
744 }
745
746 /*
747  * Prints notes for usage by authentication options
748  */
749 void PrintAuthenticationNote()
750 {
751 #ifndef _WIN32
752     printf("\t %s <username> %s <password>: for digest authentication.\n",USER,PASS);
753 #else
754         printf("\n\t If %s <username> %s <password> are defined the Digest authentication" ,USER,PASS);
755         printf(" scheme is used,\n\t otherwise the Kerberos authentication scheme will be attempted.\n");
756 #endif
757     printf("\nClient authentication options (TLS Mutual Authentication mode only):\n");
758 #ifndef _WIN32
759     printf("\t %s: If option defined <name> specify the full path of the ",
760         CERT_NAME);
761     printf("file containing client certificate and private keys.\n");
762     printf("\t %s: If option defined <pass> specify the passphrase ",
763         CERT_PASS);
764     printf("that protects the private key. ");
765 #else
766         printf("\t %s: If option defined, <name> specifies the client certificate's",
767         CERT_NAME);
768     printf(" Common Name (CN).\n");
769      
770         printf("\t\t    If option is not specified the sample application will search the certificate store \n");
771         printf("\t\t    for a client certificate matching Intel(R) AMT requirements.  \n");
772         printf("\t\t    The first one found will be used for authentication.\n");
773 #endif
774 }
775