Home | History | Annotate | Download | only in IpsecConfig
      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 }
    813