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