This commit is contained in:
Manohar 2006-02-28 11:21:45 +00:00
parent 28ece0abc4
commit dde3fd2be0
12 changed files with 0 additions and 3598 deletions

View File

@ -1,91 +0,0 @@
#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<n; i++)
{
if( str[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
}

View File

@ -1,53 +0,0 @@
#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

View File

@ -1,432 +0,0 @@
#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;
}

View File

@ -1,41 +0,0 @@
#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

View File

@ -1,587 +0,0 @@
#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;
}

View File

@ -1,44 +0,0 @@
#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

View File

@ -1,591 +0,0 @@
#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<strlen(line); i++)
{
if( line[i] == '=' )
break;
if( line[i] >=65 && line[i]<=90 )
line[i]+=32;
}
if( strstr(line, "name=") != NULL )
profileCount++;
}
PrintMessage(MESG_DEBUG, "\n GetProfileList : Total profiles found = %d ", profileCount);
if( profileCount == 0 )
{
fclose(profile);
return FPM_FALSE;
}
*profileList = ( char**) malloc(profileCount * sizeof (char *));
*profileFlag = ( int * ) malloc(profileCount * sizeof(int));
if( *profileList == NULL || *profileFlag == NULL )
{
PrintMessage(MESG_ERROR, "\n GetProfileList : Insufficient memory ");
fclose(profile);
return FPM_FALSE;
}
char **profList = *profileList;
int *profFlag = *profileFlag;
// Now read the profile names and store it..
fseek(profile, 0, SEEK_SET);
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<strlen(line); i++)
{
if( line[i] == '=' )
break;
if( line[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;
}
*/

View File

@ -1,164 +0,0 @@
#ifndef __FPM_Firefox_Password_MANAGER_H__
#define __FPM_Firefox_Password_MANAGER_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#ifdef WIN32
#include <windows.h>
#include <userenv.h>
#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 <dlfcn.h>
#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

View File

@ -1,818 +0,0 @@
#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; i<strlen(line); i++)
{
if( line[i] == '=' )
break;
if( line[i] >=65 && line[i]<=90 )
line[i]+=32;
}
if( isProfileFound )
{
temp = strchr(line,'=') + 1;
// check for IsRelative=
if( strstr(line, "isrelative=") != NULL )
{
// Is the value greater than 0 ( ascii 48 )
isRelative = (*temp > 48)? 1 : 0 ;
continue;
}
// check for Path=
if( strstr(line, "path=") != NULL )
{
path = (char*) malloc(strlen(temp) + 1);
if( !path )
{
PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Insufficient memory ");
fclose(profile);
return 0;
}
strcpy(path,temp);
continue;
}
// Break once you encounter next profile
if( strstr(line, "profile") != NULL )
{
break;
}
}
if( strstr(line, "name=") != NULL )
{
temp = strchr(line,'=') + 1;
if( STRCMPI(temp, profileName) == 0 )
{
PrintMessage(MESG_DEBUG, "\n GetFirefoxProfilePath : Profile name [%s] found ", profileName);
isProfileFound = 1;
}
}
}
fclose(profile);
if( !isProfileFound )
{
PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Specified Profile [%s] not present ", profileName);
return NULL;
}
if( !path )
{
PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Profile [%s] path not found ", profileName);
return NULL;
}
if( isRelative )
{
#ifdef WIN32
// if path contains '/' then make it '\\'
char *slash = strstr(path,"/");
if( slash != NULL )
*slash = '\\';
int totalLen = strlen(profileDir) + strlen(partialPath) + strlen(path) + 3 ;
finalProfilePath = (char *) malloc(totalLen);
if( finalProfilePath )
{
strcpy(finalProfilePath,profileDir);
strcat(finalProfilePath,"\\");
strcat(finalProfilePath,partialPath);
strcat(finalProfilePath,"\\");
strcat(finalProfilePath,path);
PrintMessage(MESG_DEBUG, "\n Final profile path is : %s ", finalProfilePath);
}
#else // Linux platform
int totalLen = strlen(homeDir) + strlen(profileDir) + strlen(path) + 2 ;
finalProfilePath = (char *) malloc(totalLen);
if( finalProfilePath )
{
strcpy(finalProfilePath,homeDir);
strcat(finalProfilePath,profileDir);
strcat(finalProfilePath,"/");
strcat(finalProfilePath,path);
PrintMessage(MESG_DEBUG, "\n Final profile path is : %s ", finalProfilePath);
}
#endif
if(path)
free(path);
}
else
{
finalProfilePath = path;
}
if( !finalProfilePath)
{
PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Insufficient memory ");
return NULL;
}
// check if profile directory exists.....
if( !IsDirectoryExists(finalProfilePath) )
{
PrintMessage(MESG_ERROR, "\n GetFirefoxProfilePath : Profile directory [%s] does not exist", finalProfilePath);
free(finalProfilePath);
return NULL;
}
return finalProfilePath;
}
char* ProfileManager::GetFirefoxLibPath()
{
char *firefoxPath = NULL;
#ifdef WIN32
char regSubKey[] = "SOFTWARE\\Clients\\StartMenuInternet\\firefox.exe\\shell\\open\\command";
char pathValue[MAX_PATH] ="";
DWORD pathSize = MAX_PATH;
DWORD valueType;
HKEY rkey;
// Open firefox registry key
if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, regSubKey, 0, KEY_READ, &rkey) != ERROR_SUCCESS )
{
PrintMessage(MESG_ERROR, "\n GetFirefoxLibPath : Failed to open the firefox registry key : HKCU\\%s", regSubKey );
return NULL;
}
// Read the firefox path value
if( RegQueryValueEx(rkey, NULL, 0, &valueType, (unsigned char*)&pathValue, &pathSize) != ERROR_SUCCESS )
{
PrintMessage(MESG_ERROR, "\n GetFirefoxLibPath : Failed to read the firefox path value from registry ");
RegCloseKey(rkey);
return NULL;
}
if( pathSize <= 0 || pathValue[0] == 0)
{
PrintMessage(MESG_ERROR, "\n GetFirefoxLibPath : Path value read from the registry is empty");
RegCloseKey(rkey);
return NULL;
}
RegCloseKey(rkey);
// This path may contain extra double quote....
if( pathValue[0] == '\"' )
{
for(unsigned int i=0; i< strlen(pathValue)-1 ; i++)
pathValue[i] = pathValue[i+1];
}
PrintMessage(MESG_DEBUG, "\n GetFirefoxLibPath : Path value read from registry is %s", pathValue);
StrLwr(pathValue);
char *firefox = strstr(pathValue, "firefox.exe");
if( firefox == NULL )
{
PrintMessage(MESG_ERROR, "\n GetFirefoxLibPath : Path value read from registry is invalid");
return NULL;
}
// remove the firefox.exe from the end...
*(firefox-1) = 0;
firefoxPath = (char*) malloc( strlen(pathValue) + 1);
if( firefoxPath )
{
strcpy(firefoxPath, pathValue);
if( !IsDirectoryExists(firefoxPath) )
{
free(firefoxPath);
return NULL;
}
}
#else // Linux platform...
char path[]="/opt/MozillaFirefox/lib";
firefoxPath = (char*) malloc( strlen(path) + 1);
if( firefoxPath )
{
strcpy(firefoxPath, path);
}
#endif
PrintMessage(MESG_DEBUG, "\n GetFirefoxLibPath : Firefox library path = [%s] ", firefoxPath);
return firefoxPath;
}
HMODULE ProfileManager::PMLoadLibrary(char *firefoxDir, char *libName)
{
char *loadPath;
HMODULE libtmp = NULL;
if( firefoxDir != NULL )
loadPath = ( char*) malloc(strlen(firefoxDir) + strlen(libName) + 2);
else
loadPath = ( char*) malloc(strlen(libName) + 1);
if( !loadPath )
{
PrintMessage(MESG_ERROR, "\n\n LoadLibrary : Insufficient memory");
return 0;
}
if( firefoxDir != NULL )
{
strcpy(loadPath, firefoxDir);
strcat(loadPath, "/");
strcat(loadPath, libName);
}
else
{
strcpy(loadPath, libName);
}
libtmp = LOADLIBRARY(loadPath);
if( !libtmp )
{
PrintMessage(MESG_ERROR, "\n\n LoadLibrary : Failed to load library %s ", loadPath);
free(loadPath);
return 0;
}
free(loadPath);
return libtmp;
}
// Public functions...
int ProfileManager::ProfileInit(char *profileName)
{
if( isInitialized == FPM_TRUE)
{
PrintMessage(MESG_DEBUG, "\n ProfileInit : Firefox profile [%s] is already initialized ", profileName);
return FPM_TRUE;
}
profilePath = GetFirefoxProfilePath(profileName);
libraryPath = GetFirefoxLibPath();
if( !profilePath || !libraryPath )
{
PrintMessage(MESG_ERROR, "\n ProfileInit : Failed to find firefox profile or library path ");
return FPM_PROFILE_NOT_PRESENT;
}
PrintMessage(MESG_DEBUG, "\n Profile path = [%s] ", profilePath);
PrintMessage(MESG_DEBUG, "\n Library path = [%s] ", libraryPath);
// First try to load from the library path then try to load from default lib path
// Here we have to first load all dependent libraries and then
// load main library , otherwise face the problems...:)
if( PMLoadLibrary(libraryPath, NSPR_LIBRARY_NAME) )
{
if((libplc=PMLoadLibrary(libraryPath, PLC_LIBRARY_NAME)) )
{
if( PMLoadLibrary(libraryPath, PLDS_LIBRARY_NAME) )
{
if( PMLoadLibrary(libraryPath, SOFTN_LIBRARY_NAME) )
libnss=PMLoadLibrary(libraryPath, NSS_LIBRARY_NAME);
}
}
}
else // try to load library from default library path
{
if( PMLoadLibrary(NULL, NSPR_LIBRARY_NAME) )
{
if((libplc=PMLoadLibrary(NULL, PLC_LIBRARY_NAME)) )
{
if( PMLoadLibrary(NULL, PLDS_LIBRARY_NAME) )
{
if( PMLoadLibrary(NULL, SOFTN_LIBRARY_NAME) )
libnss=PMLoadLibrary(NULL, NSS_LIBRARY_NAME);
}
}
}
}
if( !libnss || !libplc )
{
PrintMessage(MESG_ERROR, "\n ProfileInit : Failed to load the required library from directory %s", libraryPath);
return FPM_LIBRARY_LOAD_FAILED;
}
PrintMessage(MESG_DEBUG, "\n ProfileInit : Required libraries are loaded from firefox path successfully..");
// Get all the functions from NSS library
NSSInit = (NSS_Init) GETPROCADDRESS(libnss, "NSS_Init");
NSSShutdown = (NSS_Shutdown)GETPROCADDRESS(libnss, "NSS_Shutdown");
//PK11SetPasswordFunc = (PK11_SetPasswordFunc) GETPROCADDRESS(libnss, "PK11_SetPasswordFunc");
PK11GetInternalKeySlot = (PK11_GetInternalKeySlot) GETPROCADDRESS(libnss, "PK11_GetInternalKeySlot");
PK11FreeSlot = (PK11_FreeSlot) GETPROCADDRESS(libnss, "PK11_FreeSlot");
PK11Authenticate = (PK11_Authenticate) GETPROCADDRESS(libnss, "PK11_Authenticate");
PK11SDRDecrypt = (PK11SDR_Decrypt) GETPROCADDRESS(libnss, "PK11SDR_Decrypt");
PK11SDREncrypt = (PK11SDR_Encrypt) GETPROCADDRESS(libnss, "PK11SDR_Encrypt");
PK11CheckUserPassword = (PK11_CheckUserPassword) GETPROCADDRESS(libnss, "PK11_CheckUserPassword");
if( !NSSInit || !NSSShutdown || !PK11GetInternalKeySlot || !PK11Authenticate || !PK11SDRDecrypt || !PK11SDREncrypt || !PK11FreeSlot || !PK11CheckUserPassword)
{
PrintMessage(MESG_ERROR, "\n\n ProfileInit : Failed to get function address for library %s ", NSS_LIBRARY_NAME);
ProfileExit();
return FPM_LIBRARY_LOAD_FAILED;
}
// Get all the functions from PLC library
PLBase64Encode = ( PL_Base64Encode ) GETPROCADDRESS(libplc, "PL_Base64Encode");
PLBase64Decode = ( PL_Base64Decode ) GETPROCADDRESS(libplc, "PL_Base64Decode");
if( !PLBase64Encode || !PLBase64Decode )
{
PrintMessage(MESG_ERROR, "\nProfileInit : Failed to get function address for library %s ", PLC_LIBRARY_NAME);
ProfileExit();
return FPM_LIBRARY_LOAD_FAILED;
}
// Initialize the NSS library
if( (*NSSInit) (profilePath) != SECSuccess )
{
PrintMessage(MESG_ERROR, "\n ProfileInit : Initialization failed , Make sure key3.db and cert8.db");
PrintMessage(MESG_ERROR, "\n files are present in the specified directory\n");
ProfileExit();
return FPM_LIBRARY_INIT_FAILED;
}
PrintMessage(MESG_DEBUG, "\n ProfileInit : NSS_Init success..");
// Copy the profile name for later use
this->profileName = (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;
}

View File

@ -1,71 +0,0 @@
#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

View File

@ -1,650 +0,0 @@
#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;
}

View File

@ -1,56 +0,0 @@
// 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