985 lines
24 KiB
C++
985 lines
24 KiB
C++
/***********************************************************************
|
|
*
|
|
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; version 2.1
|
|
* of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, Novell, Inc.
|
|
*
|
|
* To contact Novell about this file by physical or electronic mail,
|
|
* you may find current contact information at www.novell.com.
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include "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_DEBUG, "\n\n LoadLibrary : Failed to load library %s ", loadPath);
|
|
free(loadPath);
|
|
return 0;
|
|
}
|
|
|
|
free(loadPath);
|
|
|
|
return libtmp;
|
|
}
|
|
|
|
//
|
|
// Checks if store is available...
|
|
//
|
|
int ProfileManager::IsStoreAvailable()
|
|
{
|
|
|
|
PrintMessage(MESG_DEBUG, "\n IsStoreAvailable : Checking if firefox and its libraries are present ");
|
|
|
|
|
|
|
|
libraryPath = GetFirefoxLibPath();
|
|
|
|
if( !libraryPath )
|
|
{
|
|
PrintMessage(MESG_ERROR, "\n IsStoreAvailable : Failed to find firefox profile or library path ");
|
|
return FPM_FALSE;
|
|
}
|
|
|
|
// First check if firefox binary is present....
|
|
// Because on NLD, NSS library is no longer shipped with firefox.
|
|
// Hence NSS libraries will still be there even if firefox is removed :)
|
|
#ifdef WIN32
|
|
|
|
char *firefox_bin_file = (char*) malloc(strlen(libraryPath)+ strlen("firefox.exe") + 2);
|
|
if( !firefox_bin_file )
|
|
{
|
|
PrintMessage(MESG_ERROR, "\n IsStoreAvailable : Insufficient memory..malloc failed \n");
|
|
return FPM_FALSE;
|
|
}
|
|
|
|
strcpy(firefox_bin_file,libraryPath);
|
|
strcat(firefox_bin_file,"\\firefox.exe");
|
|
|
|
FILE *firefox_bin = fopen(firefox_bin_file,"r");
|
|
|
|
if( firefox_bin == NULL)
|
|
{
|
|
PrintMessage(MESG_ERROR, "\n IsStoreAvailable : Failed to find firefox binary file %s\n", firefox_bin_file);
|
|
free(firefox_bin_file);
|
|
return FPM_FALSE;
|
|
}
|
|
|
|
free(firefox_bin_file);
|
|
fclose(firefox_bin);
|
|
|
|
#else
|
|
|
|
FILE *firefox_bin = fopen("/usr/bin/firefox","r");
|
|
|
|
if( firefox_bin == NULL)
|
|
{
|
|
PrintMessage(MESG_ERROR, "\n IsStoreAvailable : Failed to find firefox binary file /usr/bin/firefox \n");
|
|
return FPM_FALSE;
|
|
}
|
|
|
|
fclose(firefox_bin);
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Next 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 IsStoreAvailable : Failed to load the required firefox library");
|
|
return FPM_FALSE;
|
|
}
|
|
|
|
// Free the library
|
|
if( libnss != NULL )
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n IsStoreAvailable : Freeing library libnss.dll");
|
|
FREELIBRARY(libnss);
|
|
}
|
|
|
|
if( libplc != NULL )
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n IsStoreAvailable : Freeing library libplc.dll");
|
|
FREELIBRARY(libplc);
|
|
}
|
|
|
|
return FPM_TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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 firefox library");
|
|
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()
|
|
{
|
|
int i;
|
|
|
|
PrintMessage(MESG_DEBUG, "\n ProfileExit : Shutting down the profile %s", profileName);
|
|
|
|
if( (isInitialized == FPM_TRUE) && NSSShutdown != NULL )
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n ProfileExit : invoking NSSShutdown for profile", profileName);
|
|
for(i=0; (i<5) && ((*NSSShutdown)() == SECFailure); i++ )
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n ProfileExit %d: NSSShutdown : FAILURE",i);
|
|
//Sleep(500);
|
|
}
|
|
|
|
if( i != 5)
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n ProfileExit :NSSShutdown : SUCCESS");
|
|
|
|
}
|
|
else
|
|
PrintMessage(MESG_DEBUG, "\n ProfileExit : NSSShutdown : FAILURE");
|
|
|
|
}
|
|
|
|
if( libnss != NULL )
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n ProfileExit : Freeing library libnss.dll");
|
|
FREELIBRARY(libnss);
|
|
}
|
|
|
|
if( libplc != NULL )
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n ProfileExit : Freeing library libplc.dll");
|
|
FREELIBRARY(libplc);
|
|
}
|
|
|
|
// clean up signon data...
|
|
signonManager.RemoveSignonData();
|
|
|
|
isInitialized = FPM_FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ProfileManager::IsMasterPasswordSet()
|
|
{
|
|
PK11SlotInfo *slot = 0;
|
|
int retValue = 0;
|
|
SECStatus status;
|
|
|
|
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
|
|
|
|
status = (*PK11CheckUserPassword)(slot,"");
|
|
if( status == SECSuccess )
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n IsMasterPasswordSet : Master password is not set...");
|
|
retValue = FPM_FALSE;
|
|
}
|
|
else if(status == SECWouldBlock ) // password is wrong
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n IsMasterPasswordSet : Master password is set...");
|
|
retValue = FPM_TRUE;
|
|
}
|
|
else // something is wrong, may be key3.db is not initialized for crypt
|
|
{
|
|
PrintMessage(MESG_DEBUG, "\n IsMasterPasswordSet : Master password is not set...");
|
|
retValue = FPM_FALSE;
|
|
}
|
|
|
|
// 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;
|
|
}
|