/*********************************************************************** * * 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; }