1 /** @file
2   The main process for IpSecConfig application.
3 
4   Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
5 
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this distribution.  The full text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php.
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include <Library/UefiRuntimeServicesTableLib.h>
17 #include <Library/HiiLib.h>
18 
19 #include <Protocol/IpSec.h>
20 
21 #include "IpSecConfig.h"
22 #include "Dump.h"
23 #include "Indexer.h"
24 #include "PolicyEntryOperation.h"
25 #include "Delete.h"
26 #include "Helper.h"
27 
28 //
29 // String token ID of IpSecConfig command help message text.
30 //
31 GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringIpSecHelpTokenId = STRING_TOKEN (STR_IPSEC_CONFIG_HELP);
32 
33 //
34 // Used for ShellCommandLineParseEx only
35 // and to ensure user inputs are in valid format
36 //
37 SHELL_PARAM_ITEM    mIpSecConfigParamList[] = {
38   { L"-p",                    TypeValue },
39   { L"-a",                    TypeValue },
40   { L"-i",                    TypeValue },
41   { L"-e",                    TypeValue },
42   { L"-d",                    TypeValue },
43   { L"-f",                    TypeFlag },
44   { L"-l",                    TypeFlag },
45   { L"-enable",               TypeFlag },
46   { L"-disable",              TypeFlag },
47   { L"-status",               TypeFlag },
48 
49   //
50   // SPD Selector
51   //
52   { L"--local",               TypeValue },
53   { L"--remote",              TypeValue },
54   { L"--proto",               TypeValue },
55   { L"--local-port",          TypeValue },
56   { L"--remote-port",         TypeValue },
57   { L"--icmp-type",           TypeValue },
58   { L"--icmp-code",           TypeValue },
59 
60   //
61   // SPD Data
62   //
63   { L"--name",                TypeValue },
64   { L"--packet-flag",         TypeValue },
65   { L"--action",              TypeValue },
66   { L"--lifebyte",            TypeValue },
67   { L"--lifetime-soft",       TypeValue },
68   { L"--lifetime",            TypeValue },
69   { L"--mode",                TypeValue },
70   { L"--tunnel-local",        TypeValue },
71   { L"--tunnel-remote",       TypeValue },
72   { L"--dont-fragment",       TypeValue },
73   { L"--ipsec-proto",         TypeValue },
74   { L"--auth-algo",           TypeValue },
75   { L"--encrypt-algo",        TypeValue },
76 
77   { L"--ext-sequence",        TypeFlag  },
78   { L"--sequence-overflow",   TypeFlag  },
79   { L"--fragment-check",      TypeFlag  },
80   { L"--ext-sequence-",       TypeFlag  },
81   { L"--sequence-overflow-",  TypeFlag  },
82   { L"--fragment-check-",     TypeFlag  },
83 
84   //
85   // SA ID
86   // --ipsec-proto
87   //
88   { L"--spi",                 TypeValue },
89   { L"--tunnel-dest",         TypeValue },
90   { L"--tunnel-source",       TypeValue },
91   { L"--lookup-spi",          TypeValue },
92   { L"--lookup-ipsec-proto",  TypeValue },
93   { L"--lookup-dest",         TypeValue },
94 
95   //
96   // SA DATA
97   // --mode
98   // --auth-algo
99   // --encrypt-algo
100   //
101   { L"--sequence-number",     TypeValue },
102   { L"--antireplay-window",   TypeValue },
103   { L"--auth-key",            TypeValue },
104   { L"--encrypt-key",         TypeValue },
105   { L"--path-mtu",            TypeValue },
106 
107   //
108   // PAD ID
109   //
110   { L"--peer-id",             TypeValue },
111   { L"--peer-address",        TypeValue },
112   { L"--auth-proto",          TypeValue },
113   { L"--auth-method",         TypeValue },
114   { L"--ike-id",              TypeValue },
115   { L"--ike-id-",             TypeValue },
116   { L"--auth-data",           TypeValue },
117   { L"--revocation-data",     TypeValue },
118   { L"--lookup-peer-id",      TypeValue },
119   { L"--lookup-peer-address", TypeValue },
120 
121   { NULL,                     TypeMax   },
122 };
123 
124 //
125 // -P
126 //
127 STR2INT mMapPolicy[] = {
128   { L"SPD",       IPsecConfigDataTypeSpd },
129   { L"SAD",       IPsecConfigDataTypeSad },
130   { L"PAD",       IPsecConfigDataTypePad },
131   { NULL,         0 },
132 };
133 
134 //
135 // --proto
136 //
137 STR2INT mMapIpProtocol[] = {
138   { L"TCP",       EFI_IP4_PROTO_TCP },
139   { L"UDP",       EFI_IP4_PROTO_UDP },
140   { L"ICMP",      EFI_IP4_PROTO_ICMP },
141   { NULL,         0 },
142 };
143 
144 //
145 // --action
146 //
147 STR2INT mMapIpSecAction[] = {
148   { L"Bypass",    EfiIPsecActionBypass },
149   { L"Discard",   EfiIPsecActionDiscard },
150   { L"Protect",   EfiIPsecActionProtect },
151   { NULL,         0 },
152 };
153 
154 //
155 // --mode
156 //
157 STR2INT mMapIpSecMode[] = {
158   { L"Transport", EfiIPsecTransport },
159   { L"Tunnel",    EfiIPsecTunnel },
160   { NULL,         0 },
161 };
162 
163 //
164 // --dont-fragment
165 //
166 STR2INT mMapDfOption[] = {
167   { L"clear",     EfiIPsecTunnelClearDf },
168   { L"set",       EfiIPsecTunnelSetDf },
169   { L"copy",      EfiIPsecTunnelCopyDf },
170   { NULL,         0 },
171 };
172 
173 //
174 // --ipsec-proto
175 //
176 STR2INT mMapIpSecProtocol[] = {
177   { L"AH",        EfiIPsecAH },
178   { L"ESP",       EfiIPsecESP },
179   { NULL,         0 },
180 };
181 
182 //
183 // --auth-algo
184 //
185 STR2INT mMapAuthAlgo[] = {
186   { L"NONE",         IPSEC_AALG_NONE },
187   { L"MD5HMAC",      IPSEC_AALG_MD5HMAC },
188   { L"SHA1HMAC",     IPSEC_AALG_SHA1HMAC },
189   { L"SHA2-256HMAC", IPSEC_AALG_SHA2_256HMAC },
190   { L"SHA2-384HMAC", IPSEC_AALG_SHA2_384HMAC },
191   { L"SHA2-512HMAC", IPSEC_AALG_SHA2_512HMAC },
192   { L"AES-XCBC-MAC", IPSEC_AALG_AES_XCBC_MAC },
193   { L"NULL",         IPSEC_AALG_NULL },
194   { NULL,            0 },
195 };
196 
197 //
198 // --encrypt-algo
199 //
200 STR2INT mMapEncAlgo[] = {
201   { L"NONE",         IPSEC_EALG_NONE },
202   { L"DESCBC",       IPSEC_EALG_DESCBC },
203   { L"3DESCBC",      IPSEC_EALG_3DESCBC },
204   { L"CASTCBC",      IPSEC_EALG_CASTCBC },
205   { L"BLOWFISHCBC",  IPSEC_EALG_BLOWFISHCBC },
206   { L"NULL",         IPSEC_EALG_NULL },
207   { L"AESCBC",       IPSEC_EALG_AESCBC },
208   { L"AESCTR",       IPSEC_EALG_AESCTR },
209   { L"AES-CCM-ICV8", IPSEC_EALG_AES_CCM_ICV8 },
210   { L"AES-CCM-ICV12",IPSEC_EALG_AES_CCM_ICV12 },
211   { L"AES-CCM-ICV16",IPSEC_EALG_AES_CCM_ICV16 },
212   { L"AES-GCM-ICV8", IPSEC_EALG_AES_GCM_ICV8 },
213   { L"AES-GCM-ICV12",IPSEC_EALG_AES_GCM_ICV12 },
214   { L"AES-GCM-ICV16",IPSEC_EALG_AES_GCM_ICV16 },
215   { NULL,            0 },
216 };
217 
218 //
219 // --auth-proto
220 //
221 STR2INT mMapAuthProto[] = {
222   { L"IKEv1",        EfiIPsecAuthProtocolIKEv1 },
223   { L"IKEv2",        EfiIPsecAuthProtocolIKEv2 },
224   { NULL,            0 },
225 };
226 
227 //
228 // --auth-method
229 //
230 STR2INT mMapAuthMethod[] = {
231   { L"PreSharedSecret", EfiIPsecAuthMethodPreSharedSecret },
232   { L"Certificates",    EfiIPsecAuthMethodCertificates },
233   { NULL,               0 },
234 };
235 
236 EFI_IPSEC2_PROTOCOL          *mIpSec;
237 EFI_IPSEC_CONFIG_PROTOCOL    *mIpSecConfig;
238 EFI_HII_HANDLE               mHiiHandle;
239 CHAR16                       mAppName[]          = L"IpSecConfig";
240 
241 //
242 // Used for IpSecConfigRetriveCheckListByName only to check the validation of user input
243 //
244 VAR_CHECK_ITEM    mIpSecConfigVarCheckList[] = {
245   { L"-enable",              BIT(1)|BIT(0),  BIT(1),  BIT(2)|BIT(1)|BIT(0), 0 },
246   { L"-disable",             BIT(1)|BIT(0),  BIT(1),  BIT(2)|BIT(1)|BIT(0), 0 },
247   { L"-status",              BIT(1)|BIT(0),  BIT(1),  BIT(2)|BIT(1)|BIT(0), 0 },
248   { L"-p",                   BIT(1),         0,       BIT(2)|BIT(1)|BIT(0), 0 },
249 
250   { L"-a",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },
251   { L"-i",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },
252   { L"-d",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },
253   { L"-e",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },
254   { L"-l",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },
255   { L"-f",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },
256 
257   { L"-?",                   BIT(0),         BIT(0),  BIT(2)|BIT(1)|BIT(0), 0 },
258 
259   //
260   // SPD Selector
261   //
262   { L"--local",              0,              0,       BIT(2)|BIT(1),        0 },
263   { L"--remote",             0,              0,       BIT(2)|BIT(1),        0 },
264   { L"--proto",              0,              0,       BIT(2)|BIT(1),        0 },
265   { L"--local-port",         0,              0,       BIT(2)|BIT(1),        BIT(0) },
266   { L"--remote-port",        0,              0,       BIT(2)|BIT(1),        BIT(0) },
267   { L"--icmp-type",          0,              0,       BIT(2)|BIT(1),        BIT(1) },
268   { L"--icmp-code",          0,              0,       BIT(2)|BIT(1),        BIT(1) },
269 
270   //
271   // SPD Data
272   //
273   { L"--name",               0,              0,       BIT(2),               0 },
274   { L"--packet-flag",        0,              0,       BIT(2),               0 },
275   { L"--action",             0,              0,       BIT(2)|BIT(1),        0 },
276   { L"--lifebyte",           0,              0,       BIT(2)|BIT(1),        0 },
277   { L"--lifetime-soft",      0,              0,       BIT(2)|BIT(1),        0 },
278   { L"--lifetime",           0,              0,       BIT(2)|BIT(1),        0 },
279   { L"--mode",               0,              0,       BIT(2)|BIT(1),        0 },
280   { L"--tunnel-local",       0,              0,       BIT(2),               0 },
281   { L"--tunnel-remote",      0,              0,       BIT(2),               0 },
282   { L"--dont-fragment",      0,              0,       BIT(2),               0 },
283   { L"--ipsec-proto",        0,              0,       BIT(2)|BIT(1),        0 },
284   { L"--auth-algo",          0,              0,       BIT(2)|BIT(1),        0 },
285   { L"--encrypt-algo",       0,              0,       BIT(2)|BIT(1),        0 },
286 
287   { L"--ext-sequence",       0,              0,       BIT(2),               BIT(2) },
288   { L"--sequence-overflow",  0,              0,       BIT(2),               BIT(2) },
289   { L"--fragment-check",     0,              0,       BIT(2),               BIT(2) },
290   { L"--ext-sequence-",      0,              0,       BIT(2),               BIT(3) },
291   { L"--sequence-overflow-", 0,              0,       BIT(2),               BIT(3) },
292   { L"--fragment-check-",    0,              0,       BIT(2),               BIT(3) },
293 
294   //
295   // SA ID
296   // --ipsec-proto
297   //
298   { L"--spi",                0,              0,       BIT(1),               0 },
299   { L"--tunnel-dest",        0,              0,       BIT(1),               0 },
300   { L"--tunnel-source",      0,              0,       BIT(1),               0 },
301   { L"--lookup-spi",         0,              0,       BIT(1),               0 },
302   { L"--lookup-ipsec-proto", 0,              0,       BIT(1),               0 },
303   { L"--lookup-dest",        0,              0,       BIT(1),               0 },
304 
305   //
306   // SA DATA
307   // --mode
308   // --auth-algo
309   // --encrypt-algo
310   //
311   { L"--sequence-number",    0,              0,       BIT(1),               0 },
312   { L"--antireplay-window",  0,              0,       BIT(1),               0 },
313   { L"--auth-key",           0,              0,       BIT(1),               0 },
314   { L"--encrypt-key",        0,              0,       BIT(1),               0 },
315   { L"--path-mtu",           0,              0,       BIT(1),               0 },
316 
317   //
318   // The example to add a PAD:
319   // "-A --peer-id Mike [--peer-address 10.23.2.2] --auth-proto IKE1/IKE2
320   //     --auth-method PreSharedSeceret/Certificate --ike-id
321   //     --auth-data 343343 --revocation-data 2342432"
322   // The example to delete a PAD:
323   // "-D * --lookup-peer-id Mike [--lookup-peer-address 10.23.2.2]"
324   // "-D 1"
325   // The example to edit a PAD:
326   // "-E * --lookup-peer-id Mike --auth-method Certificate"
327 
328   //
329   // PAD ID
330   //
331   { L"--peer-id",            0,              0,       BIT(0),               BIT(4) },
332   { L"--peer-address",       0,              0,       BIT(0),               BIT(5) },
333   { L"--auth-proto",         0,              0,       BIT(0),               0 },
334   { L"--auth-method",        0,              0,       BIT(0),               0 },
335   { L"--IKE-ID",             0,              0,       BIT(0),               BIT(6) },
336   { L"--IKE-ID-",            0,              0,       BIT(0),               BIT(7) },
337   { L"--auth-data",          0,              0,       BIT(0),               0 },
338   { L"--revocation-data",    0,              0,       BIT(0),               0 },
339   { L"--lookup-peer-id",     0,              0,       BIT(0),               BIT(4) },
340   { L"--lookup-peer-address",0,              0,       BIT(0),               BIT(5) },
341 
342   { NULL,                    0,              0,       0,                    0 },
343 };
344 
345 /**
346   The function to allocate the proper sized buffer for various
347   EFI interfaces.
348 
349   @param[in, out] Status        Current status.
350   @param[in, out] Buffer        Current allocated buffer, or NULL.
351   @param[in]      BufferSize    Current buffer size needed
352 
353   @retval TRUE     If the buffer was reallocated and the caller should try the API again.
354   @retval FALSE    If the buffer was not reallocated successfully.
355 **/
356 BOOLEAN
GrowBuffer(IN OUT EFI_STATUS * Status,IN OUT VOID ** Buffer,IN UINTN BufferSize)357 GrowBuffer (
358   IN OUT EFI_STATUS    *Status,
359   IN OUT VOID          **Buffer,
360   IN     UINTN         BufferSize
361   )
362 {
363   BOOLEAN    TryAgain;
364 
365   ASSERT (Status != NULL);
366   ASSERT (Buffer != NULL);
367 
368   //
369   // If this is an initial request, buffer will be null with a new buffer size.
370   //
371   if ((NULL == *Buffer) && (BufferSize != 0)) {
372     *Status = EFI_BUFFER_TOO_SMALL;
373   }
374 
375   //
376   // If the status code is "buffer too small", resize the buffer.
377   //
378   TryAgain = FALSE;
379   if (*Status == EFI_BUFFER_TOO_SMALL) {
380 
381     if (*Buffer != NULL) {
382       FreePool (*Buffer);
383     }
384 
385     *Buffer = AllocateZeroPool (BufferSize);
386 
387     if (*Buffer != NULL) {
388       TryAgain = TRUE;
389     } else {
390       *Status = EFI_OUT_OF_RESOURCES;
391     }
392   }
393 
394   //
395   // If there's an error, free the buffer.
396   //
397   if (!TryAgain && EFI_ERROR (*Status) && (*Buffer != NULL)) {
398     FreePool (*Buffer);
399     *Buffer = NULL;
400   }
401 
402   return TryAgain;
403 }
404 
405 /**
406   Function returns an array of handles that support the requested protocol
407   in a buffer allocated from a pool.
408 
409   @param[in]      SearchType    Specifies which handle(s) are to be returned.
410   @param[in]      Protocol      Provides the protocol to search by.
411                                 This parameter is only valid for SearchType ByProtocol.
412 
413   @param[in]      SearchKey     Supplies the search key depending on the SearchType.
414   @param[in, out] NoHandles     The number of handles returned in Buffer.
415   @param[out]     Buffer        A pointer to the buffer to return the requested array of
416                                 handles that support Protocol.
417 
418   @retval EFI_SUCCESS    The resulting array of handles was returned.
419   @retval Others         Other mistake case.
420 **/
421 EFI_STATUS
LocateHandle(IN EFI_LOCATE_SEARCH_TYPE SearchType,IN EFI_GUID * Protocol OPTIONAL,IN VOID * SearchKey OPTIONAL,IN OUT UINTN * NoHandles,OUT EFI_HANDLE ** Buffer)422 LocateHandle (
423   IN     EFI_LOCATE_SEARCH_TYPE    SearchType,
424   IN     EFI_GUID                  *Protocol  OPTIONAL,
425   IN     VOID                      *SearchKey OPTIONAL,
426   IN OUT UINTN                     *NoHandles,
427      OUT EFI_HANDLE                **Buffer
428   )
429 {
430   EFI_STATUS    Status;
431   UINTN         BufferSize;
432 
433   ASSERT (NoHandles != NULL);
434   ASSERT (Buffer != NULL);
435 
436   //
437   // Initialize for GrowBuffer loop.
438   //
439   Status      = EFI_SUCCESS;
440   *Buffer     = NULL;
441   BufferSize  = 50 * sizeof (EFI_HANDLE);
442 
443   //
444   // Call the real function.
445   //
446   while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {
447     Status = gBS->LocateHandle (
448                     SearchType,
449                     Protocol,
450                     SearchKey,
451                     &BufferSize,
452                     *Buffer
453                     );
454   }
455 
456   *NoHandles = BufferSize / sizeof (EFI_HANDLE);
457   if (EFI_ERROR (Status)) {
458     *NoHandles = 0;
459   }
460 
461   return Status;
462 }
463 
464 /**
465   Find the first instance of this protocol in the system and return its interface.
466 
467   @param[in]  ProtocolGuid    The guid of the protocol.
468   @param[out] Interface       The pointer to the first instance of the protocol.
469 
470   @retval EFI_SUCCESS    A protocol instance matching ProtocolGuid was found.
471   @retval Others         A protocol instance matching ProtocolGuid was not found.
472 **/
473 EFI_STATUS
LocateProtocol(IN EFI_GUID * ProtocolGuid,OUT VOID ** Interface)474 LocateProtocol (
475   IN  EFI_GUID    *ProtocolGuid,
476   OUT VOID        **Interface
477   )
478 
479 {
480   EFI_STATUS    Status;
481   UINTN         NumberHandles;
482   UINTN         Index;
483   EFI_HANDLE    *Handles;
484 
485   *Interface    = NULL;
486   Handles       = NULL;
487   NumberHandles = 0;
488 
489   Status        = LocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);
490   if (EFI_ERROR (Status)) {
491     DEBUG ((EFI_D_INFO, "LibLocateProtocol: Handle not found\n"));
492     return Status;
493   }
494 
495   for (Index = 0; Index < NumberHandles; Index++) {
496     ASSERT (Handles != NULL);
497     Status = gBS->HandleProtocol (
498                     Handles[Index],
499                     ProtocolGuid,
500                     Interface
501                     );
502 
503     if (!EFI_ERROR (Status)) {
504       break;
505     }
506   }
507 
508   if (Handles != NULL) {
509     FreePool (Handles);
510   }
511 
512   return Status;
513 }
514 
515 /**
516   Helper function called to check the conflicted flags.
517 
518   @param[in] CheckList       The pointer to the VAR_CHECK_ITEM table.
519   @param[in] ParamPackage    The pointer to the ParamPackage list.
520 
521   @retval EFI_SUCCESS              No conflicted flags.
522   @retval EFI_INVALID_PARAMETER    The input parameter is erroroneous or there are some conflicted flags.
523 **/
524 EFI_STATUS
IpSecConfigRetriveCheckListByName(IN VAR_CHECK_ITEM * CheckList,IN LIST_ENTRY * ParamPackage)525 IpSecConfigRetriveCheckListByName (
526   IN VAR_CHECK_ITEM    *CheckList,
527   IN LIST_ENTRY        *ParamPackage
528 )
529 {
530 
531   LIST_ENTRY        *Node;
532   VAR_CHECK_ITEM    *Item;
533   UINT32            Attribute1;
534   UINT32            Attribute2;
535   UINT32            Attribute3;
536   UINT32            Attribute4;
537   UINT32            Index;
538 
539   Attribute1 = 0;
540   Attribute2 = 0;
541   Attribute3 = 0;
542   Attribute4 = 0;
543   Index      = 0;
544   Item       = mIpSecConfigVarCheckList;
545 
546   if ((ParamPackage == NULL) || (CheckList == NULL)) {
547     return EFI_INVALID_PARAMETER;
548   }
549 
550   //
551   // Enumerate through the list of parameters that are input by user.
552   //
553   for (Node = GetFirstNode (ParamPackage); !IsNull (ParamPackage, Node); Node = GetNextNode (ParamPackage, Node)) {
554     if (((SHELL_PARAM_PACKAGE *) Node)->Name != NULL) {
555       //
556       // Enumerate the check list that defines the conflicted attributes of each flag.
557       //
558       for (; Item->VarName != NULL; Item++) {
559         if (StrCmp (((SHELL_PARAM_PACKAGE *) Node)->Name, Item->VarName) == 0) {
560           Index++;
561           if (Index == 1) {
562             Attribute1 = Item->Attribute1;
563             Attribute2 = Item->Attribute2;
564             Attribute3 = Item->Attribute3;
565             Attribute4 = Item->Attribute4;
566           } else {
567             Attribute1 &= Item->Attribute1;
568             Attribute2 |= Item->Attribute2;
569             Attribute3 &= Item->Attribute3;
570             Attribute4 |= Item->Attribute4;
571             if (Attribute1 != 0) {
572               return EFI_INVALID_PARAMETER;
573             }
574 
575             if (Attribute2 != 0) {
576               if ((Index == 2) && (StrCmp (Item->VarName, L"-p") == 0)) {
577                 continue;
578               }
579 
580               return EFI_INVALID_PARAMETER;
581             }
582 
583             if (Attribute3 == 0) {
584               return EFI_INVALID_PARAMETER;
585             }
586             if (((Attribute4 & 0xFF) == 0x03) || ((Attribute4 & 0xFF) == 0x0C) ||
587                 ((Attribute4 & 0xFF) == 0x30) || ((Attribute4 & 0xFF) == 0xC0)) {
588               return EFI_INVALID_PARAMETER;
589             }
590           }
591           break;
592         }
593       }
594 
595       Item = mIpSecConfigVarCheckList;
596     }
597   }
598 
599   return EFI_SUCCESS;
600 }
601 
602 /**
603   This is the declaration of an EFI image entry point. This entry point is
604   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
605   both device drivers and bus drivers.
606 
607   The entry point for IpSecConfig application that parse the command line input and call an IpSecConfig process.
608 
609   @param[in] ImageHandle    The image handle of this application.
610   @param[in] SystemTable    The pointer to the EFI System Table.
611 
612   @retval EFI_SUCCESS    The operation completed successfully.
613 
614 **/
615 EFI_STATUS
616 EFIAPI
InitializeIpSecConfig(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)617 InitializeIpSecConfig (
618   IN EFI_HANDLE          ImageHandle,
619   IN EFI_SYSTEM_TABLE    *SystemTable
620   )
621 {
622   EFI_STATUS                    Status;
623   EFI_IPSEC_CONFIG_DATA_TYPE    DataType;
624   UINT8                         Value;
625   LIST_ENTRY                    *ParamPackage;
626   CONST CHAR16                  *ValueStr;
627   CHAR16                        *ProblemParam;
628   UINTN                         NonOptionCount;
629   EFI_HII_PACKAGE_LIST_HEADER   *PackageList;
630 
631   //
632   // Retrieve HII package list from ImageHandle
633   //
634   Status = gBS->OpenProtocol (
635                   ImageHandle,
636                   &gEfiHiiPackageListProtocolGuid,
637                   (VOID **) &PackageList,
638                   ImageHandle,
639                   NULL,
640                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
641                   );
642   if (EFI_ERROR (Status)) {
643     return Status;
644   }
645 
646   //
647   // Publish HII package list to HII Database.
648   //
649   Status = gHiiDatabase->NewPackageList (
650                           gHiiDatabase,
651                           PackageList,
652                           NULL,
653                           &mHiiHandle
654                           );
655   if (EFI_ERROR (Status)) {
656     return Status;
657   }
658 
659   ASSERT (mHiiHandle != NULL);
660 
661   Status = ShellCommandLineParseEx (mIpSecConfigParamList, &ParamPackage, &ProblemParam, TRUE, FALSE);
662   if (EFI_ERROR (Status)) {
663     ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, ProblemParam);
664     goto Done;
665   }
666 
667   Status = IpSecConfigRetriveCheckListByName (mIpSecConfigVarCheckList, ParamPackage);
668   if (EFI_ERROR (Status)) {
669     ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_MISTAKEN_OPTIONS), mHiiHandle);
670     goto Done;
671   }
672 
673   Status = LocateProtocol (&gEfiIpSecConfigProtocolGuid, (VOID **) &mIpSecConfig);
674   if (EFI_ERROR (Status) || mIpSecConfig == NULL) {
675     ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName);
676     goto Done;
677   }
678 
679   Status = LocateProtocol (&gEfiIpSec2ProtocolGuid, (VOID **) &mIpSec);
680   if (EFI_ERROR (Status) || mIpSec == NULL) {
681     ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName);
682     goto Done;
683   }
684 
685   //
686   // Enable IPsec.
687   //
688   if (ShellCommandLineGetFlag (ParamPackage, L"-enable")) {
689     if (!(mIpSec->DisabledFlag)) {
690       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_ENABLE), mHiiHandle, mAppName);
691     } else {
692       //
693       // Set enable flag.
694       //
695       Value  = IPSEC_STATUS_ENABLED;
696       Status = gRT->SetVariable (
697                       IPSECCONFIG_STATUS_NAME,
698                       &gEfiIpSecConfigProtocolGuid,
699                       EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
700                       sizeof (Value),
701                       &Value
702                       );
703       if (!EFI_ERROR (Status)) {
704         mIpSec->DisabledFlag = FALSE;
705         ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_SUCCESS), mHiiHandle, mAppName);
706       } else {
707         ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_FAILED), mHiiHandle, mAppName);
708       }
709     }
710 
711     goto Done;
712   }
713 
714   //
715   // Disable IPsec.
716   //
717   if (ShellCommandLineGetFlag (ParamPackage, L"-disable")) {
718     if (mIpSec->DisabledFlag) {
719       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_DISABLE), mHiiHandle, mAppName);
720     } else {
721       //
722       // Set disable flag; however, leave it to be disabled in the callback function of DisabledEvent.
723       //
724       gBS->SignalEvent (mIpSec->DisabledEvent);
725       if (mIpSec->DisabledFlag) {
726         ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_SUCCESS), mHiiHandle, mAppName);
727       } else {
728         ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_FAILED), mHiiHandle, mAppName);
729       }
730     }
731 
732     goto Done;
733   }
734 
735   //
736   //IPsec Status.
737   //
738   if (ShellCommandLineGetFlag (ParamPackage, L"-status")) {
739     if (mIpSec->DisabledFlag) {
740       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_DISABLE), mHiiHandle, mAppName);
741     } else {
742       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_ENABLE), mHiiHandle, mAppName);
743     }
744     goto Done;
745   }
746 
747   //
748   // Try to get policy database type.
749   //
750   DataType = (EFI_IPSEC_CONFIG_DATA_TYPE) - 1;
751   ValueStr = ShellCommandLineGetValue (ParamPackage, L"-p");
752   if (ValueStr != NULL) {
753     DataType = (EFI_IPSEC_CONFIG_DATA_TYPE) MapStringToInteger (ValueStr, mMapPolicy);
754     if (DataType == -1) {
755       ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_DB), mHiiHandle, mAppName, ValueStr);
756       goto Done;
757     }
758   }
759 
760   NonOptionCount = ShellCommandLineGetCount (ParamPackage);
761   if ((NonOptionCount - 1) > 0) {
762     ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32) (NonOptionCount - 1));
763     ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_REDUNDANCY_MANY), mHiiHandle, mAppName, ValueStr);
764     goto Done;
765   }
766 
767   if (DataType == -1) {
768     ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_DB), mHiiHandle, mAppName);
769     goto Done;
770   }
771 
772   if (ShellCommandLineGetFlag (ParamPackage, L"-a")) {
773     Status = AddOrInsertPolicyEntry (DataType, ParamPackage);
774     if (EFI_ERROR (Status)) {
775       goto Done;
776     }
777   } else if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {
778     Status = AddOrInsertPolicyEntry (DataType, ParamPackage);
779     if (EFI_ERROR (Status)) {
780       goto Done;
781     }
782   } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {
783     Status = EditPolicyEntry (DataType, ParamPackage);
784     if (EFI_ERROR (Status)) {
785       goto Done;
786     }
787   } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {
788     Status = FlushOrDeletePolicyEntry (DataType, ParamPackage);
789     if (EFI_ERROR (Status)) {
790       goto Done;
791     }
792   } else if (ShellCommandLineGetFlag (ParamPackage, L"-f")) {
793     Status = FlushOrDeletePolicyEntry (DataType, ParamPackage);
794     if (EFI_ERROR (Status)) {
795       goto Done;
796     }
797   } else if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {
798     Status = ListPolicyEntry (DataType, ParamPackage);
799     if (EFI_ERROR (Status)) {
800       goto Done;
801     }
802   } else {
803     ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, mAppName);
804     goto Done;
805   }
806 
807 Done:
808   ShellCommandLineFreeVarList (ParamPackage);
809   HiiRemovePackages (mHiiHandle);
810 
811   return EFI_SUCCESS;
812 }
813