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