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