/** @file
The main process for IpSecConfig application.
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Library/UefiRuntimeServicesTableLib.h>
#include "IpSecConfig.h"
#include "Dump.h"
#include "Indexer.h"
#include "PolicyEntryOperation.h"
#include "Delete.h"
#include "Helper.h"
//
// Used for ShellCommandLineParseEx only
// and to ensure user inputs are in valid format
//
{ L"-p", TypeValue },
{ L"-a", TypeValue },
{ L"-i", TypeValue },
{ L"-e", TypeValue },
{ L"-d", TypeValue },
{ L"-f", TypeFlag },
{ L"-l", TypeFlag },
{ L"-enable", TypeFlag },
{ L"-disable", TypeFlag },
{ L"-status", TypeFlag },
{ L"-?", TypeFlag },
//
// SPD Selector
//
{ L"--local", TypeValue },
{ L"--remote", TypeValue },
{ L"--proto", TypeValue },
{ L"--local-port", TypeValue },
{ L"--remote-port", TypeValue },
{ L"--icmp-type", TypeValue },
{ L"--icmp-code", TypeValue },
//
// SPD Data
//
{ L"--name", TypeValue },
{ L"--packet-flag", TypeValue },
{ L"--action", TypeValue },
{ L"--lifebyte", TypeValue },
{ L"--lifetime-soft", TypeValue },
{ L"--lifetime", TypeValue },
{ L"--mode", TypeValue },
{ L"--tunnel-local", TypeValue },
{ L"--tunnel-remote", TypeValue },
{ L"--dont-fragment", TypeValue },
{ L"--ipsec-proto", TypeValue },
{ L"--auth-algo", TypeValue },
{ L"--encrypt-algo", TypeValue },
{ L"--ext-sequence", TypeFlag },
{ L"--sequence-overflow", TypeFlag },
{ L"--fragment-check", TypeFlag },
{ L"--ext-sequence-", TypeFlag },
{ L"--sequence-overflow-", TypeFlag },
{ L"--fragment-check-", TypeFlag },
//
// SA ID
// --ipsec-proto
//
{ L"--spi", TypeValue },
{ L"--tunnel-dest", TypeValue },
{ L"--tunnel-source", TypeValue },
{ L"--lookup-spi", TypeValue },
{ L"--lookup-ipsec-proto", TypeValue },
{ L"--lookup-dest", TypeValue },
//
// SA DATA
// --mode
// --auth-algo
// --encrypt-algo
//
{ L"--sequence-number", TypeValue },
{ L"--antireplay-window", TypeValue },
{ L"--auth-key", TypeValue },
{ L"--encrypt-key", TypeValue },
{ L"--path-mtu", TypeValue },
//
// PAD ID
//
{ L"--peer-id", TypeValue },
{ L"--peer-address", TypeValue },
{ L"--auth-proto", TypeValue },
{ L"--auth-method", TypeValue },
{ L"--ike-id", TypeValue },
{ L"--ike-id-", TypeValue },
{ L"--auth-data", TypeValue },
{ L"--revocation-data", TypeValue },
{ L"--lookup-peer-id", TypeValue },
{ L"--lookup-peer-address", TypeValue },
};
//
// -P
//
{ L"SPD", IPsecConfigDataTypeSpd },
{ L"SAD", IPsecConfigDataTypeSad },
{ L"PAD", IPsecConfigDataTypePad },
{ NULL, 0 },
};
//
// --proto
//
{ L"TCP", EFI_IP4_PROTO_TCP },
{ L"UDP", EFI_IP4_PROTO_UDP },
{ L"ICMP", EFI_IP4_PROTO_ICMP },
{ NULL, 0 },
};
//
// --action
//
{ L"Bypass", EfiIPsecActionBypass },
{ L"Discard", EfiIPsecActionDiscard },
{ L"Protect", EfiIPsecActionProtect },
{ NULL, 0 },
};
//
// --mode
//
{ L"Transport", EfiIPsecTransport },
{ L"Tunnel", EfiIPsecTunnel },
{ NULL, 0 },
};
//
// --dont-fragment
//
{ L"clear", EfiIPsecTunnelClearDf },
{ L"set", EfiIPsecTunnelSetDf },
{ L"copy", EfiIPsecTunnelCopyDf },
{ NULL, 0 },
};
//
// --ipsec-proto
//
{ L"AH", EfiIPsecAH },
{ L"ESP", EfiIPsecESP },
{ NULL, 0 },
};
//
// --auth-algo
//
{ L"NONE", IPSEC_AALG_NONE },
{ L"MD5HMAC", IPSEC_AALG_MD5HMAC },
{ L"SHA1HMAC", IPSEC_AALG_SHA1HMAC },
{ L"SHA2-256HMAC", IPSEC_AALG_SHA2_256HMAC },
{ L"SHA2-384HMAC", IPSEC_AALG_SHA2_384HMAC },
{ L"SHA2-512HMAC", IPSEC_AALG_SHA2_512HMAC },
{ L"AES-XCBC-MAC", IPSEC_AALG_AES_XCBC_MAC },
{ L"NULL", IPSEC_AALG_NULL },
{ NULL, 0 },
};
//
// --encrypt-algo
//
{ L"NONE", IPSEC_EALG_NONE },
{ L"DESCBC", IPSEC_EALG_DESCBC },
{ L"3DESCBC", IPSEC_EALG_3DESCBC },
{ L"CASTCBC", IPSEC_EALG_CASTCBC },
{ L"BLOWFISHCBC", IPSEC_EALG_BLOWFISHCBC },
{ L"NULL", IPSEC_EALG_NULL },
{ L"AESCBC", IPSEC_EALG_AESCBC },
{ L"AESCTR", IPSEC_EALG_AESCTR },
{ L"AES-CCM-ICV8", IPSEC_EALG_AES_CCM_ICV8 },
{ L"AES-CCM-ICV12",IPSEC_EALG_AES_CCM_ICV12 },
{ L"AES-CCM-ICV16",IPSEC_EALG_AES_CCM_ICV16 },
{ L"AES-GCM-ICV8", IPSEC_EALG_AES_GCM_ICV8 },
{ L"AES-GCM-ICV12",IPSEC_EALG_AES_GCM_ICV12 },
{ L"AES-GCM-ICV16",IPSEC_EALG_AES_GCM_ICV16 },
{ NULL, 0 },
};
//
// --auth-proto
//
{ L"IKEv1", EfiIPsecAuthProtocolIKEv1 },
{ L"IKEv2", EfiIPsecAuthProtocolIKEv2 },
{ NULL, 0 },
};
//
// --auth-method
//
{ L"PreSharedSecret", EfiIPsecAuthMethodPreSharedSecret },
{ L"Certificates", EfiIPsecAuthMethodCertificates },
{ NULL, 0 },
};
//
// Used for IpSecConfigRetriveCheckListByName only to check the validation of user input
//
//
// SPD Selector
//
//
// SPD Data
//
//
// SA ID
// --ipsec-proto
//
//
// SA DATA
// --mode
// --auth-algo
// --encrypt-algo
//
//
// The example to add a PAD:
// --auth-method PreSharedSeceret/Certificate --ike-id
// --auth-data 343343 --revocation-data 2342432"
// The example to delete a PAD:
// "-D * --lookup-peer-id Mike [--lookup-peer-address 10.23.2.2]"
// "-D 1"
// The example to edit a PAD:
// "-E * --lookup-peer-id Mike --auth-method Certificate"
//
// PAD ID
//
{ L"--auth-proto", 0, 0, BIT(0), 0 },
{ L"--auth-method", 0, 0, BIT(0), 0 },
{ L"--auth-data", 0, 0, BIT(0), 0 },
{ L"--revocation-data", 0, 0, BIT(0), 0 },
{ NULL, 0, 0, 0, 0 },
};
/**
The function to allocate the proper sized buffer for various
EFI interfaces.
@param[in, out] Status Current status.
@param[in, out] Buffer Current allocated buffer, or NULL.
@param[in] BufferSize Current buffer size needed
@retval TRUE If the buffer was reallocated and the caller should try the API again.
@retval FALSE If the buffer was not reallocated successfully.
**/
)
{
//
// If this is an initial request, buffer will be null with a new buffer size.
//
}
//
// If the status code is "buffer too small", resize the buffer.
//
if (*Status == EFI_BUFFER_TOO_SMALL) {
}
} else {
}
}
//
// If there's an error, free the buffer.
//
}
return TryAgain;
}
/**
Function returns an array of handles that support the requested protocol
in a buffer allocated from a pool.
@param[in] SearchType Specifies which handle(s) are to be returned.
@param[in] Protocol Provides the protocol to search by.
This parameter is only valid for SearchType ByProtocol.
@param[in] SearchKey Supplies the search key depending on the SearchType.
@param[in, out] NoHandles The number of handles returned in Buffer.
@param[out] Buffer A pointer to the buffer to return the requested array of
handles that support Protocol.
@retval EFI_SUCCESS The resulting array of handles was returned.
@retval Others Other mistake case.
**/
)
{
//
// Initialize for GrowBuffer loop.
//
//
// Call the real function.
//
);
}
*NoHandles = 0;
}
return Status;
}
/**
Find the first instance of this protocol in the system and return its interface.
@param[in] ProtocolGuid The guid of the protocol.
@param[out] Interface The pointer to the first instance of the protocol.
@retval EFI_SUCCESS A protocol instance matching ProtocolGuid was found.
@retval Others A protocol instance matching ProtocolGuid was not found.
**/
)
{
NumberHandles = 0;
return Status;
}
);
break;
}
}
}
return Status;
}
/**
Helper function called to check the conflicted flags.
@param[in] CheckList The pointer to the VAR_CHECK_ITEM table.
@param[in] ParamPackage The pointer to the ParamPackage list.
@retval EFI_SUCCESS No conflicted flags.
@retval EFI_INVALID_PARAMETER The input parameter is erroroneous or there are some conflicted flags.
**/
)
{
Attribute1 = 0;
Attribute2 = 0;
Attribute3 = 0;
Attribute4 = 0;
Index = 0;
return EFI_INVALID_PARAMETER;
}
//
// Enumerate through the list of parameters that are input by user.
//
for (Node = GetFirstNode (ParamPackage); !IsNull (ParamPackage, Node); Node = GetNextNode (ParamPackage, Node)) {
//
// Enumerate the check list that defines the conflicted attributes of each flag.
//
Index++;
if (Index == 1) {
} else {
if (Attribute1 != 0) {
return EFI_INVALID_PARAMETER;
}
if (Attribute2 != 0) {
continue;
}
return EFI_INVALID_PARAMETER;
}
if (Attribute3 == 0) {
return EFI_INVALID_PARAMETER;
}
return EFI_INVALID_PARAMETER;
}
}
break;
}
}
}
}
return EFI_SUCCESS;
}
/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
both device drivers and bus drivers.
The entry point for IpSecConfig application that parse the command line input and call an IpSecConfig process.
@param[in] ImageHandle The image handle of this application.
@param[in] SystemTable The pointer to the EFI System Table.
@retval EFI_SUCCESS The operation completed successfully.
**/
)
{
//
// Register our string package with HII and return the handle to it.
//
Status = ShellCommandLineParseEx (mIpSecConfigParamList, &ParamPackage, &ProblemParam, TRUE, FALSE);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, ProblemParam);
goto Done;
}
goto Done;
}
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName);
goto Done;
}
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName);
goto Done;
}
//
// Enable IPsec.
//
if (!(mIpSec->DisabledFlag)) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_ENABLE), mHiiHandle, mAppName);
} else {
//
// Set enable flag.
//
sizeof (Value),
);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_SUCCESS), mHiiHandle, mAppName);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_FAILED), mHiiHandle, mAppName);
}
}
goto Done;
}
//
// Disable IPsec.
//
if (mIpSec->DisabledFlag) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_DISABLE), mHiiHandle, mAppName);
} else {
//
// Set disable flag; however, leave it to be disabled in the callback function of DisabledEvent.
//
if (mIpSec->DisabledFlag) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_SUCCESS), mHiiHandle, mAppName);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_FAILED), mHiiHandle, mAppName);
}
}
goto Done;
}
//
//IPsec Status.
//
if (mIpSec->DisabledFlag) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_DISABLE), mHiiHandle, mAppName);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_ENABLE), mHiiHandle, mAppName);
}
goto Done;
}
//
// Try to get policy database type.
//
if (DataType == -1) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_DB), mHiiHandle, mAppName, ValueStr);
goto Done;
}
}
if (DataType == -1) {
goto Done;
}
switch (DataType) {
case IPsecConfigDataTypeSpd:
break;
case IPsecConfigDataTypeSad:
break;
case IPsecConfigDataTypePad:
break;
default:
break;
}
goto Done;
}
if ((NonOptionCount - 1) > 0) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_REDUNDANCY_MANY), mHiiHandle, mAppName, ValueStr);
goto Done;
}
if (DataType == -1) {
goto Done;
}
goto Done;
}
goto Done;
}
goto Done;
}
goto Done;
}
goto Done;
}
goto Done;
}
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, mAppName);
goto Done;
}
Done:
return EFI_SUCCESS;
}