diff --git a/CASA.changes b/CASA.changes index 4508681c..02a9ce1a 100644 --- a/CASA.changes +++ b/CASA.changes @@ -1,3 +1,7 @@ +------------------------------------------------------------------- +Mon Apr 10 9:41:10 MST 2006 - jnorman@novell.com +- Bug 154548. Fix to display firefox secrets in CASAManager. + ------------------------------------------------------------------- Tue Apr 4 14:24:10 MST 2006 - jnorman@novell.com - added timer to suppress viewing values(passwords) for micasa store diff --git a/c_adlib/ad_ff/native/SignonManager.cpp b/c_adlib/ad_ff/native/SignonManager.cpp index 2e598932..5cb29bc3 100644 --- a/c_adlib/ad_ff/native/SignonManager.cpp +++ b/c_adlib/ad_ff/native/SignonManager.cpp @@ -1,628 +1,637 @@ -/*********************************************************************** - * - * 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 "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; -} - - - - +/*********************************************************************** + * + * 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 "SignonManager.h" + +// Static data to keep track of buffers +// Look at function ReadChar + static int last = 0; + static int next = 0; + + + + + +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; + + // Clean up previous buffers + last = 0; + next = 0; + + + 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]; + + 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; +} + + + +