]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/Application/IpsecConfig/IpSecConfig.c
NetworkPkg/IpsecConfig: remove module-local ARRAY_SIZE macro
[mirror_edk2.git] / NetworkPkg / Application / IpsecConfig / IpSecConfig.c
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
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
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
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
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
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 }