diff --git a/c_adlib/ad_gk/native/Common.cpp b/c_adlib/ad_gk/native/Common.cpp new file mode 100644 index 00000000..0a8b2abb --- /dev/null +++ b/c_adlib/ad_gk/native/Common.cpp @@ -0,0 +1,91 @@ + + +#include "FirefoxPasswordManager.h" +#include "Common.h" + +char lastErrorMesg[10000]; + +void PrintMessage( int level, char *mesg , ...) +{ + va_list vl; + + va_start( vl , mesg ); + vsprintf( lastErrorMesg , mesg , vl ); + va_end( vl ); + +// if we are not debugging then print DEBUG level messages +#ifdef DEBUG + printf("%s", lastErrorMesg ); +#else + if( level != MESG_DEBUG ) + printf("%s", lastErrorMesg ); +#endif + +} + + +/** +* Converts given string to lower case.... +* +*/ +void StrLwr(char *str) +{ +int n=strlen(str); + + for(int i=0; i=65 && str[i]<=90 ) + str[i]+=32; + } + +} + + +/** +* Checks if specified directory exists +* +* return MC_TRUE if directory exists else MC_FALSE +* +*/ +int IsDirectoryExists( char *path ) +{ + if( path == NULL ) + return 0; + +#ifdef WIN32 + + DWORD attr = GetFileAttributes(path); + + if( (attr == -1) || !(attr & FILE_ATTRIBUTE_DIRECTORY ) ) + { + PrintMessage(MESG_ERROR, "\n IsDirectoryExists : Directory does not exist : [%s] ", path); + return 0; + } + + return 1; + +#else + + char *program = (char*) malloc(strlen(path)+20); + + if( program == NULL ) + return 0; + + strcpy(program, "test -d "); + strcat(program, path); + + int result= system(program); + free(program); + + if( result != 0 ) + { + PrintMessage(MESG_ERROR, "\n IsDirectoryExists : Directory does not exist : [%s] ", path); + return 0; + } + + return 1; + +#endif + +} + diff --git a/c_adlib/ad_gk/native/Common.h b/c_adlib/ad_gk/native/Common.h new file mode 100644 index 00000000..f7323484 --- /dev/null +++ b/c_adlib/ad_gk/native/Common.h @@ -0,0 +1,53 @@ + +#ifndef __FPM_COMMON_H__ +#define __FPM_COMMON_H__ + +// Common structure declarations... + +struct Host +{ + char *hostName; + struct HostElement *child; + struct Host *next; +}; + + +// Each name/value pair for the Host is represented by HostElement +struct HostElement +{ + char *name; + char *value; + int isPassword; + struct HostElement *next; +}; + + +struct RejectHost +{ + char *hostName; + struct RejectHost *next; +}; + + +// Error codes + +#define FPM_PROFILE_NOT_PRESENT -101 // Specified profile does not exist +#define FPM_LIBRARY_LOAD_FAILED -102 // Failed to load the firefox library +#define FPM_LIBRARY_INIT_FAILED -103 // Failed to initialize firefox library +#define FPM_PROFILE_NOT_INITIALIZED -104 // Specified profile not initialized +#define FPM_MASTERPASSWORD_WRONG -105 // Wrong master password is specified +#define FPM_SIGNON_DATASTORE_EMPTY -106 // Internal signon data store is empty +#define FPM_SIGNON_FILE_NOT_PRESENT -107 // Signon file is not present in profile directory +#define FPM_SIGNON_FILE_READ_ERROR -108 // Error in reading signon file +#define FPM_SIGNON_FILE_WRITE_ERROR -109 // Error in writing signon file +#define FPM_SIGNON_FILE_LOCKED -110 // Signon file is locked. +#define FPM_INSUFFICIENT_MEMORY -111 // Insufficient memory. +#define FPM_ILLEGAL_HOSTNAME -112 // Hostname is not in proper form +#define FPM_HOSTNAME_NOT_PRESENT -113 // Specified hostname is not present +#define FPM_NAME_NOT_PRESENT -114 // Specified name is not present +#define FPM_SIGNON_FILE_INVALID_DATA -115 // Invalid data is read from signon file +#define FPM_PROFILE_LIMIT_EXCEEDED -116 // Maximum number of profiles exceeded... + +#endif + + diff --git a/c_adlib/ad_gk/native/CryptManager.cpp b/c_adlib/ad_gk/native/CryptManager.cpp new file mode 100644 index 00000000..16dce124 --- /dev/null +++ b/c_adlib/ad_gk/native/CryptManager.cpp @@ -0,0 +1,432 @@ + +#include "CryptManager.h" + + + +void CryptManager::SetupFunctions(void *funList[]) +{ + + //PK11SetPasswordFunc = (PK11_SetPasswordFunc) funList[0]; + PK11GetInternalKeySlot = (PK11_GetInternalKeySlot) funList[1]; + PK11FreeSlot = (PK11_FreeSlot) funList[2]; + PK11Authenticate = (PK11_Authenticate) funList[3]; + PK11CheckUserPassword =(PK11_CheckUserPassword) funList[4]; + PK11SDRDecrypt = (PK11SDR_Decrypt) funList[5]; + PK11SDREncrypt = (PK11SDR_Encrypt) funList[6]; + PLBase64Encode = (PL_Base64Encode) funList[7]; + PLBase64Decode = (PL_Base64Decode) funList[8]; + +} + +int CryptManager::GetEncryptionPref() +{ + +return FPM_TRUE; +} + + +/** +* This function encrypts the clear text data. First it performs TRIPLE DES encryption +* and then performs base64 encoding on the encrypted data. +* +* @param(in) clearData clear text data to be encrypted +* @param(out) finalData encrypted data ( null terminated) +* +* @return FPM_TRUE on success and FPM_FALSE on error. +* +*/ +int CryptManager::EncryptString (char *clearData, char **finalData) +{ +int encryptDataLen = 0; +char *encryptData = NULL; +char *encodeData = NULL; +int retValue; + + + if( clearData == NULL ) + { + PrintMessage(MESG_ERROR, "\n EncryptString : Text Data is NULL"); + return FPM_FALSE; + } + + // Do the encryption if encryption pref is set otherwise just do base64 encoding... + if ( GetEncryptionPref() ) + { + PrintMessage(MESG_DEBUG, "\n EncryptString : Performing PK11 Encryption..."); + + retValue = FPM_FALSE; + if( ((retValue = CryptPK11EncryptString(clearData, strlen(clearData), &encryptData, &encryptDataLen)) != FPM_TRUE) || ( encryptData == NULL) ) + { + PrintMessage(MESG_ERROR, "\n EncryptString : Failed to encrypt the string : %s ", clearData); + return retValue; + } + + if( (CryptBase64Encode(encryptData, encryptDataLen, finalData) != FPM_TRUE) || (*finalData == NULL) ) + { + PrintMessage(MESG_ERROR, "\n EncryptString : BASE64 encoding failed"); + return FPM_FALSE; + } + + PrintMessage(MESG_DEBUG, "\n EncryptString : Success "); + + // WARNING : If you uncomment , then be ready for side effects , crashes..etc + // Need full analysis of malloc for this data.. + // Free the allocated blocks... + + //if( encryptData ) + // free( encryptData); + + return FPM_TRUE; + } + + // otherwise do our own obscuring using Base64 encoding + PrintMessage(MESG_DEBUG, "\n EncryptString : Performing JUST base64 encoding..."); + + if( (CryptBase64Encode(clearData, strlen(clearData), &encodeData) == FPM_FALSE) || (encodeData == NULL) ) + { + PrintMessage(MESG_ERROR, "\n EncryptString : BASE64 encoding failed"); + return FPM_FALSE; + } + + // We need to add the CRYPT_PREFIX at the begining of encoded data... + // This will help during decrption process to identify type of encryption + + int prefixLen = strlen( CRYPT_PREFIX ); + int encodeLen = strlen( encodeData ); + *finalData = (char *)malloc( prefixLen + encodeLen + 1); + + if( *finalData == NULL ) + { + PrintMessage(MESG_ERROR, "\n EncryptString : Insufficient memory"); + return FPM_FALSE; + } + + // FinalData = CRYPT_PREFIX + Encoded Data + '\0' + strcpy(*finalData, CRYPT_PREFIX); + strcat(*finalData, encodeData); + *(*finalData + prefixLen + encodeLen) = 0; + + free(encodeData); + + return FPM_TRUE; +} + + + + +/** +* This function decrypts the encrypted data. First it performs base64 decoding and +* then performs TRIPLE DES decryption. +* +* @param(in) cryptData encrypted data +* @param(out) clearData clear text data ( null terminated) +* +* @return FPM_TRUE on success and FPM_FALSE on error. +* +*/ + +int CryptManager::DecryptString(char *cryptData, char **clearData) +{ +int decodeLen = 0; +int finalLen = 0; +char *decodeData = NULL; +char *finalData = NULL; +int retValue; + + if( cryptData == NULL ) + { + PrintMessage(MESG_ERROR, "\n DecryptString: CryptData is NULL..."); + return FPM_FALSE; + } + + // treat zero-length crypt string as a special case + if(cryptData[0] == '\0') + { + *clearData = (char*) malloc(1); + **clearData = 0; + return FPM_TRUE; + } + + // use PK11 encryption stuff if crypt doesn't starts with prefix + if( cryptData[0] != CRYPT_PREFIX[0] ) + { + + PrintMessage(MESG_DEBUG, "\n Performing PK11 Decryption "); + + // First do base64 decoding..... + if( (CryptBase64Decode(cryptData, &decodeData, &decodeLen) != FPM_TRUE) || (decodeData == NULL) ) + { + PrintMessage(MESG_ERROR, "\n DecryptString : Base64 decoding of crypt data failed "); + return FPM_FALSE; + } + + PrintMessage(MESG_DEBUG, "\n DecryptString : base64data (%d) = %s ", decodeLen, decodeData); + + // Now do actual PK11 decryption + retValue = FPM_FALSE; + retValue = CryptPK11DecryptString(decodeData, decodeLen, &finalData, &finalLen); + + if( retValue != FPM_TRUE ) + { + PrintMessage(MESG_ERROR, "\n DecryptString : Failed to decrypt the string "); + return retValue; + } + + + // WARNING : Decrypted string is not NULL terminated + // So we will create new NULL terminated string here... + + *clearData = (char*) malloc( finalLen + 1 ); + + if( *clearData == NULL ) + { + PrintMessage(MESG_ERROR, "\n DecryptString :Insufficient memory... "); + return FPM_INSUFFICIENT_MEMORY; + } + else + { + PrintMessage(MESG_DEBUG, "\n DecryptString : Copying new data ...."); + memcpy(*clearData, finalData, finalLen); + *(*clearData + finalLen) = 0; // Null terminate the string.... + } + + /* + // Free the allocated memory + // This is causing the problems currently...Later point we have to reanalyze the cause for this + + if( decodeData ) + free(decodeData); + + if( finalData ) + free(finalData); + */ + + PrintMessage(MESG_DEBUG, "\n decryptString : finalLen = %d ", finalLen); + + return FPM_TRUE; + } + + + // otherwise do our own de-obscuring + PrintMessage(MESG_DEBUG, "\n DecryptString : Performing simple Base64 Decoding "); + + unsigned int PREFIX_Len = strlen(CRYPT_PREFIX); + if( strlen(cryptData) == PREFIX_Len ) + { + *clearData = (char *)malloc(1); + **clearData = '\0'; + return FPM_TRUE; + } + + if( CryptBase64Decode(&cryptData[PREFIX_Len], clearData, &decodeLen) == FPM_FALSE ) + { + PrintMessage(MESG_ERROR, "\n DecryptString : Base64 decoding of crypt data failed "); + return FPM_FALSE; + } + + return FPM_TRUE; +} + + + +/** +* Performs base64 encoding of the encrypted data.. +* +* @param(in) cryptData encrypted data +* @param(in) cryptDataLen length of encrypted data +* @param(out) encodeData base64 encoded data +* +* @return FPM_TRUE on success and FPM_FALSE on error. +* +*/ + +int CryptManager::CryptBase64Encode(char *cryptData, int cryptDataLen, char **encodeData) +{ + + *encodeData = (*PLBase64Encode)((const char *)cryptData, cryptDataLen, NULL); + + if ( *encodeData == NULL ) + { + PrintMessage(MESG_ERROR, "\n Base64 encoding failed ..."); + return FPM_FALSE; + } + + return FPM_TRUE; +} + + + + + +/** +* Performs base64 decoding of the encrypted data.. +* +* @param(in) cryptData encrypted data +* @param(out) decodeData base64 decoded data +* @param(out) decodeLen length of base64 decoded data +* +* @return FPM_TRUE on success and FPM_FALSE on error. +* +*/ +int CryptManager::CryptBase64Decode(char *cryptData, char **decodeData, int *decodeLen) +{ + int len = strlen( cryptData ); + int adjust = 0; + + PrintMessage(MESG_DEBUG, "\n CryptBase64Decode : Length of crypt data = %d", len); + + // Compute length adjustment + if (cryptData[len-1] == '=') + { + adjust++; + if (cryptData[len-2] == '=') + adjust++; + } + + *decodeData = ( char *)(*PLBase64Decode)(cryptData, len, NULL); + + if( *decodeData == NULL ) + { + PrintMessage(MESG_ERROR, "\n Base64 decoding failed ..."); + return FPM_FALSE; + } + + *decodeLen = (len*3)/4 - adjust; + + PrintMessage(MESG_DEBUG, "\n CryptBase64Decode : Length of decoded data = %d", *decodeLen); + + return FPM_TRUE; +} + + +/** +* Performs TRIPLE DES encryption of clear text data +* +* @param(in) clearData clear text data to be encrypted +* @param(in) clearDataLen length of clear text data +* @param(out) cryptData TRIPLE DES encrypted data +* @param(out) cryptDataLen length of encrypted data +* +* @return FPM_TRUE on success and FPM_FALSE on error. +* +*/ +int CryptManager::CryptPK11EncryptString(char *clearData, int clearDataLen, char **cryptData, int *cryptDataLen) +{ + PK11SlotInfo *slot = 0; + SECItem keyid; + SECItem request; + SECItem reply; + SECStatus status; + + slot = (*PK11GetInternalKeySlot)(); + + if (!slot) + { + PrintMessage(MESG_ERROR, "\n CryptPK11EncryptString : PK11_GetInternalKeySlot failed ..."); + return FPM_FALSE; + } + + // PK11 authentication + if ( (*PK11Authenticate)(slot, PR_TRUE, NULL) != SECSuccess) + { + // since we have specified password callback function , we won't come here... + PrintMessage(MESG_ERROR, "\n CryptPK11EncryptString : PK11_Authenticate failed, possibly master password is wrong"); + return FPM_MASTERPASSWORD_WRONG; + } + + + // Use default key id + keyid.data = 0; + keyid.len = 0; + request.data = (unsigned char *)clearData; + request.len = clearDataLen; + reply.data = 0; + reply.len = 0; + + status = (*PK11SDREncrypt)(&keyid, &request, &reply, NULL); + + if (status != SECSuccess) + { + PrintMessage(MESG_ERROR, "\n CryptPK11EncryptString : PK11SDR_Encrypt failed ..."); + return FPM_FALSE; + } + + + *cryptData = (char*)reply.data; + *cryptDataLen = reply.len; + + return FPM_TRUE; +} + + + +/** +* Performs TRIPLE DES decryption of base64 decoded data +* +* @param(in) decodeData base64 decoded data +* @param(in) decodeLen length of base64 decoded data +* @param(out) clearData decrypted data +* @param(out) finalLen length of decrypted data +* +* @return FPM_TRUE on success and FPM_FALSE on error. +* +*/ +int CryptManager::CryptPK11DecryptString(char *decodeData, int decodeLen, char **clearData, int *finalLen) +{ + PK11SlotInfo *slot = 0; + SECStatus status; + SECItem request; + SECItem reply; + + PrintMessage(MESG_DEBUG, "\n CryptPK11DecryptString entered ..."); + + // Find token with SDR key + slot = (*PK11GetInternalKeySlot)(); + + if (!slot) + { + PrintMessage(MESG_ERROR, "\n PK11_GetInternalKeySlot failed ..."); + return FPM_FALSE; + } + + PrintMessage(MESG_DEBUG, "\n PK11_GetInternalKeySlot SUCCESS ..."); + + // Force authentication + if ( (*PK11Authenticate)(slot, PR_TRUE, NULL) != SECSuccess) + { + // since we have specified password callback function , we won't come here... + PrintMessage(MESG_ERROR, "\n PK11_Authenticate failed, Probably master password is wrong"); + return FPM_MASTERPASSWORD_WRONG; + } + + PrintMessage(MESG_DEBUG, "\n PK11_Authenticate SUCCESS ..."); + + // Decrypt the string + request.data = (unsigned char *)decodeData; + request.len = decodeLen; + reply.data = 0; + reply.len = 0; + + PrintMessage(MESG_DEBUG, "\n calling PK11SDR_Decrypt ..."); + + status = (*PK11SDRDecrypt)(&request, &reply, NULL); + + if (status != SECSuccess) + { + PrintMessage(MESG_ERROR, "\n PK11SDR_Decrypt failed ..."); + return FPM_FALSE; + } + + PrintMessage(MESG_DEBUG, "\n PK11SDR_Decrypt SUCCESS "); + + // WARNING : This string is not NULL terminated.. + *clearData = (char*)reply.data; + *finalLen = reply.len; + + // Free the slot + (*PK11FreeSlot) (slot); + + return FPM_TRUE; +} + + diff --git a/c_adlib/ad_gk/native/CryptManager.h b/c_adlib/ad_gk/native/CryptManager.h new file mode 100644 index 00000000..d6d42718 --- /dev/null +++ b/c_adlib/ad_gk/native/CryptManager.h @@ -0,0 +1,41 @@ + + +#ifndef __FPM_CRYPT_MANAGER_H__ +#define __FPM_CRYPT_MANAGER_H__ + +#include "FirefoxPasswordManager.h" +#include "Common.h" + + +class CryptManager +{ + + //PK11_SetPasswordFunc PK11SetPasswordFunc; + PK11_GetInternalKeySlot PK11GetInternalKeySlot; + PK11_FreeSlot PK11FreeSlot; + PK11_Authenticate PK11Authenticate; + PK11_CheckUserPassword PK11CheckUserPassword; + PK11SDR_Decrypt PK11SDRDecrypt; + PK11SDR_Encrypt PK11SDREncrypt; + + PL_Base64Encode PLBase64Encode; + PL_Base64Decode PLBase64Decode; + +public: + + int DecryptString(char *cryptData, char **clearData); + int EncryptString (char *clearData, char **finalData) ; + int CryptBase64Decode(char *cryptData, char **decodeData, int *decodeLen); + int CryptBase64Encode(char *cryptData, int cryptDataLen, char **encodeData); + int CryptPK11DecryptString(char *decodeData, int decodeLen, char **clearData, int *finalLen); + int CryptPK11EncryptString(char *clearData, int clearDataLen, char **cryptData, int *cryptDataLen); + + void SetupFunctions(void *funList[]); + int GetEncryptionPref(); + +}; + + +#endif + + diff --git a/c_adlib/ad_gk/native/DataManager.cpp b/c_adlib/ad_gk/native/DataManager.cpp new file mode 100644 index 00000000..b993e98e --- /dev/null +++ b/c_adlib/ad_gk/native/DataManager.cpp @@ -0,0 +1,587 @@ + +#include "DataManager.h" + + +DataManager::DataManager() +{ + hostList = NULL; + rejectHostList = NULL; +} + + + +DataManager::~DataManager() +{ + +} + +int DataManager::AddRejectHost(char *hostName) +{ +RejectHost *t; + + if( hostName == NULL || hostName[0] == 0 ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Host name is NULL or empty "); + // Just ignore this.. + return FPM_TRUE; + } + + // check if the specified host is already present + for(t=rejectHostList; t ; t = t->next) + { + if( STRCMPI(hostName, t->hostName) == 0 ) + { + PrintMessage(MESG_DEBUG, "\n DataManager : Specified hostname [%s] is already present ", hostName); + return FPM_TRUE; + } + } + + // Create new Host element for new host + RejectHost *tempHost = (RejectHost *) malloc(sizeof(RejectHost)); + + if( tempHost ) + tempHost->hostName = (char*) malloc(strlen(hostName) + 1); + + if( !tempHost || !tempHost->hostName) + { + PrintMessage(MESG_ERROR, "\n DataManager : Failed to add reject host due to insufficient memory "); + return FPM_INSUFFICIENT_MEMORY; + } + + strcpy(tempHost->hostName, hostName); + tempHost->next = NULL; + + if( rejectHostList == NULL ) + rejectHostList = tempHost; + else + { // Add new host at the end + for(t=rejectHostList; t->next ; t=t->next); + + t->next = tempHost; + } + + return FPM_TRUE; + + +} + + +//invoked from outside +int DataManager::RemoveRejectHost(char *hostName) +{ + RejectHost *prev = NULL; + + if( !hostName ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Host name is Null ...."); + return FPM_FALSE; + } + + // Find out and destroy it..! + for(RejectHost *t=rejectHostList; t ; prev=t,t=t->next) + { + if( STRCMPI(hostName, t->hostName) == 0 ) + { + // if this is the first node + if( rejectHostList == t ) + rejectHostList = t->next; + else + prev->next = t->next; + + free(t->hostName); + free(t); + return FPM_TRUE; + } + } + + PrintMessage(MESG_ERROR, "\n DataManager : Specified hostname[%s] is not present in the reject host list", hostName); + + return FPM_FALSE; + +} + + +void DataManager::PrintAllRejectHosts() +{ + + PrintMessage(MESG_PRINT, "\n\n ****** List of Reject Hosts ******"); + + for(RejectHost *t=rejectHostList; t ; t=t->next) + PrintMessage(MESG_PRINT, "\n %s", t->hostName); + +} + + +// internal function +int DataManager::AddHost(char *hostName) +{ +Host *host, *t; + + if( hostName == NULL || hostName[0] == 0 ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Host name is NULL or empty "); + return FPM_ILLEGAL_HOSTNAME; + } + + // check if the specified host is already present + for(host=hostList; host ; host = host->next) + { + if( STRCMPI(hostName, host->hostName) == 0 ) + { + PrintMessage(MESG_DEBUG, "\n DataManager : Specified hostname [%s] is already present ", hostName); + return FPM_TRUE; + } + } + + // Create new Host + Host *tempHost = (Host *) malloc(sizeof(Host)); + + if( tempHost ) + tempHost->hostName = (char*) malloc(strlen(hostName) + 1); + + if( !tempHost || !tempHost->hostName) + { + PrintMessage(MESG_ERROR, "\n DataManager : Failed to add host due to insufficient memory "); + return FPM_INSUFFICIENT_MEMORY; + } + + strcpy(tempHost->hostName, hostName); + tempHost->child = NULL; + tempHost->next = NULL; + + // Now add the new host to the existing store + if( hostList == NULL ) + hostList = tempHost; + else + { // Add new host at the end + for(t=hostList; t->next ; t=t->next); + + t->next = tempHost; + } + + return FPM_TRUE; +} + + + +// invoked from outside... +int DataManager::ModifyHost(char *oldHostName, char *newHostName) +{ + if( !oldHostName || !newHostName ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Null parameters passed...."); + return FPM_FALSE; + } + + + for(Host *t=hostList; t ; t=t->next) + { + if( STRCMPI(oldHostName, t->hostName) == 0 ) + { + free(t->hostName); + t->hostName = (char*) malloc( strlen(newHostName) + 1 ); + + if( !t->hostName ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Failed to modify host entry due to insufficient memory "); + return FPM_FALSE; + } + + strcpy(t->hostName, newHostName); + return FPM_TRUE; + } + } + + PrintMessage(MESG_ERROR, "\n DataManager : Specified hostname[%s] is not present ", oldHostName); + return FPM_FALSE; + +} + +int DataManager::AddHost(Host *host) +{ + +Host *t; + + if( host == NULL ) + { + PrintMessage(MESG_ERROR, "\n AddHost : host is NULL...."); + return FPM_FALSE; + } + + for(t=hostList; t ; t=t->next) + { + if( STRCMPI(host->hostName, t->hostName) == 0 ) + { + PrintMessage(MESG_ERROR, "\n AddHost : Specified hostname %s is already present..", host->hostName); + return FPM_FALSE; + } + } + + Host *newHost = DuplicateHost(host); + + if( newHost == NULL) + { + PrintMessage(MESG_ERROR, "\n AddHost : Insufficient memory"); + return FPM_INSUFFICIENT_MEMORY; + } + + // Add the new host at the end of the list... + if( hostList == NULL ) + hostList = newHost; + else + { + for(t=hostList; t->next ; t=t->next); + + t->next = newHost; + } + + PrintMessage(MESG_DEBUG, "\n AddHost : Host %s added successfully", newHost->hostName); + + return FPM_TRUE; +} + + + +int DataManager::ModifyHost(Host *host) +{ + Host *prev = NULL; + + if( host == NULL ) + { + PrintMessage(MESG_ERROR, "\n ModifyHost : host is NULL...."); + return FPM_FALSE; + } + + // check if the specified host is present + // If present remove it and add new host ... + for(Host *t=hostList; t ; prev=t,t=t->next) + { + if( STRCMPI(host->hostName, t->hostName) == 0 ) + { + Host *newHost = DuplicateHost(host); + + if( newHost == NULL ) + { + PrintMessage(MESG_ERROR, "\n ModifyHost : Insufficient memory"); + return FPM_INSUFFICIENT_MEMORY; + } + + // if this is the first node + if( hostList == t ) + { + hostList = newHost; + newHost->next = t->next; + } + else + { + prev->next = newHost; + newHost->next = t->next; + } + + PrintMessage(MESG_DEBUG, "\n ModifyHost : Host %s modified successfully", newHost->hostName); + + return FPM_TRUE; + } + } + + PrintMessage(MESG_ERROR, "\n ModifyHost : Specified host %s is not present", host->hostName); + + return FPM_HOSTNAME_NOT_PRESENT; +} + + + + +//invoked from outside +int DataManager::RemoveHost(char *hostName) +{ + Host *prev = NULL; + + if( !hostName ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Host name is Null ...."); + return FPM_ILLEGAL_HOSTNAME; + } + + // Find out and destroy it..! + for(Host *t=hostList; t ; prev=t,t=t->next) + { + if( STRCMPI(hostName, t->hostName) == 0 ) + { + // if this is the first node + if( hostList == t ) + hostList = t->next; + else + prev->next = t->next; + + free(t->hostName); + free(t); + return FPM_TRUE; + } + } + + PrintMessage(MESG_ERROR, "\n DataManager : Specified hostname[%s] is not present ", hostName); + + return FPM_HOSTNAME_NOT_PRESENT; +} + + +Host* DataManager::DuplicateHost(Host *host) +{ +HostElement *prev = NULL; +HostElement *t, *temp; + + Host *newHost = (Host *) malloc(sizeof(Host)); + + if( newHost ) + newHost->hostName = (char*) malloc(strlen(host->hostName) + 1); + + if( !newHost || !newHost->hostName ) + { + PrintMessage(MESG_ERROR, "\n DuplicateHost : Insufficient memory"); + return NULL; + } + + strcpy(newHost->hostName, host->hostName); + newHost->child = NULL; + newHost->next = NULL; + + for(t=host->child; t ; t = t->next) + { + HostElement *nh = (HostElement*) malloc(sizeof(HostElement)); + + if( nh ) + { + nh->name = (char*) malloc(strlen(t->name) + 1 ); + nh->value = (char*) malloc(strlen(t->value) + 1); + } + + if( !nh || !nh->name || !nh->value) + goto duplicate_error; + + nh->isPassword = t->isPassword; + strcpy(nh->name, t->name); + strcpy(nh->value, t->value); + nh->next = NULL; + + if( prev == NULL ) + newHost->child = nh; + else + prev->next = nh; + + prev = nh; + } + + + return newHost; + +duplicate_error: + + // cleanup partially loaded data + for(t=newHost->child; t ; ) + { + if(t->name) free(t); + if(t->value) free(t); + + temp = t; + t = t->next; + free(temp); + } + + + if(newHost->hostName) + free(newHost->hostName); + + free(newHost); + + PrintMessage(MESG_ERROR, "\n DuplicateHost : Insufficient memory"); + return NULL; +} + +void DataManager::PrintAllHosts() +{ + PrintMessage(MESG_PRINT, "\n\n List of hosts "); + + for(Host *t=hostList; t ; t=t->next) + { + PrintMessage(MESG_PRINT, "\n\n %s", t->hostName); + for(HostElement *h=t->child; h ; h= h->next) + { + PrintMessage(MESG_PRINT, "\n %s : %s ", h->name, h->value); + } + } +} + + + + +int DataManager::AddHostElement(char *hostName, char *name, char *value, unsigned char isPassword) +{ + Host *host; + HostElement *h, *t; + + + if( !hostName || !name || !value) + { + PrintMessage(MESG_ERROR, "\n DataManager : Null parameters passed...."); + return FPM_SIGNON_FILE_INVALID_DATA; + } + + + // First find the specified host + for(host = hostList; host ; host = host->next) + { + if( STRCMPI(hostName, host->hostName) == 0 ) + break; + } + + + if( !host ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Specified hostname[%s] is not present ", hostName); + return FPM_HOSTNAME_NOT_PRESENT; + } + + // check if specified name/value pair exist already.... + for(h = host->child; h ; h=h->next) + { + if( (STRCMPI(h->name,name) == 0 ) && (strcmp(h->value, value) == 0 ) ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Specified name/value [%s/%s]pair is already present ", name,value); + return FPM_TRUE; + } + } + + HostElement *temp = (HostElement *) malloc(sizeof(HostElement)); + if( temp ) + { + temp->name = (char*) malloc( strlen(name)+1 ); + temp->value = (char*) malloc( strlen( value) + 1 ); + } + + if( !temp || !temp->name || !temp->value ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Failed to add name/value due to insufficient memory "); + return FPM_INSUFFICIENT_MEMORY; + } + + strcpy(temp->name,name); + strcpy(temp->value, value); + temp->isPassword = isPassword; + temp->next = NULL; + + // Now add it to the host... + if( host->child == NULL ) + { + host->child = temp; + } + else + { + for(t = host->child; t->next ; t=t->next); + + t->next = temp; + } + + return FPM_TRUE; +} + + +// invoked from outside.. +int DataManager::RemoveHostElement(char *hostName, char *value) +{ + + Host *host; + + if( !hostName || !value ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Null parameters passed...."); + return FPM_FALSE; + } + + // First find the specified hot + for(host = hostList; host; host = host->next) + { + if( STRCMPI(hostName, host->hostName) == 0 ) + break; + } + + if( !host ) + { + PrintMessage(MESG_ERROR, "\n DataManager : Specified hostname[%s] is not present ", hostName); + return FPM_FALSE; + } + + HostElement *prev = host->child; + for(HostElement *h = host->child; h ;prev=h, h=h->next) + { + if( strcmp(h->value, value) == 0 ) + { + + if( host->child == h ) + host->child = h->next; + else + prev->next = h->next; + + free(h->value); + free(h->name); + free(h); + + return FPM_TRUE; + } + } + + + return FPM_FALSE; +} + + +// internal +int DataManager::RemoveAllData() +{ + + RemoveAllRejectHosts(); + RemoveAllHosts(); + + return FPM_TRUE; +} + + +int DataManager::RemoveAllRejectHosts() +{ +RejectHost *t = rejectHostList; +RejectHost *temp; + + for( ; t; ) + { + temp = t; + t= t->next; + RemoveRejectHost(temp->hostName); + } + + rejectHostList = NULL; + + return FPM_TRUE; +} + + +int DataManager::RemoveAllHosts() +{ +Host *t = hostList; +Host *temp; + + for( ; t ; ) + { + temp = t; + t = t->next; + + RemoveHost(temp->hostName); + } + + hostList = NULL; + + return FPM_TRUE; + +} + + + diff --git a/c_adlib/ad_gk/native/DataManager.h b/c_adlib/ad_gk/native/DataManager.h new file mode 100644 index 00000000..5f7aef72 --- /dev/null +++ b/c_adlib/ad_gk/native/DataManager.h @@ -0,0 +1,44 @@ + +#ifndef __FPM_DATA_MANAGER_H__ +#define __FPM_DATA_MANAGER_H__ + +#include "FirefoxPasswordManager.h" +#include "Common.h" + + +class DataManager +{ + +public: + + Host *hostList; + RejectHost *rejectHostList; + + DataManager(); + virtual ~DataManager(); + + int AddRejectHost(char *hostName); + int RemoveRejectHost(char *hostName); + void PrintAllRejectHosts(); + + + int AddHost(char *hostName); + int AddHost(Host *host); + int ModifyHost(struct Host *host); + int ModifyHost(char *oldHostName, char *newHostName); + int RemoveHost(char *hostName); + void PrintAllHosts(); + + int AddHostElement(char *hostName, char *name, char *value, unsigned char isPassword); + int RemoveHostElement(char *hostName, char *clearValue); + Host* DuplicateHost(Host *host); + + int RemoveAllData(); + int RemoveAllRejectHosts(); + int RemoveAllHosts(); + +}; + +#endif + + diff --git a/c_adlib/ad_gk/native/FirefoxPasswordManager.cpp b/c_adlib/ad_gk/native/FirefoxPasswordManager.cpp new file mode 100644 index 00000000..4c0b18ba --- /dev/null +++ b/c_adlib/ad_gk/native/FirefoxPasswordManager.cpp @@ -0,0 +1,591 @@ + + +#include "FirefoxPasswordManager.h" +#include "Common.h" +#include "ProfileManager.h" + + +ProfileManager profileManager[MAX_PROFILE_COUNT]; +int profileCount = 0; + + +/* +* Gets the list of profile names... +* +* @param[in/out] profiles pointer to array of profile names +* @param[in/out] profileFlag Indicates if default profile or not. +* @return count count of profiles +* 0 no profiles found +* < 0 on error +* +* If one or more profiles found then profiles array is filled with +* the profile names and count of profiles is returned. ProfileFlag[] +* array is filled with 1 or 0 to indicate if the respective profile +* is default profile or not.If no profiles found then value 0 is +* returned and negative values is returned if there is an error. +* +*/ + +extern "C" APIEXPORT int FPM_GetProfileList(char **profileList[], int *profileFlag[]) +{ + +#ifdef WIN32 + + char profileDir[MAX_PATH] = ""; + char partialPath[] = "Application Data\\Mozilla\\Firefox"; + char profilePath[MAX_PATH]; + char line[1024]; + + DWORD pathSize = MAX_PATH; + char *finalProfilePath = NULL; + int profileCount = 0; + unsigned int i; + HANDLE token; + + + // Get current user's profile directory + if( OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == FALSE ) + { + PrintMessage(MESG_ERROR, "\n GetProfileList : Failed to get current process token "); + return FPM_FALSE; + } + + if( GetUserProfileDirectory(token, profileDir, &pathSize) == FALSE ) + { + PrintMessage(MESG_ERROR, "\n GetProfileList : Failed to get user profile directory"); + return FPM_FALSE; + } + + PrintMessage(MESG_DEBUG, "\n GetProfileList : User Profile directory = %s", profileDir); + + // Get firefox profile directory + strcpy(profilePath, profileDir); + strcat(profilePath,"\\"); + strcat(profilePath,partialPath); + strcat(profilePath,"\\profiles.ini"); + + PrintMessage(MESG_DEBUG, "\n GetProfileList : Firefox profile dir path = %s ", profilePath); + + +#else // Linux platform.... + + char profileDir[] ="/.mozilla/firefox"; + char profileFile[] ="/.mozilla/firefox/profiles.ini"; + + char line[1024]; + char *profilePath = NULL; + char *homeDir = NULL; + char *finalProfilePath = NULL; + int profileCount = 0; + unsigned int i; + + // Get home directory + homeDir = getenv("HOME"); + + if(homeDir == NULL ) + { + PrintMessage(MESG_ERROR, "\n GetProfileList : Unable to get home directory "); + return FPM_FALSE; + } + + profilePath = (char*) malloc( strlen(homeDir) + strlen(profileFile) + 3 ); + if( profilePath == NULL ) + { + PrintMessage(MESG_ERROR, "\n GetProfileList : Insufficient memory "); + return FPM_FALSE; + } + strcpy(profilePath,homeDir); + strcat(profilePath,profileFile); + + PrintMessage(MESG_DEBUG, "\n GetProfileList : Firefox profile dir path = %s ", profilePath); + +#endif + + // Open the firefox profile setting file + FILE *profile = fopen(profilePath, "r"); + + if( profile == NULL ) + { + PrintMessage(MESG_ERROR, "\n GetProfileList : Unable to find firefox profile file : %s ", profilePath); + return FPM_FALSE; + } + + // First find out the count of profiles.... + profileCount = 0; + while(fgets(line, 1024, profile)) + { + // Remove trailing end of line character + line[strlen(line)-1]= 0; + + // Convert to smaller case until "=" found.... + for(i=0; i=65 && line[i]<=90 ) + line[i]+=32; + } + + if( strstr(line, "name=") != NULL ) + { + char *temp = strchr(line,'=') + 1; + profList[profileCount] = (char*) malloc(strlen(temp)+1); + + if( profList[profileCount] == NULL ) + { + PrintMessage(MESG_ERROR, "\n GetProfileList : Insufficient memory "); + fclose(profile); + return 0; + } + + strcpy(profList[profileCount],temp); + profFlag[profileCount] = 0; + + PrintMessage(MESG_ERROR, "\n GetProfileList : Found profile = [%s]", profList[profileCount]); + profileCount++; + continue; + } + + // check if the current profile is default + if( strstr(line, "default=1") != NULL ) + { + profFlag[profileCount-1] = 1; + } + + } + + fclose(profile); + + // if there is only one profile then set it default profile + if( profileCount == 1 ) + { + **profileFlag = 1; + } + + return profileCount; +} + + + + + + +extern "C" APIEXPORT int FPM_FirefoxProfileInit(char *profileName) +{ +int retValue; +int profileIndex = -1; +int isObjectExist = FPM_FALSE; + + // check if the profile is already initialized... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + PrintMessage(MESG_ERROR, "\n FirefoxProfileInit : Specified profile object [%s] is already present ", profileName); + profileIndex = i; + isObjectExist = FPM_TRUE; + } + } + } + + // This is new profile... + if( (profileIndex == -1) && ( (profileCount + 1) >= MAX_PROFILE_COUNT) ) + { + PrintMessage(MESG_ERROR, "\n FirefoxProfileInit : Max profile count exceeded."); + return FPM_PROFILE_LIMIT_EXCEEDED; + } + + if(profileIndex == -1 ) + { + profileIndex = profileCount; + profileCount++; + } + // If not already initialized then go and initialize it... + if( profileManager[profileIndex].isInitialized == FPM_FALSE ) + { + if( (retValue = profileManager[profileIndex].ProfileInit(profileName)) != FPM_TRUE ) + { + PrintMessage(MESG_ERROR, "\n FirefoxProfileInit : Failed to initialize the profile %s ", profileName); + return retValue; + } + } + else + { + PrintMessage(MESG_DEBUG, "\n FirefoxProfileInit : Firefox profile %s is already initialized ", profileName); + return FPM_TRUE; + } + + PrintMessage(MESG_DEBUG, "\n FirefoxProfileInit : Firefox profile %s initialized successfully ", profileName); + + return FPM_TRUE; +} + + +extern "C" APIEXPORT int FPM_FirefoxProfileExit(char *profileName) +{ + // Find the profile... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + // check if its initialized + if( profileManager[i].isInitialized == FPM_TRUE ) + { + PrintMessage(MESG_DEBUG, "\n FirefoxProfileExit : Exiting the firefox profile %s ", profileName); + profileManager[i].ProfileExit(); + return FPM_TRUE; + } + else + { + PrintMessage(MESG_ERROR, "\n FirefoxProfileExit : Specified profile %s is not initialized , cannot exit the profile", profileName); + return FPM_PROFILE_NOT_INITIALIZED; + } + } + } + } + + PrintMessage(MESG_ERROR, "\n FirefoxProfileExit : Specified profile %s is not found", profileName); + + return FPM_PROFILE_NOT_PRESENT; + + +} + + +extern "C" APIEXPORT int FPM_IsMasterPasswordSet(char *profileName) +{ + + // Find the profile... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + // check if its initialized + if( profileManager[i].isInitialized == FPM_TRUE ) + { + PrintMessage(MESG_DEBUG, "\n IsMasterPasswordSet : invoking IsMasterPasswordSet for profile %s", profileName); + return profileManager[i].IsMasterPasswordSet(); + } + else + { + PrintMessage(MESG_ERROR, "\n IsMasterPasswordSet : Specified profile %s is not initialized ", profileName); + return FPM_PROFILE_NOT_INITIALIZED; + } + } + } + } + + PrintMessage(MESG_ERROR, "\n IsMasterPasswordSet : Specified profile %s is not found", profileName); + + return FPM_PROFILE_NOT_PRESENT; + +} + + +extern "C" APIEXPORT int FPM_CheckMasterPassword(char *profileName, char *masterPassword) +{ + + // Find the profile... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + // check if its initialized + if( profileManager[i].isInitialized == FPM_TRUE ) + { + PrintMessage(MESG_DEBUG, "\n CheckMasterPassword : invoking CheckMasterPassword for profile %s", profileName); + return profileManager[i].CheckMasterPassword(masterPassword, 1); + } + else + { + PrintMessage(MESG_ERROR, "\n CheckMasterPassword : Specified profile %s is not initialized ", profileName); + return FPM_PROFILE_NOT_INITIALIZED; + } + } + } + } + + + PrintMessage(MESG_ERROR, "\n CheckMasterPassword : Specified profile %s is not found", profileName); + + return FPM_PROFILE_NOT_PRESENT; + +} + + + +extern "C" APIEXPORT int FPM_GetSignonData(char *profileName,struct Host **host, int doRefresh) +{ + + // Find the profile... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + // check if its initialized + if( profileManager[i].isInitialized == FPM_TRUE ) + { + PrintMessage(MESG_DEBUG, "\n GetSignonData : invoking GetSignonData for profile %s", profileName); + return profileManager[i].GetSignonData(host, doRefresh); + } + else + { + PrintMessage(MESG_ERROR, "\n GetSignonData : Specified profile %s is not initialized", profileName); + return FPM_PROFILE_NOT_INITIALIZED; + } + } + } + } + + + PrintMessage(MESG_ERROR, "\n GetSignonData : Specified profile %s is not found", profileName); + + return FPM_PROFILE_NOT_PRESENT; +} + + + +extern "C" APIEXPORT int FPM_WriteSignonData(char *profileName) +{ + + // Find the profile... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + // check if its initialized + if( profileManager[i].isInitialized == FPM_TRUE ) + { + PrintMessage(MESG_DEBUG, "\n WriteSignonData : invoking WriteSignonData for profile %s", profileName); + return profileManager[i].WriteSignonData(); + } + else + { + PrintMessage(MESG_ERROR, "\n WriteSignonData : Specified profile %s is not initialized", profileName); + return FPM_PROFILE_NOT_INITIALIZED; + } + } + } + } + + + PrintMessage(MESG_ERROR, "\n WriteSignonData : Specified profile %s is not found", profileName); + + return FPM_PROFILE_NOT_PRESENT; +} + + + + +extern "C" APIEXPORT int FPM_AddHost(char *profileName, struct Host *host, int doUpdate) +{ + + // Find the profile... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + // check if its initialized + if( profileManager[i].isInitialized == FPM_TRUE ) + { + PrintMessage(MESG_DEBUG, "\n AddHost : invoking AddHost for profile %s", profileName); + return profileManager[i].AddHost(host, doUpdate); + } + else + { + PrintMessage(MESG_ERROR, "\n AddHost : Specified profile %s is not initialized", profileName); + return FPM_PROFILE_NOT_INITIALIZED; + } + } + } + } + + + PrintMessage(MESG_ERROR, "\n AddHost : Specified profile %s is not found", profileName); + + return FPM_PROFILE_NOT_PRESENT; + +} + + +extern "C" APIEXPORT int FPM_ModifyHost(char *profileName, struct Host *host, int doUpdate) +{ + // Find the profile... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + // check if its initialized + if( profileManager[i].isInitialized == FPM_TRUE ) + { + PrintMessage(MESG_DEBUG, "\n ModifyHost : invoking ModifyHost for profile %s", profileName); + return profileManager[i].ModifyHost(host, doUpdate); + } + else + { + PrintMessage(MESG_ERROR, "\n ModifyHost : Specified profile %s is not initialized", profileName); + return FPM_PROFILE_NOT_INITIALIZED; + } + } + } + } + + + PrintMessage(MESG_ERROR, "\n ModifyHost : Specified profile %s is not found", profileName); + + return FPM_PROFILE_NOT_PRESENT; + + +} + + +extern "C" APIEXPORT int FPM_RemoveHost(char *profileName, char *hostName, int doUpdate) +{ + // Find the profile... + for(int i=0; i< profileCount; i++) + { + if( profileManager[i].profileName != NULL ) + { + if( STRCMPI(profileManager[i].profileName, profileName) == 0 ) + { + // check if its initialized + if( profileManager[i].isInitialized == FPM_TRUE ) + { + PrintMessage(MESG_DEBUG, "\n RemoveHost : invoking RemoveHost for profile %s", profileName); + return profileManager[i].RemoveHost(hostName, doUpdate); + } + else + { + PrintMessage(MESG_ERROR, "\n RemoveHost : Specified profile %s is not initialized", profileName); + return FPM_PROFILE_NOT_INITIALIZED; + } + } + } + } + + PrintMessage(MESG_ERROR, "\n RemoveHost : Specified profile %s is not found", profileName); + + return FPM_PROFILE_NOT_PRESENT; +} + + +/* +int main(int argc, char* argv[]) +{ +char **profileList; +int *profileFlag; +int profCount; + + profCount = FPM_GetProfileList(&profileList, &profileFlag); + + if( profCount > 0) + { + printf("\n Profile names are as follows..."); + for(int i=0; i< profCount; i++) + { + printf("\n %d => [%s] [%d]", i+1, profileList[i], profileFlag[i]); + + // Load the default profile... + if( profileFlag[i] == 1 ) + { + ProfileManager *pm = new ProfileManager(); + printf("\n ***************************************"); + + if( pm->ProfileInit(profileList[i]) == 1) + { + pm->CheckMasterPassword("test123", 1); + struct Host *hostInfo; + pm->GetSignonData(&hostInfo, 1); + + // Print all the data + PrintMessage(MESG_PRINT, "\n\n List of hosts "); + + for(Host *t=hostInfo; t ; t=t->next) + { + PrintMessage(MESG_PRINT, "\n\n %s", t->hostName); + for(HostElement *h=t->child; h ; h= h->next) + { + PrintMessage(MESG_PRINT, "\n %s : %s ", h->name, h->value); + } + } + + pm->WriteSignonData(); + + pm->ProfileExit(); + } + } + + printf("\n ***************************************"); + } + } + + return 0; +} + + */ + + + + diff --git a/c_adlib/ad_gk/native/FirefoxPasswordManager.h b/c_adlib/ad_gk/native/FirefoxPasswordManager.h new file mode 100644 index 00000000..f256d86a --- /dev/null +++ b/c_adlib/ad_gk/native/FirefoxPasswordManager.h @@ -0,0 +1,164 @@ + + +#ifndef __FPM_Firefox_Password_MANAGER_H__ +#define __FPM_Firefox_Password_MANAGER_H__ + + + +#include +#include +#include +#include +#include + +#ifdef WIN32 + #include + #include + #pragma comment(lib,"userenv.lib") + + #define STRCMPI strcmpi + #define APIEXPORT __declspec(dllexport) + + #define NSS_LIBRARY_NAME "nss3.dll" + #define PLC_LIBRARY_NAME "plc4.dll" + #define NSPR_LIBRARY_NAME "nspr4.dll" + #define PLDS_LIBRARY_NAME "plds4.dll" + #define SOFTN_LIBRARY_NAME "softokn3.dll" + + #define LOADLIBRARY(x) LoadLibrary(x) + #define GETPROCADDRESS GetProcAddress + #define FREELIBRARY FreeLibrary + +#else + #include + #define STRCMPI strcasecmp + #define APIEXPORT + + #define NSS_LIBRARY_NAME "libnss3.so" + #define PLC_LIBRARY_NAME "libplc4.so" + #define NSPR_LIBRARY_NAME "libnspr4.so" + #define PLDS_LIBRARY_NAME "libplds4.so" + #define SOFTN_LIBRARY_NAME "libsoftokn3.so" + + #define LOADLIBRARY(x) dlopen(x, RTLD_LAZY) // alternative : RTLD_NOW + #define GETPROCADDRESS dlsym + #define FREELIBRARY dlclose + + #define HMODULE void * + +#endif + + + +#define FPM_TRUE 1 +#define FPM_FALSE 0 + +#define MESG_DEBUG 0 +#define MESG_PRINT 1 +#define MESG_ERROR 2 + +#define MAX_PROFILE_COUNT 5 + +#define DEBUG 11 + +#define Unichar unsigned int + +#define HEADER_VERSION "#2c" +#define CRYPT_PREFIX "~" + +#define SIGNON_FILE_NAME "signons.txt" + +// Internal structure declaration taken from firefox..... +typedef enum SECItemType +{ + siBuffer = 0, + siClearDataBuffer = 1, + siCipherDataBuffer = 2, + siDERCertBuffer = 3, + siEncodedCertBuffer = 4, + siDERNameBuffer = 5, + siEncodedNameBuffer = 6, + siAsciiNameString = 7, + siAsciiString = 8, + siDEROID = 9, + siUnsignedInteger = 10, + siUTCTime = 11, + siGeneralizedTime = 12 +}; + +//typedef struct SECItemStr SECItem; + +struct SECItem +{ + SECItemType type; + unsigned char *data; + unsigned int len; +}; + + +typedef enum SECStatus +{ + SECWouldBlock = -2, + SECFailure = -1, + SECSuccess = 0 +}; + +// For some PR type varialbes...just to remove gecko-sdk dependency +// following is added here. +#define PRBool int +#define PRUint32 unsigned int +#define PR_TRUE 1 +#define PR_FALSE 0 + + + +// End + + + +typedef struct PK11SlotInfoStr PK11SlotInfo; + +// NSS Library functions +//typedef char *(PR_CALLBACK *PK11PasswordFunc)(PK11SlotInfo *slot, PRBool retry, void *arg); +typedef SECStatus (*NSS_Init) (const char *configdir); +typedef SECStatus (*NSS_Shutdown) (void); +//typedef void (*PK11_SetPasswordFunc) (PK11PasswordFunc func); +typedef PK11SlotInfo * (*PK11_GetInternalKeySlot) (void); +typedef void (*PK11_FreeSlot) (PK11SlotInfo *slot); +typedef SECStatus (*PK11_Authenticate) (PK11SlotInfo *slot, PRBool loadCerts, void *wincx); +typedef SECStatus (*PK11_CheckUserPassword) (PK11SlotInfo *slot,char *pw); +typedef SECStatus (*PK11SDR_Decrypt) (SECItem *data, SECItem *result, void *cx); +typedef SECStatus (*PK11SDR_Encrypt) (SECItem *keyid, SECItem *data, SECItem *result, void *cx); + +// PLC Library functions +typedef char * (*PL_Base64Encode)( const char *src, PRUint32 srclen, char *dest); +typedef char * (*PL_Base64Decode)( const char *src, PRUint32 srclen, char *dest); + +void PrintMessage( int level, char *mesg , ...); +int IsDirectoryExists( char *path ); +void StrLwr(char *str); + + + +// Profile initiliazation functions +extern "C" APIEXPORT int FPM_GetProfileList(char **profileList[], int **profileFlag); +extern "C" APIEXPORT int FPM_FirefoxProfileInit(char *profileName); +extern "C" APIEXPORT int FPM_FirefoxProfileExit(char *profileName); + +// Master password functions +extern "C" APIEXPORT int FPM_IsMasterPasswordSet(char *profileName); +extern "C" APIEXPORT int FPM_CheckMasterPassword(char *profileName, char *masterPassword); + +// Signon data update functions +extern "C" APIEXPORT int FPM_GetSignonData(char *profileName,struct Host **host, int doRefresh); +extern "C" APIEXPORT int FPM_WriteSignonData(char *profileName); +extern "C" APIEXPORT int FPM_AddHost(char *profileName, struct Host *host, int doUpdate); +extern "C" APIEXPORT int FPM_ModifyHost(char *profileName, struct Host *host, int doUpdate); +extern "C" APIEXPORT int FPM_RemoveHost(char *profileName, char *hostname, int doUpdate); + + +#endif + + + + diff --git a/c_adlib/ad_gk/native/Makefile b/c_adlib/ad_gk/native/Makefile index bdfd31c7..c093c738 100644 --- a/c_adlib/ad_gk/native/Makefile +++ b/c_adlib/ad_gk/native/Makefile @@ -1,7 +1,7 @@ # # configure environment # -TARGET = ad_gk +TARGET = ad_ff include global.mak include defaults.$(PLAT) include rules.mak diff --git a/c_adlib/ad_gk/native/ProfileManager.cpp b/c_adlib/ad_gk/native/ProfileManager.cpp new file mode 100644 index 00000000..d449c0dc --- /dev/null +++ b/c_adlib/ad_gk/native/ProfileManager.cpp @@ -0,0 +1,818 @@ + +#include "ProfileManager.h" + + + +// Private functions.... + +ProfileManager::ProfileManager() +{ + isInitialized = 0; + libnss = NULL; + libplc = NULL; + + profileName = NULL; + profilePath = NULL; + libraryPath = NULL; + masterPassword = NULL; + + +} + + +char * ProfileManager::GetFirefoxProfilePath(char *profileName) +{ + +#ifdef WIN32 + + char profileDir[MAX_PATH] = ""; + char partialPath[] = "Application Data\\Mozilla\\Firefox"; + char profilePath[MAX_PATH]; + char line[1024]; + + DWORD pathSize = MAX_PATH; + char *finalProfilePath = NULL; + unsigned int i; + HANDLE token; + + + // Get current user's profile directory + if( OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == FALSE ) + { + PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Failed to get current process token "); + return 0; + } + + if( GetUserProfileDirectory(token, profileDir, &pathSize) == FALSE ) + { + PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Failed to get user profile directory"); + return 0; + } + + PrintMessage(MESG_DEBUG, "\n GetFirefoxProfilePath : User Profile directory = %s", profileDir); + + // Get firefox profile directory + strcpy(profilePath, profileDir); + strcat(profilePath,"\\"); + strcat(profilePath,partialPath); + strcat(profilePath,"\\profiles.ini"); + + PrintMessage(MESG_DEBUG, "\n GetFirefoxProfilePath : Firefox profile.ini path = %s ", profilePath); + + +#else // Linux platform.... + + char profileDir[] ="/.mozilla/firefox"; + char profileFile[] ="/.mozilla/firefox/profiles.ini"; + + char line[1024]; + char *profilePath = NULL; + char *homeDir = NULL; + char *finalProfilePath = NULL; + unsigned int i; + + // Get home directory + homeDir = getenv("HOME"); + + if(homeDir == NULL ) + { + PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Unable to get home directory "); + return 0; + } + + profilePath = (char*) malloc( strlen(homeDir) + strlen(profileFile) + 3 ); + if( profilePath == NULL ) + { + PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Insufficient memory "); + return 0; + } + strcpy(profilePath,homeDir); + strcat(profilePath,profileFile); + + PrintMessage(MESG_DEBUG, "\n GetFirefoxProfilePath : Firefox profile dir path = %s ", profilePath); + +#endif + + // Open the firefox profile setting file + FILE *profile = fopen(profilePath, "r"); + + if( profile == NULL ) + { + PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Unable to find firefox profile file : %s ", profilePath); + return NULL; + } + + // Find out the profile path for given profile name + char *temp; + int isProfileFound = 0; + int isRelative = 1; + char *path = NULL; + + while(fgets(line, 1024, profile)) + { + // Remove trailing end of line character + line[strlen(line)-1]= 0; + + // Convert to smaller case until "=" found.... + for(i=0; iprofileName = (char*) malloc(strlen(profileName)+1); + if( !this->profileName ) + { + PrintMessage(MESG_ERROR, "\n ProfileInit : Insufficient memory.."); + return FPM_INSUFFICIENT_MEMORY; + } + + strcpy(this->profileName, profileName); + + + // TODO + // Read the preference from the config file present in the profile... + + isInitialized = FPM_TRUE; + + // Setup the function pointers... + void *funList[9]; + + funList[0] = (void*)NULL ; //PK11SetPasswordFunc; + funList[1] = (void*)PK11GetInternalKeySlot; + funList[2] = (void*)PK11FreeSlot; + funList[3] = (void*)PK11Authenticate; + funList[4] = (void*)PK11CheckUserPassword; + funList[5] = (void*)PK11SDRDecrypt; + funList[6] = (void*)PK11SDREncrypt; + funList[7] = (void*)PLBase64Encode; + funList[8] = (void*)PLBase64Decode; + + signonManager.SetupFunctions(funList); + + return FPM_TRUE; +} + + + +void ProfileManager::ProfileExit() +{ + PrintMessage(MESG_DEBUG, "\n ProfileExit : Shutting down the profile %s", profileName); + + if( (isInitialized == FPM_TRUE) && NSSShutdown != NULL ) + (*NSSShutdown)(); + + if( libnss != NULL ) + FREELIBRARY(libnss); + + if( libplc != NULL ) + FREELIBRARY(libplc); + + // clean up signon data... + signonManager.RemoveSignonData(); + + isInitialized = FPM_FALSE; +} + + + + + + +int ProfileManager::IsMasterPasswordSet() +{ +PK11SlotInfo *slot = 0; +int retValue = 0; + + slot = (*PK11GetInternalKeySlot)(); + + if (!slot) + { + PrintMessage(MESG_ERROR, "\n IsMasterPasswordSet PK11_GetInternalKeySlot failed ..."); + return FPM_FALSE; + } + + PrintMessage(MESG_DEBUG, "\n PK11_GetInternalKeySlot SUCCESS ..."); + + // Check with empty password....If it succeeds then master password is not set + if( (*PK11CheckUserPassword)(slot,"") == SECSuccess ) + { + PrintMessage(MESG_DEBUG, "\n IsMasterPasswordSet : Master password is not set..."); + retValue = FPM_FALSE; + } + else + { + PrintMessage(MESG_DEBUG, "\n IsMasterPasswordSet : Master password is set..."); + retValue = FPM_TRUE; + } + + // Free the slot + (*PK11FreeSlot) (slot); + + return retValue; +} + + + + + + +int ProfileManager::CheckMasterPassword(char *masterPassword, int doSave) +{ +PK11SlotInfo *slot = 0; +int retValue = 0; + + slot = (*PK11GetInternalKeySlot)(); + + if (!slot) + { + PrintMessage(MESG_ERROR, "\n CheckMasterPassword PK11_GetInternalKeySlot failed ..."); + return FPM_FALSE; + } + + + if( (*PK11CheckUserPassword)(slot, masterPassword) == SECSuccess ) + { + // Store the password for internal use... + if( doSave ) + { + PrintMessage(MESG_DEBUG, "\n CheckMasterPassword : saving master password for future use ******..."); + + this->masterPassword = (char *) malloc( strlen(masterPassword)+1 ); + + if( !this->masterPassword ) + { + PrintMessage(MESG_ERROR, "\n CheckMasterPassword : Insufficient memory"); + (*PK11FreeSlot) (slot); // Free the slot... + return FPM_INSUFFICIENT_MEMORY; + } + + strcpy(this->masterPassword, masterPassword); + } + + PrintMessage(MESG_DEBUG, "\n CheckMasterPassword : specified master password is correct..."); + retValue = FPM_TRUE; + } + else + { + PrintMessage(MESG_ERROR, "\n CheckMasterPassword : specified master password is wrong..."); + retValue = FPM_FALSE; + } + + // Free the slot + (*PK11FreeSlot) (slot); + + return retValue; +} + + + + + + +int ProfileManager::GetSignonData( struct Host **host, int doRefresh) +{ +int retValue; + + //TODO NAG: + //check if "remember password" enabled.... + + // Reload the signon data from the file... + if( doRefresh ) + { + retValue = RefreshSignonData(); + *host = signonManager.GetHostInfo(); + return retValue; + } + + // if host list is null read again.... + // TODO NAG : If there is no data , this will cause refresh to happen every time... + + if( signonManager.GetHostInfo() == NULL ) + { + retValue = RefreshSignonData(); + *host = signonManager.GetHostInfo(); + return retValue; + } + + // Just return the previously loaded data + *host = signonManager.GetHostInfo(); + + return FPM_TRUE; +} + + + + +int ProfileManager::RefreshSignonData() +{ + + // First check if master password is correct.... + if( masterPassword ) + { + // Just check for password , don't save.... + if( CheckMasterPassword(masterPassword, 0 ) != FPM_TRUE ) + { + PrintMessage(MESG_ERROR, "\n RefreshSignonData : master password is wrong..can't proceed with signon decryption" ); + return FPM_MASTERPASSWORD_WRONG; + } + } + else // check if master password is set... + { + // master password is set and its not specified + if( IsMasterPasswordSet() == FPM_TRUE ) + { + PrintMessage(MESG_ERROR, "\n RefreshSignonData : master password is set..but its not specified " ); + return FPM_MASTERPASSWORD_WRONG; + } + } + + + return signonManager.LoadSignonData(profilePath); +} + + + + + +int ProfileManager::WriteSignonData() +{ + // First check if master password is correct.... + if( masterPassword ) + { + // Just check for password , don't save.... + if( CheckMasterPassword(masterPassword, 0 ) != FPM_TRUE ) + { + PrintMessage(MESG_ERROR, "\n WriteSignonData : master password is wrong..can't proceed with signon decryption" ); + return FPM_MASTERPASSWORD_WRONG; + } + } + else // check if master password is set... + { + // master password is set and its not specified + if( IsMasterPasswordSet() == FPM_TRUE ) + { + PrintMessage(MESG_ERROR, "\n WriteSignonData : master password is set..but its not specified " ); + return FPM_MASTERPASSWORD_WRONG; + } + } + + + return signonManager.WriteSignonData(profilePath); + +} + + + + +int ProfileManager::AddHost(struct Host *host, int doUpdate) +{ +int retValue; + + if( (retValue = signonManager.AddHost(host)) != FPM_TRUE) + { + PrintMessage(MESG_ERROR, "\n AddHost : Failed to add the host %s ", host->hostName); + return retValue; + } + + if( doUpdate > 0 ) + { + PrintMessage(MESG_ERROR, "\n AddHost : Updating the signon file "); + return WriteSignonData(); + } + + return FPM_TRUE; +} + + + + +int ProfileManager::ModifyHost(struct Host *host, int doUpdate) +{ +int retValue; + + if( (retValue = signonManager.ModifyHost(host)) != FPM_TRUE) + { + PrintMessage(MESG_ERROR, "\n ModifyHost : Failed to modify the host %s ", host->hostName); + return retValue; + } + + + if( doUpdate > 0) + { + PrintMessage(MESG_ERROR, "\n ModifyHost : Updating the signon file "); + return WriteSignonData(); + } + + return FPM_TRUE; + + + +} + + + +int ProfileManager::RemoveHost(char *hostName, int doUpdate) +{ +int retValue; + + if( (retValue = signonManager.RemoveHost(hostName)) != FPM_TRUE) + { + PrintMessage(MESG_ERROR, "\n RemoveHost : Failed to remove the hsot %s ", hostName); + return retValue; + } + + if( doUpdate > 0 ) + { + PrintMessage(MESG_ERROR, "\n RemoveHost : Updating the signon file "); + return WriteSignonData(); + } + + return FPM_TRUE; +} diff --git a/c_adlib/ad_gk/native/ProfileManager.h b/c_adlib/ad_gk/native/ProfileManager.h new file mode 100644 index 00000000..6e6697dc --- /dev/null +++ b/c_adlib/ad_gk/native/ProfileManager.h @@ -0,0 +1,71 @@ + + +#ifndef __FPM_PROFILE_MANAGER_H__ +#define __FPM_PROFILE_MANAGER_H__ + +#include "FirefoxPasswordManager.h" +#include "Common.h" +#include "SignonManager.h" + + +class ProfileManager +{ + SignonManager signonManager; + + char *profilePath; + char *libraryPath; + char *masterPassword; + + HMODULE libnss; + HMODULE libplc; + + // NSS Library function pointers + NSS_Init NSSInit; + NSS_Shutdown NSSShutdown; + //PK11_SetPasswordFunc PK11SetPasswordFunc; + PK11_GetInternalKeySlot PK11GetInternalKeySlot; + PK11_FreeSlot PK11FreeSlot; + PK11_Authenticate PK11Authenticate; + PK11_CheckUserPassword PK11CheckUserPassword; + PK11SDR_Decrypt PK11SDRDecrypt; + PK11SDR_Encrypt PK11SDREncrypt; + + PL_Base64Encode PLBase64Encode; + PL_Base64Decode PLBase64Decode; + +public : + + char *profileName; + int isInitialized; + +private : + + char *GetFirefoxProfilePath(char *profileName); + char *GetFirefoxLibPath(); + HMODULE PMLoadLibrary(char *firefoxDir, char *libName); + int RefreshSignonData(); + + + +public: + + ProfileManager(); + + int ProfileInit(char *profileName); + void ProfileExit(); + + int IsMasterPasswordSet(); + int CheckMasterPassword(char *masterPassword, int doSave); + + int GetSignonData( struct Host **host, int doRefresh); + int WriteSignonData(); + + int AddHost(struct Host *host, int doUpdate); + int ModifyHost(struct Host *host, int doUpdat); + int RemoveHost(char *hostname, int doUpdate); + +}; + + +#endif + diff --git a/c_adlib/ad_gk/native/SignonManager.cpp b/c_adlib/ad_gk/native/SignonManager.cpp new file mode 100644 index 00000000..f3cc900e --- /dev/null +++ b/c_adlib/ad_gk/native/SignonManager.cpp @@ -0,0 +1,650 @@ + +#include "SignonManager.h" + +SignonManager::SignonManager() +{ + signonFile = NULL; +} + + + + +SignonManager::~SignonManager() +{ + +} + + +void SignonManager::SetupFunctions(void *funList[]) +{ + cryptManager.SetupFunctions(funList); +} + + + + +int SignonManager::OpenSignonFile(char *firefoxProfileDir, char *fileName, char *accessType ) +{ +char *signonFilePath = NULL; + + signonFilePath = (char*) malloc( strlen(firefoxProfileDir) + strlen(fileName) + 3 ); + + if( signonFilePath == NULL ) + { + PrintMessage(MESG_ERROR, "\n Insufficient memory ...."); + return FPM_INSUFFICIENT_MEMORY; + } + + strcpy(signonFilePath, firefoxProfileDir); + strcat(signonFilePath, "/"); + strcat(signonFilePath, fileName); + + PrintMessage(MESG_DEBUG, "\n Final signon filename is = %s ", signonFilePath); + + // Open the signon file + signonFile = fopen(signonFilePath, accessType); + + if( signonFile == NULL ) + { + PrintMessage(MESG_ERROR, "\n SignonManager : Error opening signon file %s", signonFilePath); + free(signonFilePath); + return FPM_SIGNON_FILE_NOT_PRESENT; + } + + // cleanup + free(signonFilePath); + + return FPM_TRUE; + +} + + +int SignonManager::CloseSignonFile() +{ + + if( signonFile ) + fclose(signonFile); + + return FPM_TRUE; + +} + + +int SignonManager::ReadLine(char *buffer, int size) +{ + Unichar c; + int strLength = 0, i=0; + + buffer[0] = 0; + + while(1) + { + c = ReadCharUTF8(); + + /* note that eof is not set until we read past the end of the file */ + if ( c == FPM_FALSE ) // || feof(file) ) + return FPM_FALSE; + + if (c == '\n') + { + buffer[strLength++] = 0; + break; + } + + + if (c != '\r') + { + for(i=0; i < 4 && ( (c & 0xff) != 0 ) ; i++) + { + if( strLength >= size ) + { + // Increase the capacity dynamically + PrintMessage(MESG_ERROR, "SignonManager : Buffer is insufficient to store data"); + return FPM_FALSE; + } + + buffer[strLength++] = (char)c; + c = c >> 8; + } + } + } + + + // PrintMessage(MESG_DEBUG,"SignonManager : ReadLine = %s ",buffer); + return FPM_TRUE; + +} + + + + +Unichar SignonManager::ReadCharUTF8() +{ + Unichar c = ReadChar(); + + if ((c & 0x80) == 0x00) + { + return c; + } + else if ((c & 0xE0) == 0xC0) + { + return (((c & 0x1F)<<6) + (ReadChar() & 0x3F)); + } + else if ((c & 0xF0) == 0xE0) + { + return (((c & 0x0F)<<12) + ((ReadChar() & 0x3F)<<6) + (ReadChar() & 0x3F)); + } + + + return FPM_FALSE; // 0 => not a utf8 character... +} + + + + + + +// This does buffered reading... +// +char SignonManager::ReadChar() +{ + const int buflen = 1000; + static char buf[buflen+1]; + static int last = 0; + static int next = 0; + + if (next >= last) + { + next = 0; + last = fread(buf, 1, buflen, signonFile); + PrintMessage(MESG_DEBUG,"\n SignonManager : ReadChar = Read %d bytes ",last); + + if (last <= 0) // || feof(file) + { + /* note that eof is not set until we read past the end of the file */ + PrintMessage(MESG_DEBUG,"\n SignonManager : ReadChar = End of file..! "); + return FPM_FALSE; + } + } + + return (buf[next++]); +} + + + + + +int SignonManager::WriteCharUTF8(Unichar c) +{ + if (c <= 0x7F) + { + if( fputc((char)c, signonFile) == EOF ) + return FPM_SIGNON_FILE_WRITE_ERROR; + } + else if (c <= 0x7FF) + { + if( fputc( ((Unichar)0xC0) | ((c>>6) & 0x1F), signonFile) == EOF ) + return FPM_SIGNON_FILE_WRITE_ERROR; + + if( fputc( ((Unichar)0x80) | (c & 0x3F), signonFile ) == EOF ) + return FPM_SIGNON_FILE_WRITE_ERROR; + + } + else + { + if( fputc( ((Unichar)0xE0) | ((c>>12) & 0xF), signonFile) == EOF ) + return FPM_SIGNON_FILE_WRITE_ERROR; + if( fputc( ((Unichar)0x80) | ((c>>6) & 0x3F), signonFile) == EOF) + return FPM_SIGNON_FILE_WRITE_ERROR; + if( fputc( ((Unichar)0x80) | (c & 0x3F), signonFile) == EOF) + return FPM_SIGNON_FILE_WRITE_ERROR; + } + + return FPM_TRUE; +} + + + +int SignonManager::WriteLine(char *line) +{ + + for(int i=0; i < strlen(line); i++) + { + if( WriteCharUTF8(line[i]) != FPM_TRUE ) + return FPM_SIGNON_FILE_WRITE_ERROR; + + } + + if( WriteCharUTF8('\n') != FPM_TRUE ) + return FPM_SIGNON_FILE_WRITE_ERROR; + + return FPM_TRUE; + +} + + + + +/* +* Load the signon data from firefox signon file..... +* +* +*/ +int SignonManager::LoadSignonData(char *firefoxProfileDir ) +{ +char header[256]; +char buffer[4096]; +char hostName[4096]; +char name[1024]; +int bufferLength = 4095; +int retValue; +char *clearData = NULL; +int count = 0; + + + // open the signon file + if( (retValue = OpenSignonFile(firefoxProfileDir, SIGNON_FILE_NAME, "r")) != FPM_TRUE ) + { + return retValue; + } + + // Clean up any previously loaded data... + dataManager.RemoveAllData(); + + // read the signon header information + if( ReadLine(header, 256) != FPM_TRUE ) + { + PrintMessage(MESG_ERROR, "\n SignonManager : Error in reading signon format header %s", header); + CloseSignonFile(); + return FPM_SIGNON_FILE_READ_ERROR; + } + + // check if the format is right... + if( strcmp(header, HEADER_VERSION) != 0) + { + PrintMessage(MESG_ERROR, "\n SignonManager : Header version information is not proper"); + CloseSignonFile(); + return FPM_SIGNON_FILE_INVALID_DATA; + } + + + PrintMessage(MESG_DEBUG, "\n\n ****** Reject Host List *******"); + + // read the reject list + while ( ReadLine(buffer, bufferLength) == FPM_TRUE) + { + // Check for end of reject list i.e full stop + if (strlen(buffer) != 0 && buffer[0] == '.') + { + break; // end of reject list + } + + if( (retValue = dataManager.AddRejectHost(buffer) ) != FPM_TRUE ) + { + CloseSignonFile(); + dataManager.RemoveAllData(); // clean up any partial loaded data + + return retValue; + } + + PrintMessage(MESG_DEBUG, "\n Reject Host : %s ", buffer); + + } + + + PrintMessage(MESG_DEBUG, "\n\n ****** Host list with username / password ****** "); + + + while (ReadLine(hostName, bufferLength) == FPM_TRUE) + { + // a blank line is perfectly valid here -- corresponds to a local file + if (strlen(hostName) < 1) + { + PrintMessage(MESG_ERROR, "\n SignonManager : Host URL is not proper"); + CloseSignonFile(); + dataManager.RemoveAllData(); // clean up partial loaded data + + return FPM_ILLEGAL_HOSTNAME; + } + + if( ( retValue = dataManager.AddHost(hostName) ) != FPM_TRUE ) + { + CloseSignonFile(); + dataManager.RemoveAllData(); // clean up partial loaded data + + return retValue; + } + + + PrintMessage(MESG_DEBUG, "\n\n Host : %s ", hostName); + + // prepare to read the name/value pairs + while( ReadLine(buffer, bufferLength) == FPM_TRUE ) + { + // line starting with . terminates the pairs for this URL entry + if (buffer[0] == '.') + { + break; // end of URL entry + } + + // save the name part and determine if it is a password + unsigned char isPassword = 0; + if (buffer[0] == '*') + { + isPassword = 1; + strcpy(name,&buffer[1]); + retValue = ReadLine(buffer, bufferLength); + } + else + { + isPassword = 0; + strcpy(name, buffer); + retValue = ReadLine(buffer, bufferLength); + } + + PrintMessage(MESG_DEBUG, "\n\n name = %s and value = %s ", name, buffer); + + // read in and save the value part + if ( retValue != FPM_TRUE ) + { + // error in input file so give up + PrintMessage(MESG_ERROR, "\n SignonManager : Error occured while reading VALUE for : %s ", name); + CloseSignonFile(); + dataManager.RemoveAllData(); // clean up partial loaded data + + return FPM_SIGNON_FILE_READ_ERROR; + } + + // Decrypt the encrypted value.... + retValue = FPM_FALSE; + if( ((retValue = cryptManager.DecryptString(buffer, &clearData)) == FPM_TRUE) && (clearData != NULL) ) + { + // Add the name/value pair to the existing store.... + retValue = dataManager.AddHostElement(hostName, name, clearData, isPassword); + + if( retValue != FPM_TRUE ) + { + CloseSignonFile(); + dataManager.RemoveAllData(); // clean up partial loaded data + return retValue; + } + } + else + { + + CloseSignonFile(); + dataManager.RemoveAllData(); // clean up partial loaded data + + return retValue; + } + + } + + } + + + // Now close the signon file + CloseSignonFile(); + + // Print data for cross checking +#ifdef DEBUG + dataManager.PrintAllRejectHosts(); + dataManager.PrintAllHosts(); +#endif + return FPM_TRUE; + +} + + +int SignonManager::WriteSignonData(char *firefoxProfileDir) +{ +int retValue; +char *cryptData = NULL; +char *signonFilePath = NULL; +char *tempFilePath = NULL; +char fileName[256]; + +Host *t; +HostElement *h; +RejectHost *r; + + // TODO : If signon data has not changed since last write then return... +/* // There may be requirement to write empty data... + if( dataManager.hostList == NULL ) + { + PrintMessage(MESG_ERROR, "\n WriteSignonData : Signon data is empty..."); + return FPM_SIGNON_DATASTORE_EMPTY; + } +*/ + + // Generate random file name + srand( (unsigned)time( NULL ) ); + sprintf(fileName,"signon_fpm_%d.txt", rand()); + + // Setup the signon and temp filename.. + signonFilePath = (char*) malloc( strlen(firefoxProfileDir) + strlen(SIGNON_FILE_NAME) + 3); + tempFilePath =(char*) malloc( strlen(firefoxProfileDir) + strlen(fileName) + 3); + + if( signonFilePath == NULL || tempFilePath == NULL) + { + PrintMessage(MESG_ERROR, "\n WriteSignonData : Insufficient memory ...."); + return FPM_INSUFFICIENT_MEMORY; + } + + strcpy(signonFilePath, firefoxProfileDir); + strcat(signonFilePath, "/"); + strcat(signonFilePath, SIGNON_FILE_NAME); + + strcpy(tempFilePath, firefoxProfileDir); + strcat(tempFilePath, "/"); + strcat(tempFilePath, fileName); + + // Open signon file + if( (retValue = OpenSignonFile(firefoxProfileDir, fileName, "w")) != FPM_TRUE ) + { + PrintMessage(MESG_ERROR, "\nWriteSignonData : Failed to create temp signon file : %s.", fileName); + return retValue; + } + + + // write out the format revision number + if( (retValue = WriteLine(HEADER_VERSION)) != FPM_TRUE) + goto write_signon_error; + + // write out reject host list + for(r=dataManager.rejectHostList; r ; r=r->next) + { + if( (retValue = WriteLine(r->hostName)) != FPM_TRUE ) + goto write_signon_error; + + } + + // End of reject host list + if( (retValue = WriteLine(".")) != FPM_TRUE ) + goto write_signon_error; + + + /* format for cached logins shall be: + * url LINEBREAK {name LINEBREAK value LINEBREAK}* . LINEBREAK + * if type is password, name is preceded by an asterisk (*) + */ + + + // write out each URL node + for(t=dataManager.hostList; t ; t=t->next) + { + PrintMessage(MESG_DEBUG, "\n\nWriteSignonData : Adding name/value pairs for host %s", t->hostName); + + if( (retValue = WriteLine(t->hostName)) != FPM_TRUE ) + goto write_signon_error; + + + for(h=t->child; h ; h= h->next) + { + PrintMessage(MESG_DEBUG, "\n nWriteSignonData : %s : %s ", h->name, h->value); + + if( h->isPassword) + { + if( (retValue = WriteCharUTF8('*')) != FPM_TRUE ) + goto write_signon_error; + } + + if( (retValue = WriteLine(h->name)) != FPM_TRUE ) + goto write_signon_error; + + + // encrypt the value + retValue = FPM_FALSE; + retValue = cryptManager.EncryptString(h->value, &cryptData); + + if( (retValue == FPM_TRUE) && (cryptData != NULL )) + { + if( (retValue = WriteLine(cryptData)) != FPM_TRUE ) + goto write_signon_error; + } + else + { + PrintMessage(MESG_ERROR, "\n nWriteSignonData : Encryption of value %s failed ", h->value); + goto write_signon_error; + } + } + + if( (retValue = WriteLine(".")) != FPM_TRUE ) + goto write_signon_error; + } + + // close this temporary file... + CloseSignonFile(); + + + PrintMessage(MESG_DEBUG, "\n WriteSignonData : Removing previous signon file %s ", signonFilePath); + + // Delete previous signon file + if( remove(signonFilePath) != 0 ) + { + // Either file not present or file is locked... + PrintMessage(MESG_ERROR, "\n WriteSignonData : Failed to delete signon file : %s ", signonFilePath); + FILE *sfile= NULL; + if( (sfile = fopen(signonFilePath,"r") ) != NULL ) + { + // we are able to open signon file in read only mode => file is present + fclose(sfile); + remove(tempFilePath); // delete temporary signon file + + PrintMessage(MESG_ERROR, "\nWriteSignonData : Signon file is locked "); + return FPM_SIGNON_FILE_LOCKED; + } + + // File is not present ..that's good news , so continue... + } + + PrintMessage(MESG_DEBUG, "success \n WriteSignonData : Renaming temp file %s back to signon file %s ", tempFilePath, signonFilePath); + + // Rename temp file back to signon file + if( ( retValue = rename(tempFilePath, signonFilePath) ) != 0 ) + { + PrintMessage(MESG_ERROR, "\n WriteSignonData : Failed to rename the temp file %s back to signon file %s ", tempFilePath, signonFilePath); + PrintMessage(MESG_ERROR, "\n WriteSignonData : Following error has occured : %d ", retValue); + + return FPM_FALSE; + } + + PrintMessage(MESG_DEBUG, "\n WriteSignonData : Successfully written new signon data ..."); + + return FPM_TRUE; + +write_signon_error: + + CloseSignonFile(); + remove(tempFilePath); // remove the temporary signon file.... + + return retValue; +} + + + +int SignonManager::RemoveSignonData() +{ + + return dataManager.RemoveAllData(); + +} + + +int SignonManager::AddHost(struct Host *host) +{ + + return dataManager.AddHost(host); + +} + + +int SignonManager::ModifyHost(struct Host *host) +{ + + return dataManager.ModifyHost(host); + +} + + + +int SignonManager::RemoveHost(char *hostName) +{ + return dataManager.RemoveHost(hostName); +} + + + + +struct Host * SignonManager::GetHostInfo() +{ + + return dataManager.hostList; +} + + +int SignonManager::AddUser(char *host, char *userName, char *password) +{ +char checkString[]="test123"; +char *cryptData = NULL; +char *clearData = NULL; +char *newdata = NULL; + /* + // TODO : check if signon preference enabled.... + if( CheckSignonPref() == FPM_FALSE ) + { + PrintMessage(MESG_ERROR, "\n MCSignonManager : Signon preference is not enabled..."); + return FPM_FALSE; + } + + + if( EncryptString ("test123", &cryptData) == FPM_FALSE ) + { + PrintMessage(MESG_ERROR, "\n MCSignonManager : fAILED TO EncryptString"); + return FPM_FALSE; + } + + newdata = (char*) malloc(strlen(cryptData) + 1); + strcpy(newdata, cryptData); + + if( DecryptString(newdata, &clearData) == FPM_FALSE ) + { + PrintMessage(MESG_ERROR, "\n MCSignonManager : Failed to DecryptString"); + return FPM_FALSE; + } + + printf("\n final decrypted string is : %s ", clearData); + + if( strcmp(checkString, clearData) == 0 ) + { + printf("\n Encryption - decryption test is success "); + } + else + printf("\n Encryption - decryption test is FAILED "); + */ + return FPM_TRUE; + + +} + + diff --git a/c_adlib/ad_gk/native/SignonManager.h b/c_adlib/ad_gk/native/SignonManager.h new file mode 100644 index 00000000..516b34c8 --- /dev/null +++ b/c_adlib/ad_gk/native/SignonManager.h @@ -0,0 +1,56 @@ +// SignonManager.h: interface for the SignonManager class. +// +////////////////////////////////////////////////////////////////////// + +#ifndef __FPM_SIGNON_MANAGER_H__ +#define __FPM_SIGNON_MANAGER_H__ + + + +#include "FirefoxPasswordManager.h" +#include "Common.h" +#include "DataManager.h" +#include "CryptManager.h" + + +class SignonManager +{ + + DataManager dataManager; + CryptManager cryptManager; + FILE *signonFile; + +public: + SignonManager(); + virtual ~SignonManager(); + + int OpenSignonFile(char *firefoxProfileDir, char *fileName, char *accessType ); + int CloseSignonFile(); + + int ReadLine(char *buffer, int size); + char ReadChar(); + Unichar ReadCharUTF8(); + int WriteCharUTF8(Unichar c); + int WriteLine(char *line); + + + int LoadSignonData(char *firefoxProfileDir); + int WriteSignonData(char *firefoxProfileDir); + int RemoveSignonData(); + + int AddUser(char *host, char *userName, char *password); + int RemoveHost(char *hostName); + int ModifyHost(struct Host *host); + int AddHost(struct Host *host); + + + struct Host* GetHostInfo(); + void SetupFunctions(void *funList[]); + + + int CheckSignonPref(); + +}; + +#endif + diff --git a/c_adlib/ad_gk/native/link.lux b/c_adlib/ad_gk/native/link.lux index 4798177b..019f3c26 100644 --- a/c_adlib/ad_gk/native/link.lux +++ b/c_adlib/ad_gk/native/link.lux @@ -1,15 +1,5 @@ LINK = $(CPP) \ - -Wl,-Bsymbolic \ -shared \ - -pthread\ - -O2 -fno-exceptions -fno-check-new\ - -Wl,-rpath -Wl,/usr/lib$(ARC) \ - -L/usr/lib$(ARC) -lpthread -lc -ldl \ - -L/opt/gnome/lib$(ARC) -lglib-2.0 \ - -Wl,-soname -Wl,lib$(TARGET).so.$(PROD_NUM) \ + -Wl \ -o $(LIBDIR)$(XTRA)/lib$(TARGET).so.$(BLD_VER) \ - -L$(LIBDIR)$(XTRA) \ $(OBJDIR)*.$(O) - - - diff --git a/c_adlib/ad_gk/native/objs.lux b/c_adlib/ad_gk/native/objs.lux index 50130ebf..25e959c6 100644 --- a/c_adlib/ad_gk/native/objs.lux +++ b/c_adlib/ad_gk/native/objs.lux @@ -1,2 +1,7 @@ OBJS=\ - ad_gk.$(O) + Common.$(O) \ + CryptManager.$(O) \ + FirefoxPasswordManager.$(O) \ + ProfileManager.$(O) \ + SignonManager.$(O) \ + DataManager.$(O)