2816 lines
82 KiB
C
2816 lines
82 KiB
C
/***********************************************************************
|
|
*
|
|
* Copyright (C) 2005-2006 Novell, Inc. Inc. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; version 2.1
|
|
* of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, Novell, Inc.
|
|
*
|
|
* To contact Novell about this file by physical or electronic mail,
|
|
* you may find current contact information at www.novell.com.
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include "sscs_ipc.h"
|
|
|
|
#define MAX_RECV_HEAD_LEN 6
|
|
#define WINDOWS_LOGIN_ID 1
|
|
|
|
// return codes
|
|
#define MAX_RETURN_CODE 21
|
|
int32_t static gReturnCodes[21] = {
|
|
NSSCS_SUCCESS, //SSCS_REPLY_SUCCESS 0
|
|
NSSCS_E_INVALID_PARAM, //SSCS_E_INVALID_MESSAGE -1
|
|
NSSCS_E_INCOMPATIBLE_VERSION, //SSCS_E_VERSION_NOT_SUPPORTED -2
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_SYSTEM_ERROR -3
|
|
NSSCS_E_SERVICE_NOT_SUPPORTED, //SSCS_E_REPLY_NOT_AVAILABLE -4
|
|
NSSCS_E_INVALID_SECRET_ID, // REQUIRES New
|
|
//SSCS_E_INVALID_KEYCHAIN -5
|
|
NSSCS_E_INVALID_SECRET_ID, //SSCS_E_INVALID_SECRETID -6
|
|
NSSCS_E_SECRET_ID_EXISTS, // REQUIRES NEW -//SSCS_E_KEYCHAIN_ALREADY_EXISTS -7
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_MAX_KEYCHAINS_REACHED -8
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_ADD_KEYCHAIN_FAILED -9
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_NO_KEYCHAINS_EXIST -10
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_KEYCHAIN_DOES_NOT_EXIST -11
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_REMOVE_KEYCHAIN_FAILED -12
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_WRITE_SECRET_FAILED -13
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_ADDING_DEFAULT_KEYCHAIN_FAILED -14
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_NO_SECRETS_EXIST -15
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_REMOVE_SECRET_FAILED -16
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_GET_SOCKET_PATH_FAILED -17
|
|
NSSCS_E_SYSTEM_FAILURE, //SSCS_E_CREATE_SOCKET_FAILED -18
|
|
NSSCS_E_INVALID_SECRET_ID, //SSCS_E_SECRETID_DOES_NOT_EXIST -19
|
|
NSSCS_E_INVALID_PARAM, //SSCS_E_INVALID_INPUT -20
|
|
};
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
Function - HexDump
|
|
Description - Dumps the information in Hex and Ascii. (16 Bytes per line).
|
|
Parameters
|
|
lpBuf (IN) - Data to be dumped.
|
|
iBytes (IN) - Number of bytes in lpBuf.
|
|
Returns - none
|
|
-----------------------------------------------------------------------------*/
|
|
#ifdef DEBUG
|
|
void HexDump(char *lpBuf, int iBytes)
|
|
{
|
|
char buffer[17];
|
|
int count,count1, ch;
|
|
|
|
printf("\n\n");
|
|
for(count = 0; count < iBytes; )
|
|
{
|
|
for(count1 = 0; count1 < 16;count1++)
|
|
{
|
|
ch = lpBuf[count++];
|
|
ch &= 0x000000FF;
|
|
printf("%02x ",ch);
|
|
if(!(count % 8))
|
|
printf("- ");
|
|
|
|
buffer[count1] = (ch > 0x20) ? ch : '.';
|
|
}
|
|
buffer[count1] = '\0';
|
|
printf(" %s\n",buffer);
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
/* Map the sscs returned return code to NDK error codes */
|
|
int32_t mapReturnCode(int32_t sscsCode)
|
|
{
|
|
sscsCode *= -1;
|
|
if(sscsCode < 0 || sscsCode > MAX_RETURN_CODE)
|
|
return NSSCS_E_SYSTEM_FAILURE;
|
|
return gReturnCodes[sscsCode];
|
|
}
|
|
|
|
/* Function name :
|
|
* Tokenize
|
|
* Arguments :
|
|
* tokenType - 0 for keychainids and 1 for secretids
|
|
* buffer - the buffer to be parsed
|
|
* idList - the list which needs to be filled with the tokens.
|
|
* Description:
|
|
* As Windows does not have strtok_r call, this function would
|
|
* abstract the tokenizing functionality.
|
|
* On Linux, this would call strtok_r, whereas on Windows
|
|
* strtok would be used.
|
|
*/
|
|
int Tokenize( int tokenType, char* buffer, void *idList )
|
|
{
|
|
int i = 0;
|
|
char *tok = NULL;
|
|
|
|
#ifdef SSCS_LINUX_PLAT_F
|
|
|
|
char *tmpPtr = NULL;
|
|
|
|
|
|
for (tok = strtok_r((char *)buffer,"*",&tmpPtr);
|
|
tok != NULL;
|
|
tok = strtok_r(NULL,"*",&tmpPtr))
|
|
{
|
|
if( 0 == tokenType )
|
|
{
|
|
sscs_Utf8Strcpy(((SSCS_KEYCHAIN_ID_T*)idList)[i].keychainID,tok);
|
|
((SSCS_KEYCHAIN_ID_T*)idList)[i].len = sscs_Utf8StrSize(tok);
|
|
}
|
|
else
|
|
{
|
|
sscs_Utf8Strcpy(((SSCS_SECRET_ID_T*)idList)[i].id,tok);
|
|
((SSCS_SECRET_ID_T*)idList)[i].len = sscs_Utf8StrSize(tok);
|
|
}
|
|
i++;
|
|
}
|
|
#endif
|
|
|
|
#ifdef SSCS_WIN32_PLAT_F
|
|
char seps[] = "*";
|
|
|
|
/* Establish string and get the first token: */
|
|
tok = strtok( (char *)buffer, seps );
|
|
while( tok != NULL )
|
|
{
|
|
/* While there are tokens in "string" */
|
|
if( 0 == tokenType )
|
|
{
|
|
sscs_Utf8Strcpy(((SSCS_KEYCHAIN_ID_T*)idList)[i].keychainID,tok);
|
|
((SSCS_KEYCHAIN_ID_T*)idList)[i].len = sscs_Utf8StrSize(tok);
|
|
}
|
|
else
|
|
{
|
|
sscs_Utf8Strcpy(((SSCS_SECRET_ID_T*)idList)[i].id,tok);
|
|
((SSCS_SECRET_ID_T*)idList)[i].len = sscs_Utf8StrSize(tok);
|
|
}
|
|
i++;
|
|
|
|
/* Get next token: */
|
|
tok = strtok( NULL, seps );
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
int32_t ipc_OpenSecretStore
|
|
(
|
|
void *secretStoreID,
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
SSCS_SECRETSTORE_T *ssID = (SSCS_SECRETSTORE_T *)secretStoreID;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t ssNameLen = 0;
|
|
uint32_t msgLen = 0;
|
|
uint32_t version = 0;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if( (NULL == ssHandle) || (NULL == ssHandle->platHandle) ||
|
|
(NULL == secretStoreID) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
*(int *)ssHandle->platHandle = IPC_CREATE();
|
|
if(*(int *)ssHandle->platHandle < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
ssNameLen = sscs_Utf8StrSize(ssID->ssName);
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_DWORD_LEN +
|
|
MSG_STRING_LEN +
|
|
ssNameLen;
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_CACHE_OPEN_SECRET_STORE_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
|
|
memcpy(pReq,&ssID->version,MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
|
|
memcpy(pReq,&ssNameLen,MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
|
|
memcpy(pReq,ssID->ssName,ssNameLen);
|
|
pReq += ssNameLen;
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,(char *)gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
DMSG(("Write failed : %s\n",strerror(errno)));
|
|
DMSG(("Closing socket : %d\n",*(int*)ssHandle->platHandle));
|
|
DMSG(("ipc_OpenSecretStore:IPC_WRITE returned :%d\n",retVal));
|
|
IPC_CLOSE(*(int *)ssHandle->platHandle);
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
//HexDump(gpReqBuf, msgLen);
|
|
#endif
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_OPENSS);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
DMSG(("ipc_OpenSecretStore:read returned :%d\n",retVal));
|
|
DMSG(("Read failed : %s\n",strerror(errno)));
|
|
DMSG(("Closing socket : %d\n",*(int*)ssHandle->platHandle));
|
|
|
|
IPC_CLOSE(*(int *)ssHandle->platHandle);
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&version, pReply, MSG_DWORD_LEN);
|
|
pReply += MSG_DWORD_LEN;
|
|
// Check for version here.
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
|
|
if(sockReturn != SSCS_REPLY_SUCCESS)
|
|
{
|
|
DMSG(("ipc_OpenSecretStore:sscs returned :%d\n",sockReturn));
|
|
DMSG(("Closing socket : %d\n",*(int*)ssHandle->platHandle));
|
|
IPC_CLOSE(*(int *)ssHandle->platHandle);
|
|
retCode = mapReturnCode(sockReturn);
|
|
break;
|
|
}
|
|
}while(0);
|
|
|
|
return retCode; // map the return code from sockReturn
|
|
}
|
|
|
|
int32_t ipc_CloseSecretStore
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
uint32_t ssFlags
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t msgLen = 0;
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN + MSG_DWORD_LEN;
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_CACHE_CLOSE_SECRET_STORE_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
|
|
//marshall ssflags
|
|
memcpy(pReq, &ssFlags, MSG_DWORD_LEN);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
retVal = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
DMSG(("Closing socket : %d\n",*(int*)ssHandle->platHandle));
|
|
IPC_CLOSE(*(int *)ssHandle->platHandle);
|
|
return retCode; // map return code
|
|
}
|
|
|
|
int32_t ipc_RemoveSecretStore
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t msgLen = 0;
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN;
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_CACHE_REMOVE_SECRET_STORE_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
return retCode;
|
|
|
|
}
|
|
|
|
|
|
int32_t ipc_EnumerateKeychainIDs
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_KEYCHAIN_ID_LIST_T *kcIDList
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
SS_UTF8_T nulc = '\0';
|
|
SS_UTF8_T delimiter = '*';
|
|
int i = 0,j = 0;
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t msgLen = 0;
|
|
uint32_t bufLen = 0;
|
|
uint32_t numIds = 0;
|
|
|
|
SS_UTF8_T *tmpBuf = NULL;
|
|
SS_UTF8_T *tmpPtr = NULL;
|
|
SS_UTF8_T *tok = NULL;
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if( (NULL == ssHandle) || (NULL == ssHandle->platHandle) ||
|
|
(NULL == kcIDList) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN;
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_CACHE_ENUMERATE_KEYCHAINIDS_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
memset(pReply,0,MIN_REPLY_BUF_LEN);
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
// I would like to get return code here itself
|
|
// so that I need not check for other things.
|
|
memcpy(&bufLen,pReply, MSG_DWORD_LEN);
|
|
if( 0 == bufLen )
|
|
{
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
DMSG(("Reading retcode::%d\n",retVal));
|
|
}
|
|
retCode = mapReturnCode(sockReturn);
|
|
kcIDList->returnedIDs = 0;
|
|
break;
|
|
}
|
|
// Let me check if the global buffer is sufficient
|
|
if( bufLen < MIN_REPLY_BUF_LEN/(sizeof(char)) )
|
|
pReply = gpReplyBuf;
|
|
else
|
|
{
|
|
pReply = (Byte *)malloc( (bufLen+1) * sizeof(char));
|
|
if( NULL == pReply )
|
|
{
|
|
// Cleanup the channel by reading the remaining and return error.
|
|
int n;
|
|
n = msgLen - MSG_REPLY_GENERAL;
|
|
while(n)
|
|
{
|
|
int bytes = IPC_READ(*(int *)ssHandle->platHandle, gpReplyBuf, MIN_REPLY_BUF_LEN);
|
|
if( bytes > 0 )
|
|
n -= MIN_REPLY_BUF_LEN;
|
|
else
|
|
break;
|
|
}
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,
|
|
&sockReturn, MSG_DWORD_LEN);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
DMSG(("Reading retcode::%d\n",retVal));
|
|
}
|
|
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
} //if malloc fail loop ends here
|
|
else
|
|
tmpBuf = (SS_UTF8_T *)pReply; // Save this ptr to free later.
|
|
}
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,pReply, bufLen*sizeof(char));
|
|
|
|
tmpPtr = (SS_UTF8_T *)pReply;
|
|
tmpPtr[bufLen] = nulc;
|
|
#ifdef DEBUG
|
|
//HexDump(pReply, retVal);
|
|
#endif
|
|
// Count number of ids
|
|
numIds = 1; // Atleast there is one !!
|
|
while( tmpPtr = sscs_Utf8Strchr(tmpPtr, delimiter) )
|
|
{
|
|
numIds++;
|
|
tmpPtr++;
|
|
}
|
|
if( numIds > kcIDList->returnedIDs )
|
|
{
|
|
kcIDList->returnedIDs = numIds;
|
|
if(tmpBuf)
|
|
{
|
|
free(tmpBuf);
|
|
tmpBuf = NULL;
|
|
}
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
kcIDList->enumHandle = 0;
|
|
|
|
retCode = NSSS_E_ENUM_BUFF_TOO_SHORT;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Tokenize( 0, (SS_UTF8_T*)pReply, kcIDList->keyChainIDList );
|
|
kcIDList->returnedIDs = numIds;
|
|
kcIDList->enumHandle = 0;
|
|
if(tmpBuf)
|
|
{
|
|
free(tmpBuf);
|
|
tmpBuf = NULL;
|
|
}
|
|
}
|
|
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
DMSG(("Reading retcode::%d\n",retVal));
|
|
|
|
}
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
return retCode;
|
|
}
|
|
|
|
|
|
int32_t ipc_AddKeychain
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
uint32_t ssFlags,
|
|
SSCS_KEYCHAIN_ID_T *keychainID
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if( (NULL == ssHandle) || (NULL == ssHandle->platHandle) ||
|
|
(NULL == keychainID) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
keychainIDLen = keychainID->len;
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_DWORD_LEN + // flags
|
|
MSG_STRING_LEN +
|
|
keychainIDLen; // Keychain ID
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_CACHE_ADD_KEYCHAIN_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &ssFlags, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
|
|
memcpy((SS_UTF8_T*)pReq,keychainID->keychainID,keychainIDLen);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
return retCode;
|
|
}
|
|
|
|
int32_t ipc_RemoveKeychain
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_KEYCHAIN_ID_T *keychainID
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if( (NULL == ssHandle) || (NULL == ssHandle->platHandle) ||
|
|
(NULL == keychainID) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
keychainIDLen = keychainID->len;
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN +
|
|
keychainIDLen; // Keychain ID
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_CACHE_REMOVE_KEYCHAIN_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID, keychainIDLen);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
} while(0);
|
|
|
|
return retCode;
|
|
}
|
|
|
|
|
|
int32_t ipc_EnumerateSecretIDs
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_LIST_T *secretIDList
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
SS_UTF8_T nulc = '\0';
|
|
SS_UTF8_T delimiter = '*';
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
uint32_t bufLen = 0;
|
|
uint32_t numIds = 0;
|
|
|
|
int i = 0;
|
|
|
|
SS_UTF8_T *tmpBuf = NULL;
|
|
SS_UTF8_T *tmpPtr = NULL;
|
|
SS_UTF8_T *tok = NULL;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if( (NULL == ssHandle) || (NULL == ssHandle->platHandle) ||
|
|
(NULL == keychainID) || (NULL == secretIDList) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
keychainIDLen = keychainID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN +
|
|
keychainIDLen; // Keychain ID
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_CACHE_ENUMERATE_SECRETIDS_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy((SS_UTF8_T *)pReq,(SS_UTF8_T *)keychainID->keychainID,keychainIDLen);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if( retVal < 0 )
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
// I would like to get return code here itself
|
|
// so that I need not check for other things.
|
|
memcpy(&bufLen,pReply, MSG_DWORD_LEN);
|
|
if( 0 == bufLen )
|
|
{
|
|
// Cleanup the channel by reading the return code.
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
secretIDList->returnedIDs = 0;
|
|
retCode = mapReturnCode(sockReturn);
|
|
break;
|
|
}
|
|
// Let me check if the global buffer is sufficient
|
|
if(bufLen < MIN_REPLY_BUF_LEN/(sizeof(SS_UTF8_T)))
|
|
pReply = gpReplyBuf;
|
|
else
|
|
{
|
|
pReply = (Byte *)malloc( (bufLen+1) * sizeof(SS_UTF8_T));
|
|
if(pReply == NULL)
|
|
{
|
|
// Cleanup the channel by reading the remaining and return error.
|
|
int n;
|
|
n = msgLen - MSG_REPLY_GENERAL;
|
|
while(n)
|
|
{
|
|
int bytes = IPC_READ((*(int *)ssHandle->platHandle), gpReplyBuf, MIN_REPLY_BUF_LEN);
|
|
if(bytes > 0 )
|
|
n -= MIN_REPLY_BUF_LEN;
|
|
else
|
|
break;
|
|
}
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,
|
|
&sockReturn, MSG_DWORD_LEN);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
DMSG(("Reading retcode::%d\n",retVal));
|
|
|
|
}
|
|
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
else
|
|
tmpBuf = (SS_UTF8_T *)pReply; // Save this ptr to free later.
|
|
}
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,pReply, bufLen*sizeof(SS_UTF8_T));
|
|
DMSG(("Read returns..%d\n",retVal));
|
|
tmpPtr = (SS_UTF8_T *)pReply;
|
|
tmpPtr[bufLen] = nulc;
|
|
DMSG(("Secretid list is %s\n", pReply));
|
|
|
|
// Count number of ids
|
|
numIds = 1; // Atleast there is one !!
|
|
while(tmpPtr = sscs_Utf8Strchr(tmpPtr, delimiter))
|
|
{
|
|
numIds++;
|
|
tmpPtr++;
|
|
}
|
|
if( numIds > secretIDList->returnedIDs )
|
|
{
|
|
secretIDList->returnedIDs = numIds;
|
|
if(tmpBuf)
|
|
{
|
|
free(tmpBuf);
|
|
tmpBuf = NULL;
|
|
}
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
secretIDList->enumHandle = 0;
|
|
retCode = NSSS_E_ENUM_BUFF_TOO_SHORT;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Tokenize( 1, (SS_UTF8_T*)pReply, secretIDList->secIDList );
|
|
secretIDList->returnedIDs = numIds;
|
|
secretIDList->enumHandle = 0;
|
|
if(tmpBuf)
|
|
{
|
|
free(tmpBuf);
|
|
tmpBuf = NULL;
|
|
}
|
|
}
|
|
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
DMSG(("Reading retcode::%d\n",retVal));
|
|
}
|
|
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
return retCode;
|
|
}
|
|
|
|
int32_t ipc_ReadSecret
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_T *secretID,
|
|
SSCS_SECRET_T *secretData,
|
|
SSCS_PASSWORD_T *epPassword,
|
|
uint32_t *bytesRequired
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
uint32_t dataLen = 0;
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t secretIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
SSCS_PASSWORD_T myPassword = {0,0,""};
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle) || (NULL == keychainID) || (NULL == secretID) || (NULL == secretData) || (NULL == bytesRequired))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
|
|
keychainIDLen = keychainID->len;
|
|
secretIDLen = secretID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS ||
|
|
secretIDLen > NSSS_MAX_SECRET_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
// epPassword is optional. So, the code should not break.
|
|
if( NULL == epPassword )
|
|
epPassword = &myPassword;
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN + // KeychainID length
|
|
keychainIDLen + // Keychain ID
|
|
MSG_STRING_LEN + // SecretID length
|
|
secretIDLen + // SecretID
|
|
MSG_STRING_LEN + // epPassword len
|
|
epPassword->pwordLen;
|
|
|
|
pReq = gpReqBuf;
|
|
msgid = REQ_CACHE_READ_SECRET_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID,keychainIDLen);
|
|
pReq += keychainIDLen ;
|
|
memcpy(pReq, &secretIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretID->id, secretIDLen);
|
|
pReq += secretIDLen;
|
|
memcpy(pReq, &(epPassword->pwordLen), MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, epPassword->pword, epPassword->pwordLen);
|
|
pReq += epPassword->pwordLen;
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if( 0 == retVal )
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&dataLen,pReply, MSG_DWORD_LEN);
|
|
if( 0 == dataLen )
|
|
{
|
|
// Cleanup the channel by reading the return code.
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
if( retVal < 0 )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
secretData->len = dataLen;
|
|
retCode = mapReturnCode(sockReturn);
|
|
break;
|
|
}
|
|
// Let me check if the buffer passed by application is big enough
|
|
if(dataLen <= (uint32_t)secretData->len)
|
|
{
|
|
// Read the secret into application buffer.
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, secretData->data, dataLen);
|
|
if( retVal < 0 )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
secretData->len = dataLen;
|
|
}
|
|
else
|
|
{
|
|
//buffer allocated by application is not sufficient to hold the data.
|
|
*bytesRequired = dataLen;
|
|
{
|
|
// Cleanup the channel by reading the remaining and return error.
|
|
int n;
|
|
n = dataLen;
|
|
while(n)
|
|
{
|
|
int bytes = IPC_READ(*(int *)ssHandle->platHandle, gpReplyBuf, MIN_REPLY_BUF_LEN);
|
|
if( bytes > 0)
|
|
n -= MIN_REPLY_BUF_LEN;
|
|
else
|
|
break;
|
|
}
|
|
// Read the sscs return code also.
|
|
IPC_READ(*(int *)ssHandle->platHandle, (Byte *) &sockReturn, MSG_DWORD_LEN);
|
|
retCode = NSSCS_E_ENUM_BUFF_TOO_SHORT;
|
|
break;
|
|
}
|
|
}
|
|
// Read the sscs return code also.
|
|
IPC_READ(*(int *)ssHandle->platHandle, (Byte *) &sockReturn, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
} while(0);
|
|
return retCode;
|
|
}
|
|
|
|
int ipc_WriteSecret
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
uint32_t ssFlags,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_T *secretID,
|
|
SSCS_SECRET_T *secretData,
|
|
SSCS_PASSWORD_T *epPassword,
|
|
SSCS_EXT_T *ext
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
Byte *tmpBuf = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t secretIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
uint32_t extID = 0;
|
|
uint32_t luidLen = 0;
|
|
|
|
|
|
SSCS_PASSWORD_T myPassword = {0,0,""};
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle) || (NULL == keychainID) || (NULL == secretID) ||(NULL == secretData))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
|
|
keychainIDLen = keychainID->len;
|
|
secretIDLen = secretID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS ||
|
|
secretIDLen > NSSS_MAX_SECRET_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
// epPassword is optional. So, the code should not break.
|
|
if(epPassword == NULL)
|
|
epPassword = &myPassword;
|
|
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN + // KeychainID length
|
|
keychainIDLen + // Keychain ID
|
|
MSG_STRING_LEN + // SecretID length
|
|
secretIDLen + // SecretID
|
|
MSG_STRING_LEN + // Secret Value Length
|
|
secretData->len +
|
|
MSG_STRING_LEN + // epPassword len
|
|
epPassword->pwordLen;
|
|
|
|
// is there an ext
|
|
if (ext)
|
|
{
|
|
// The login capture on Windows determines the LUID of the user
|
|
// and sends it as an Extension, marshall it across the pipe
|
|
// see the WriteSecret verb for handling it.
|
|
if (ext->extID == WINDOWS_LOGIN_ID)
|
|
{
|
|
// 4 byte ext type, 4 byte len and 8 bytes of LUID
|
|
msgLen += MSG_DWORD_LEN + MSG_DWORD_LEN + WINDOWS_LUID_LEN;
|
|
// as setup in the capture module
|
|
//ext.extID = WINDOWS_LOGON_ID;
|
|
//ext.version = 0x00010000; // 1.0.0
|
|
//ext.ext = (void *)lpLogonId;
|
|
// _LUID { DWORD LowPart; LONG HighPart; // 8 byte
|
|
}
|
|
else
|
|
msgLen += MSG_DWORD_LEN;
|
|
}
|
|
else
|
|
{
|
|
// the cache daemon expects a ext, add it here
|
|
msgLen += MSG_DWORD_LEN;
|
|
}
|
|
|
|
if( msgLen > MIN_REQUEST_BUF_LEN )
|
|
{
|
|
tmpBuf = (Byte*)malloc(msgLen);
|
|
if( NULL == tmpBuf )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
memset(tmpBuf,0,msgLen);
|
|
pReq = tmpBuf;
|
|
}
|
|
else
|
|
{
|
|
pReq = gpReqBuf;
|
|
}
|
|
|
|
msgid = REQ_CACHE_WRITE_SECRET_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID,keychainIDLen );
|
|
pReq += keychainIDLen;
|
|
memcpy(pReq, &secretIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretID->id,secretIDLen);
|
|
pReq += secretIDLen;
|
|
memcpy(pReq, &(secretData->len), MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretData->data, secretData->len);
|
|
pReq += secretData->len;
|
|
memcpy(pReq, &(epPassword->pwordLen), MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, epPassword->pword, epPassword->pwordLen);
|
|
pReq += epPassword->pwordLen;
|
|
|
|
// marshall the extension if there is one
|
|
if (ext)
|
|
{
|
|
if (ext->extID == WINDOWS_LOGIN_ID)
|
|
{
|
|
extID = EXT_TYPE_WINDOWS_LUID;
|
|
memcpy(pReq, &extID, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
|
|
luidLen = WINDOWS_LUID_LEN;
|
|
memcpy(pReq, &luidLen, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
|
|
memcpy(pReq, ext->ext, 8);
|
|
pReq += 8;
|
|
}
|
|
else
|
|
{
|
|
uint32_t extID = 0;
|
|
memcpy(pReq,&extID,MSG_DWORD_LEN);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uint32_t extID = 0;
|
|
memcpy(pReq,&extID,MSG_DWORD_LEN);
|
|
}
|
|
|
|
if(tmpBuf != NULL)
|
|
{
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,tmpBuf,msgLen);
|
|
}
|
|
else
|
|
{
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,gpReqBuf, msgLen);
|
|
}
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
if( tmpBuf != NULL )
|
|
{
|
|
free(tmpBuf);
|
|
tmpBuf = NULL;
|
|
}
|
|
return retCode;
|
|
}
|
|
|
|
int32_t ipc_RemoveSecret
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_T *secretID,
|
|
SSCS_PASSWORD_T *epPassword
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t secretIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if( (NULL == ssHandle) || (NULL == ssHandle->platHandle) ||
|
|
(NULL == keychainID) || (NULL == secretID) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
keychainIDLen = keychainID->len;
|
|
secretIDLen = secretID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS ||
|
|
secretIDLen > NSSS_MAX_SECRET_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN + // KeychainID length
|
|
keychainIDLen + // Keychain ID
|
|
MSG_STRING_LEN + // SecretID length
|
|
secretIDLen + // SecretID
|
|
MSG_STRING_LEN ; // epPassword len
|
|
if( epPassword )
|
|
{
|
|
msgLen += epPassword->pwordLen;
|
|
}
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_CACHE_REMOVE_SECRET_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID, keychainIDLen);
|
|
pReq += keychainIDLen;
|
|
memcpy(pReq, &secretIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretID->id, secretIDLen);
|
|
pReq += secretIDLen;
|
|
|
|
if(epPassword)
|
|
{
|
|
memcpy(pReq, &(epPassword->pwordLen), MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, epPassword->pword, epPassword->pwordLen);
|
|
pReq += epPassword->pwordLen;
|
|
}
|
|
else
|
|
{
|
|
int pwordlen = 0;
|
|
memcpy(pReq, &pwordlen, MSG_STRING_LEN);
|
|
}
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
return retCode;
|
|
}
|
|
|
|
int32_t ipc_GetSecretStoreInfo
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_SECRETSTORE_INFO_T *ssInfo
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t msgLen = 0;
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
if( NULL == ssInfo )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN;
|
|
|
|
if( msgLen > MIN_REQUEST_BUF_LEN )
|
|
{
|
|
//Allocate more memory for gpReqBuf
|
|
}
|
|
pReq = gpReqBuf;
|
|
msgid = REQ_GET_SECRETSTORE_INFO_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = SSCS_E_SYSTEM_ERROR;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply,
|
|
MSG_REPLY_GETSSINFO);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = SSCS_E_SYSTEM_ERROR;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&(ssInfo->numKeyChains),pReply,MSG_DWORD_LEN);
|
|
pReply += MSG_DWORD_LEN;
|
|
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
|
|
if(sockReturn != SSCS_REPLY_SUCCESS)
|
|
{
|
|
DMSG(("Ret code :%d\n",sockReturn));
|
|
}
|
|
retCode = sockReturn;
|
|
}while(0);
|
|
|
|
return retCode; // map return code
|
|
}
|
|
|
|
int32_t ipc_GetKeychainInfo
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_KEYCHAIN_INFO_T *kcInfo
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t msgLen = 0;
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
if( (NULL == keychainID) || (NULL == kcInfo) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN + MSG_DWORD_LEN +
|
|
(keychainID->len );
|
|
|
|
if( msgLen > MIN_REQUEST_BUF_LEN )
|
|
{
|
|
//Allocate more memory for gpReqBuf
|
|
}
|
|
pReq = gpReqBuf;
|
|
msgid = REQ_GET_KEYCHAIN_INFO_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq,&(keychainID->len),MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq,keychainID->keychainID,keychainID->len);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply,MSG_REPLY_GETKEYCHAIN_INFO);
|
|
if(retVal < 0)
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&(kcInfo->flags),pReply,MSG_DWORD_LEN);
|
|
pReply += MSG_DWORD_LEN;
|
|
memcpy(&(kcInfo->numSecrets),pReply,MSG_DWORD_LEN);
|
|
pReply += MSG_DWORD_LEN;
|
|
memcpy(&(kcInfo->numOfDeletedSecs),pReply,MSG_DWORD_LEN);
|
|
pReply += MSG_DWORD_LEN;
|
|
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
|
|
if(sockReturn != SSCS_REPLY_SUCCESS)
|
|
{
|
|
DMSG(("Ret code :%d\n",sockReturn));
|
|
}
|
|
retCode = sockReturn;
|
|
|
|
}while(0);
|
|
|
|
return retCode;
|
|
|
|
}
|
|
|
|
int32_t ipc_LockCache
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN;
|
|
|
|
pReq = gpReqBuf;
|
|
msgid = REQ_LOCK_CACHE_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL)
|
|
;
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
|
|
if(sockReturn != SSCS_REPLY_SUCCESS)
|
|
{
|
|
DMSG(("Ret code :%d\n",sockReturn));
|
|
}
|
|
retCode = sockReturn;
|
|
|
|
}while(0);
|
|
return retCode; // map return code
|
|
|
|
}
|
|
|
|
int32_t ipc_UnlockCache
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_PASSCODE_T *passcode
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN;
|
|
|
|
pReq = gpReqBuf;
|
|
msgid = REQ_UNLOCK_CACHE_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
// log debug info here
|
|
retCode = SSCS_E_SYSTEM_ERROR;
|
|
break;
|
|
}
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = SSCS_E_SYSTEM_ERROR;
|
|
break;
|
|
}
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
|
|
if(sockReturn != SSCS_REPLY_SUCCESS)
|
|
{
|
|
DMSG(("Ret code :%d\n",sockReturn));
|
|
}
|
|
retCode = sockReturn;
|
|
|
|
}while(0);
|
|
|
|
return retCode; // map return code
|
|
|
|
}
|
|
|
|
int32_t ipc_SetMasterPasscode
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_PASSCODE_T *passcode
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t passcodeType = 0;
|
|
uint32_t passcodeLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if( (NULL == ssHandle) || (NULL == ssHandle->platHandle) ||
|
|
(NULL == passcode) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
passcodeType = passcode->passcodeType;
|
|
passcodeLen = ((SSCS_PASSWORD_T*)(passcode->passcodeHandle))->pwordLen;
|
|
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_DWORD_LEN + // passcodetype
|
|
MSG_STRING_LEN + //passcodeLen
|
|
passcodeLen;
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_SET_MASTER_PASSCODE;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &passcodeType, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
memcpy(pReq, &passcodeLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
|
|
memcpy((SS_UTF8_T*)pReq,((SSCS_PASSWORD_T*)(passcode->passcodeHandle))->pword,passcodeLen);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = sockReturn;
|
|
|
|
}while(0);
|
|
|
|
return retCode;
|
|
}
|
|
|
|
int32_t ipc_ReadKey
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_T *secretID,
|
|
SS_UTF8_T *key,
|
|
uint32_t keyLen,
|
|
uint8_t *val,
|
|
uint32_t *valLen,
|
|
SSCS_PASSWORD_T *epPassword,
|
|
uint32_t *bytesRequired
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
uint32_t dataLen = 0;
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t secretIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
SSCS_PASSWORD_T myPassword = {0,0,""};
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle) || (NULL == keychainID) || (NULL == secretID) || (NULL == bytesRequired))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
|
|
keychainIDLen = keychainID->len;
|
|
secretIDLen = secretID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS ||
|
|
secretIDLen > NSSS_MAX_SECRET_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
// epPassword is optional. So, the code should not break.
|
|
if( NULL == epPassword )
|
|
epPassword = &myPassword;
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN + // KeychainID length
|
|
keychainIDLen + // Keychain ID
|
|
MSG_STRING_LEN + // SecretID length
|
|
secretIDLen + // SecretID
|
|
MSG_STRING_LEN + //keyLen
|
|
keyLen + //key
|
|
MSG_STRING_LEN + // epPassword len
|
|
epPassword->pwordLen;
|
|
|
|
pReq = gpReqBuf;
|
|
msgid = REQ_READ_KEY_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID,keychainIDLen);
|
|
pReq += keychainIDLen ;
|
|
memcpy(pReq, &secretIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretID->id, secretIDLen);
|
|
pReq += secretIDLen;
|
|
|
|
memcpy(pReq, &keyLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, key, keyLen);
|
|
pReq += keyLen;
|
|
|
|
memcpy(pReq, &(epPassword->pwordLen), MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, epPassword->pword, epPassword->pwordLen);
|
|
pReq += epPassword->pwordLen;
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if( 0 == retVal )
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&dataLen,pReply, MSG_DWORD_LEN);
|
|
if( 0 == dataLen )
|
|
{
|
|
// Cleanup the channel by reading the return code.
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
if( retVal < 0 )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
retCode = mapReturnCode(sockReturn);
|
|
break;
|
|
}
|
|
// Let me check if the buffer passed by application is big enough
|
|
if(dataLen <= *valLen)
|
|
{
|
|
// Read the secret into application buffer.
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, val, dataLen);
|
|
if( retVal < 0 )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
// set the length of the data
|
|
*valLen = dataLen;
|
|
|
|
}
|
|
else
|
|
{
|
|
//buffer allocated by application is not sufficient to hold the data.
|
|
*bytesRequired = dataLen;
|
|
{
|
|
// Cleanup the channel by reading the remaining and return error.
|
|
int n;
|
|
n = dataLen;
|
|
while(n)
|
|
{
|
|
int bytes = IPC_READ(*(int *)ssHandle->platHandle, gpReplyBuf, MIN_REPLY_BUF_LEN);
|
|
if( bytes > 0)
|
|
n -= MIN_REPLY_BUF_LEN;
|
|
else
|
|
break;
|
|
}
|
|
// Read the sscs return code also.
|
|
IPC_READ(*(int *)ssHandle->platHandle, (Byte *) &sockReturn, MSG_DWORD_LEN);
|
|
retCode = NSSCS_E_ENUM_BUFF_TOO_SHORT;
|
|
break;
|
|
}
|
|
}
|
|
// Read the sscs return code also.
|
|
IPC_READ(*(int *)ssHandle->platHandle, (Byte *) &sockReturn, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
} while(0);
|
|
return retCode;
|
|
}
|
|
|
|
int32_t ipc_ReadBinaryKey
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_T *secretID,
|
|
SS_UTF8_T *key,
|
|
uint32_t keyLen,
|
|
uint8_t *val,
|
|
uint32_t *valLen,
|
|
SSCS_PASSWORD_T *epPassword,
|
|
uint32_t *bytesRequired
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
uint32_t dataLen = 0;
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t secretIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
SSCS_PASSWORD_T myPassword = {0,0,""};
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle) || (NULL == keychainID) || (NULL == secretID) || (NULL == bytesRequired))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
keychainIDLen = keychainID->len;
|
|
secretIDLen = secretID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS ||
|
|
secretIDLen > NSSS_MAX_SECRET_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
// epPassword is optional. So, the code should not break.
|
|
if( NULL == epPassword )
|
|
epPassword = &myPassword;
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN + // KeychainID length
|
|
keychainIDLen + // Keychain ID
|
|
MSG_STRING_LEN + // SecretID length
|
|
secretIDLen + // SecretID
|
|
MSG_STRING_LEN + //keyLen
|
|
keyLen + //key
|
|
MSG_STRING_LEN + // epPassword len
|
|
epPassword->pwordLen;
|
|
|
|
pReq = gpReqBuf;
|
|
msgid = REQ_READ_BINARY_KEY_MSGID;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID,keychainIDLen);
|
|
pReq += keychainIDLen ;
|
|
memcpy(pReq, &secretIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretID->id, secretIDLen);
|
|
pReq += secretIDLen;
|
|
|
|
memcpy(pReq, &keyLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, key, keyLen);
|
|
pReq += keyLen;
|
|
|
|
memcpy(pReq, &(epPassword->pwordLen), MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, epPassword->pword, epPassword->pwordLen);
|
|
pReq += epPassword->pwordLen;
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if( 0 == retVal )
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&dataLen,pReply, MSG_DWORD_LEN);
|
|
if( 0 == dataLen )
|
|
{
|
|
// Cleanup the channel by reading the return code.
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle,&sockReturn, MSG_DWORD_LEN);
|
|
if( retVal < 0 )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
retCode = mapReturnCode(sockReturn);
|
|
break;
|
|
}
|
|
// Let me check if the buffer passed by application is big enough
|
|
if(dataLen <= *valLen)
|
|
{
|
|
// Read the secret into application buffer.
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, val, dataLen);
|
|
if( retVal < 0 )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
*valLen = dataLen;
|
|
|
|
}
|
|
else
|
|
{
|
|
//buffer allocated by application is not sufficient to hold the data.
|
|
*bytesRequired = dataLen;
|
|
{
|
|
// Cleanup the channel by reading the remaining and return error.
|
|
int n;
|
|
n = dataLen;
|
|
while(n)
|
|
{
|
|
int bytes = IPC_READ(*(int *)ssHandle->platHandle, gpReplyBuf, MIN_REPLY_BUF_LEN);
|
|
if( bytes > 0)
|
|
n -= MIN_REPLY_BUF_LEN;
|
|
else
|
|
break;
|
|
}
|
|
// Read the sscs return code also.
|
|
IPC_READ(*(int *)ssHandle->platHandle, (Byte *) &sockReturn, MSG_DWORD_LEN);
|
|
retCode = NSSCS_E_ENUM_BUFF_TOO_SHORT;
|
|
break;
|
|
}
|
|
}
|
|
// Read the sscs return code also.
|
|
IPC_READ(*(int *)ssHandle->platHandle, (Byte *) &sockReturn, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
} while(0);
|
|
return retCode;
|
|
}
|
|
|
|
int ipc_WriteKey
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
uint32_t ssFlags,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_T *secretID,
|
|
SS_UTF8_T *key,
|
|
uint32_t keyLen,
|
|
uint8_t *val,
|
|
uint32_t valLen,
|
|
SSCS_PASSWORD_T *epPassword,
|
|
SSCS_EXT_T *ext
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
Byte *tmpBuf = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t secretIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
uint32_t extID = 0;
|
|
uint32_t luidLen = 0;
|
|
|
|
|
|
SSCS_PASSWORD_T myPassword = {0,0,""};
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle) || (NULL == keychainID) || (NULL == secretID) ||(NULL == key))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
|
|
keychainIDLen = keychainID->len;
|
|
secretIDLen = secretID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS ||
|
|
secretIDLen > NSSS_MAX_SECRET_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
// epPassword is optional. So, the code should not break.
|
|
if(epPassword == NULL)
|
|
epPassword = &myPassword;
|
|
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN + // KeychainID length
|
|
keychainIDLen + // Keychain ID
|
|
MSG_STRING_LEN + // SecretID length
|
|
secretIDLen + // SecretID
|
|
MSG_STRING_LEN + // Secret Value Length
|
|
keyLen +
|
|
MSG_STRING_LEN +
|
|
valLen +
|
|
MSG_STRING_LEN + // epPassword len
|
|
epPassword->pwordLen;
|
|
|
|
// is there an ext, account for it
|
|
if (ext)
|
|
{
|
|
// The login capture on Windows determines the LUID of the user
|
|
// and sends it as an Extension, marshall it across the pipe
|
|
// see the WriteSecret verb for handling it.
|
|
if (ext->extID == WINDOWS_LOGIN_ID)
|
|
{
|
|
// 4 byte ext type, 4 byte len and 8 bytes of LUID
|
|
msgLen += MSG_DWORD_LEN + MSG_DWORD_LEN + WINDOWS_LUID_LEN;
|
|
// as setup in the capture module
|
|
//ext.extID = WINDOWS_LOGON_ID;
|
|
//ext.version = 0x00010000; // 1.0.0
|
|
//ext.ext = (void *)lpLogonId;
|
|
// _LUID { DWORD LowPart; LONG HighPart; // 8 byte
|
|
}
|
|
else
|
|
msgLen += MSG_DWORD_LEN;
|
|
}
|
|
else
|
|
{
|
|
// the cache daemon expects a ext, add it here
|
|
msgLen += MSG_DWORD_LEN;
|
|
}
|
|
|
|
if( msgLen > MIN_REQUEST_BUF_LEN )
|
|
{
|
|
tmpBuf = (Byte*)malloc(msgLen);
|
|
if( NULL == tmpBuf )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
memset(tmpBuf,0,msgLen);
|
|
pReq = tmpBuf;
|
|
}
|
|
else
|
|
{
|
|
pReq = gpReqBuf;
|
|
}
|
|
|
|
msgid = REQ_WRITE_KEY_MSGID;
|
|
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID,keychainIDLen );
|
|
pReq += keychainIDLen;
|
|
memcpy(pReq, &secretIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretID->id,secretIDLen);
|
|
pReq += secretIDLen;
|
|
|
|
memcpy(pReq,&keyLen,MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,key,keyLen);
|
|
pReq += keyLen;
|
|
memcpy(pReq,&valLen,MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,val,valLen);
|
|
pReq += valLen;
|
|
|
|
memcpy(pReq, &(epPassword->pwordLen), MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, epPassword->pword, epPassword->pwordLen);
|
|
pReq += epPassword->pwordLen;
|
|
|
|
// marshall the extension if there is one
|
|
if (ext)
|
|
{
|
|
if (ext->extID == WINDOWS_LOGIN_ID)
|
|
{
|
|
extID = EXT_TYPE_WINDOWS_LUID;
|
|
memcpy(pReq, &extID, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
|
|
luidLen = WINDOWS_LUID_LEN;
|
|
memcpy(pReq, &luidLen, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
|
|
memcpy(pReq, ext->ext, 8);
|
|
pReq += 8;
|
|
}
|
|
else
|
|
{
|
|
uint32_t extID = 0;
|
|
memcpy(pReq,&extID,MSG_DWORD_LEN);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uint32_t extID = 0;
|
|
memcpy(pReq,&extID,MSG_DWORD_LEN);
|
|
}
|
|
|
|
if(tmpBuf != NULL)
|
|
{
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,tmpBuf,msgLen);
|
|
}
|
|
else
|
|
{
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,gpReqBuf, msgLen);
|
|
}
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
if( tmpBuf != NULL )
|
|
{
|
|
free(tmpBuf);
|
|
tmpBuf = NULL;
|
|
}
|
|
return retCode;
|
|
}
|
|
|
|
|
|
|
|
int ipc_WriteBinaryKey
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
uint32_t ssFlags,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_T *secretID,
|
|
SS_UTF8_T *key,
|
|
uint32_t keyLen,
|
|
uint8_t *val,
|
|
uint32_t valLen,
|
|
SSCS_PASSWORD_T *epPassword,
|
|
SSCS_EXT_T *ext
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
Byte *tmpBuf = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t secretIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
uint32_t extID = 0;
|
|
uint32_t luidLen = 0;
|
|
|
|
|
|
SSCS_PASSWORD_T myPassword = {0,0,""};
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle) || (NULL == keychainID) || (NULL == secretID) ||(NULL == key))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
|
|
keychainIDLen = keychainID->len;
|
|
secretIDLen = secretID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS ||
|
|
secretIDLen > NSSS_MAX_SECRET_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
// epPassword is optional. So, the code should not break.
|
|
if(epPassword == NULL)
|
|
epPassword = &myPassword;
|
|
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_STRING_LEN + // KeychainID length
|
|
keychainIDLen + // Keychain ID
|
|
MSG_STRING_LEN + // SecretID length
|
|
secretIDLen + // SecretID
|
|
MSG_STRING_LEN + // Secret Value Length
|
|
keyLen +
|
|
MSG_STRING_LEN +
|
|
valLen +
|
|
MSG_STRING_LEN + // epPassword len
|
|
epPassword->pwordLen;
|
|
|
|
// is there an ext, account for it
|
|
if (ext)
|
|
{
|
|
// The login capture on Windows determines the LUID of the user
|
|
// and sends it as an Extension, marshall it across the pipe
|
|
// see the WriteSecret verb for handling it.
|
|
if (ext->extID == WINDOWS_LOGIN_ID)
|
|
{
|
|
// 4 byte ext type, 4 byte len and 8 bytes of LUID
|
|
msgLen += MSG_DWORD_LEN + MSG_DWORD_LEN + WINDOWS_LUID_LEN;
|
|
// as setup in the capture module
|
|
//ext.extID = WINDOWS_LOGON_ID;
|
|
//ext.version = 0x00010000; // 1.0.0
|
|
//ext.ext = (void *)lpLogonId;
|
|
// _LUID { DWORD LowPart; LONG HighPart; // 8 byte
|
|
}
|
|
else
|
|
msgLen += MSG_DWORD_LEN;
|
|
}
|
|
else
|
|
{
|
|
// the cache daemon expects a ext, add it here
|
|
msgLen += MSG_DWORD_LEN;
|
|
}
|
|
|
|
if( msgLen > MIN_REQUEST_BUF_LEN )
|
|
{
|
|
tmpBuf = (Byte*)malloc(msgLen);
|
|
if( NULL == tmpBuf )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
memset(tmpBuf,0,msgLen);
|
|
pReq = tmpBuf;
|
|
}
|
|
else
|
|
{
|
|
pReq = gpReqBuf;
|
|
}
|
|
|
|
|
|
msgid = REQ_WRITE_BINARY_KEY_MSGID;
|
|
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID,keychainIDLen );
|
|
pReq += keychainIDLen;
|
|
memcpy(pReq, &secretIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretID->id,secretIDLen);
|
|
pReq += secretIDLen;
|
|
|
|
memcpy(pReq,&keyLen,MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,key,keyLen);
|
|
pReq += keyLen;
|
|
memcpy(pReq,&valLen,MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,val,valLen);
|
|
pReq += valLen;
|
|
|
|
memcpy(pReq, &(epPassword->pwordLen), MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, epPassword->pword, epPassword->pwordLen);
|
|
pReq += epPassword->pwordLen;
|
|
|
|
// marshall the extension if there is one
|
|
if (ext)
|
|
{
|
|
if (ext->extID == WINDOWS_LOGIN_ID)
|
|
{
|
|
extID = EXT_TYPE_WINDOWS_LUID;
|
|
memcpy(pReq, &extID, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
|
|
luidLen = WINDOWS_LUID_LEN;
|
|
memcpy(pReq, &luidLen, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
|
|
memcpy(pReq, ext->ext, 8);
|
|
pReq += 8;
|
|
}
|
|
else
|
|
{
|
|
uint32_t extID = 0;
|
|
memcpy(pReq,&extID,MSG_DWORD_LEN);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uint32_t extID = 0;
|
|
memcpy(pReq,&extID,MSG_DWORD_LEN);
|
|
}
|
|
|
|
if(tmpBuf != NULL)
|
|
{
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,tmpBuf,msgLen);
|
|
}
|
|
else
|
|
{
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,gpReqBuf, msgLen);
|
|
}
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = mapReturnCode(sockReturn);
|
|
|
|
}while(0);
|
|
|
|
if( tmpBuf != NULL )
|
|
{
|
|
free(tmpBuf);
|
|
tmpBuf = NULL;
|
|
}
|
|
return retCode;
|
|
}
|
|
|
|
|
|
int32_t ipc_SetMasterPassword
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
SSCS_PASSWORD_T *passwd,
|
|
SSCS_HINT_T *hint
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t passwdType = 0;
|
|
uint32_t passwdLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if( (NULL == ssHandle) || (NULL == ssHandle->platHandle) ||
|
|
(NULL == passwd) )
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
passwdType = passwd->pwordType;
|
|
passwdLen = passwd->pwordLen;
|
|
|
|
|
|
// Prepare Request buffer
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_DWORD_LEN + // passwdtype
|
|
MSG_STRING_LEN + //passwdLen
|
|
passwdLen;
|
|
|
|
pReq = gpReqBuf;
|
|
|
|
msgid = REQ_SET_MASTER_PASSWORD;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq, &passwdType, MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
memcpy(pReq, &passwdLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
|
|
memcpy((SS_UTF8_T*)pReq,passwd->pword,passwdLen);
|
|
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle, gpReqBuf, msgLen);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
retCode = sockReturn;
|
|
|
|
}while(0);
|
|
|
|
return retCode;
|
|
}
|
|
|
|
int ipc_IsSecretPersistent
|
|
(
|
|
SSCS_SECRETSTORE_HANDLE_T *ssHandle,
|
|
uint32_t ssFlags,
|
|
SSCS_KEYCHAIN_ID_T *keychainID,
|
|
SSCS_SECRET_ID_T *secretID,
|
|
SSCS_EXT_T *ext
|
|
)
|
|
{
|
|
int retVal = 0; //to be used in the function internally
|
|
int32_t retCode = NSSCS_SUCCESS; //to be returned to caller
|
|
int32_t sockReturn = 0; //obtained from the server
|
|
|
|
Byte gpReqBuf[MIN_REQUEST_BUF_LEN];
|
|
Byte gpReplyBuf[MIN_REPLY_BUF_LEN];
|
|
Byte *pReq = NULL, *pReply = NULL;
|
|
Byte *tmpBuf = NULL;
|
|
|
|
uint16_t msgid = 0;
|
|
uint32_t keychainIDLen = 0;
|
|
uint32_t secretIDLen = 0;
|
|
uint32_t msgLen = 0;
|
|
|
|
memset(gpReqBuf,0,sizeof(gpReqBuf));
|
|
memset(gpReplyBuf,0,sizeof(gpReplyBuf));
|
|
|
|
do
|
|
{
|
|
if((NULL == ssHandle) || (NULL == ssHandle->platHandle))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
|
|
if(ssFlags == 0)
|
|
{
|
|
if( (NULL == keychainID) || ( NULL == secretID ))
|
|
{
|
|
retCode = NSSCS_E_INVALID_PARAM;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Prepare Request buffer
|
|
|
|
if( ssFlags == 0 )
|
|
{
|
|
keychainIDLen = keychainID->len;
|
|
secretIDLen = secretID->len;
|
|
|
|
if( keychainIDLen > NSSS_MAX_KEYCHAIN_ID_CHARS ||
|
|
secretIDLen > NSSS_MAX_SECRET_ID_CHARS )
|
|
{
|
|
retCode = NSSS_E_SECRET_ID_TOO_LONG;
|
|
break;
|
|
}
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_DWORD_LEN + //ssFlags
|
|
MSG_STRING_LEN + // KeychainID length
|
|
keychainIDLen + // Keychain ID
|
|
MSG_STRING_LEN + // SecretID length
|
|
secretIDLen; // SecretID
|
|
}
|
|
else
|
|
{
|
|
msgLen = MSGID_LEN + MSG_LEN +
|
|
MSG_DWORD_LEN; //ssFlags
|
|
}
|
|
|
|
if( msgLen > MIN_REQUEST_BUF_LEN )
|
|
{
|
|
tmpBuf = (Byte*)malloc(msgLen);
|
|
if( NULL == tmpBuf )
|
|
{
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
memset(tmpBuf,0,msgLen);
|
|
pReq = tmpBuf;
|
|
}
|
|
else
|
|
{
|
|
pReq = gpReqBuf;
|
|
}
|
|
|
|
msgid = REQ_IS_SECRET_PERSISTENT;
|
|
memcpy(pReq, &msgid, MSGID_LEN);
|
|
pReq += MSGID_LEN;
|
|
memcpy(pReq, &msgLen, MSG_LEN);
|
|
pReq += MSG_LEN;
|
|
memcpy(pReq,&ssFlags,MSG_DWORD_LEN);
|
|
pReq += MSG_DWORD_LEN;
|
|
|
|
if( ssFlags == 0 )
|
|
{
|
|
memcpy(pReq, &keychainIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq,keychainID->keychainID,keychainIDLen );
|
|
pReq += keychainIDLen;
|
|
memcpy(pReq, &secretIDLen, MSG_STRING_LEN);
|
|
pReq += MSG_STRING_LEN;
|
|
memcpy(pReq, secretID->id,secretIDLen);
|
|
pReq += secretIDLen;
|
|
}
|
|
if(tmpBuf != NULL)
|
|
{
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,tmpBuf,msgLen);
|
|
}
|
|
else
|
|
{
|
|
retVal = IPC_WRITE(*(int *)ssHandle->platHandle,gpReqBuf, msgLen);
|
|
}
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
// Read reply
|
|
pReply = gpReplyBuf;
|
|
retVal = IPC_READ(*(int *)ssHandle->platHandle, pReply, MSG_REPLY_GENERAL);
|
|
if(retVal < 0)
|
|
{
|
|
//log debug info here
|
|
retCode = NSSCS_E_SYSTEM_FAILURE;
|
|
break;
|
|
}
|
|
|
|
memcpy(&msgid,pReply, MSGID_LEN);
|
|
pReply += MSGID_LEN;
|
|
memcpy(&msgLen,pReply, MSG_LEN);
|
|
pReply += MSG_LEN;
|
|
memcpy(&sockReturn, pReply, MSG_DWORD_LEN);
|
|
if( (sockReturn == SSCS_SECRET_IS_PERSISTENT) ||
|
|
(sockReturn == SSCS_STORE_IS_PERSISTENT) )
|
|
retCode = 1;
|
|
else if( (sockReturn == SSCS_SECRET_IS_NOT_PERSISTENT) ||
|
|
(sockReturn == SSCS_STORE_IS_NOT_PERSISTENT) )
|
|
retCode = 0;
|
|
else
|
|
retCode = mapReturnCode(sockReturn);
|
|
}while(0);
|
|
|
|
if( tmpBuf != NULL )
|
|
{
|
|
free(tmpBuf);
|
|
tmpBuf = NULL;
|
|
}
|
|
return retCode;
|
|
}
|
|
|