⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwscore.cpp

📁 Password Safe Password Safe is a password database utility. Users can keep their passwords securely
💻 CPP
字号:
// file PWScore.cpp//-----------------------------------------------------------------------------#pragma warning(push,3) // sad that VC6 cannot cleanly compile standard headers#include <fstream> // for WritePlaintextFile#include <iostream>#include <string>#include <vector>#pragma warning(pop)#pragma warning(disable : 4786)using namespace std;#include "PWScore.h"#include "BlowFish.h"#include "PWSprefs.h"PWScore::PWScore() : m_currfile(_T("")), m_changed(false),		     m_usedefuser(false), m_defusername(_T("")),		     m_ReadFileVersion(PWSfile::UNKNOWN_VERSION),		     m_passkey(NULL), m_passkey_len(0){  int i;  srand((unsigned)time(NULL));  CItemData::SetSessionKey(); // per-session initialization  for (i = 0; i < sizeof(m_session_key); i++)    m_session_key[i] = newrand();  for (i = 0; i < sizeof(m_session_salt); i++)    m_session_salt[i] = newrand();}PWScore::~PWScore(){  if (m_passkey_len > 0) {    trashMemory(m_passkey, ((m_passkey_len + 7)/8)*8);    delete[] m_passkey;  }}voidPWScore::ClearData(void){  if (m_passkey_len > 0) {    trashMemory(m_passkey, ((m_passkey_len + 7)/8)*8);    delete[] m_passkey;    m_passkey_len = 0;  }  //Composed of ciphertext, so doesn't need to be overwritten  m_pwlist.RemoveAll();}voidPWScore::NewFile(const CMyString &passkey){   ClearData();   SetPassKey(passkey);   m_changed = false;}intPWScore::WriteFile(const CMyString &filename, PWSfile::VERSION version){  PWSfile out(filename, GetPassKey());  int status;  // preferences are kept in header, which is written in OpenWriteFile,  // so we need to update the prefernce string here  out.SetPrefString(PWSprefs::GetInstance()->Store());  status = out.OpenWriteFile(version);  if (status != PWSfile::SUCCESS)    return CANT_OPEN_FILE;  CItemData temp;  POSITION listPos = m_pwlist.GetHeadPosition();  while (listPos != NULL)    {      temp = m_pwlist.GetAt(listPos);      out.WriteRecord(temp);      m_pwlist.GetNext(listPos);    }  out.CloseFile();  m_changed = FALSE;  m_ReadFileVersion = version; // needed when saving a V17 as V20 1st time [871893]  return SUCCESS;}intPWScore::WritePlaintextFile(const CMyString &filename){  ofstream of(filename);  if (!of)    return CANT_OPEN_FILE;  CItemData temp;  POSITION listPos = m_pwlist.GetHeadPosition();  while (listPos != NULL)    {      temp = m_pwlist.GetAt(listPos);      of << temp.GetPlaintext('\t') << endl;      m_pwlist.GetNext(listPos);    }  of.close();  return SUCCESS;}/*intPWScore::WriteXMLFile(const CMyString &filename){  ofstream of(filename);  if (!of)    return CANT_OPEN_FILE;  of << "<?xml version=\"1.0\">" << endl;  of << "<passwordsafe>" << endl;  POSITION listPos = m_pwlist.GetHeadPosition();  while (listPos != NULL)    {      CItemData temp = m_pwlist.GetAt(listPos);      of << "  <entry>" << endl;      // TODO: need to handle entity escaping of values.      of << "    <group>" << temp.GetGroup() << "</group>" << endl;      of << "    <title>" << temp.GetTitle() << "</title>" << endl;      of << "    <username>" << temp.GetUser() << "</username>" << endl;      of << "    <password>" << temp.GetPassword() << "</password>" << endl;      of << "    <notes>" << temp.GetNotes() << "</notes>" << endl;      of << "  </entry>" << endl;      m_pwlist.GetNext(listPos);    }  of << "</passwordsafe>" << endl;  of.close();  return SUCCESS;}*/intPWScore::ImportPlaintextFile(const CMyString &filename){    static const char *ImportedPrefix = { "Imported" };    ifstream ifs(filename);    if (!ifs)        return CANT_OPEN_FILE;    for (;;)    {        // read a single line.        string linebuf;        if (!getline(ifs, linebuf, '\n')) break;        // remove MS-DOS linebreaks, if needed.        if (!linebuf.empty() && *(linebuf.end() - 1) == '\r') {            linebuf.resize(linebuf.size() - 1);        }        // tokenize into separate elements        vector<string> tokens;        for (int startpos = 0; ; ) {            int nextchar = linebuf.find_first_of('\t', startpos);            if (nextchar >= 0 && tokens.size() < 3) {                tokens.push_back(linebuf.substr(startpos, nextchar - startpos));                startpos = nextchar + 1;            } else {                tokens.push_back(linebuf.substr(startpos));                break;            }        }        if (tokens.size() != 4) {            ASSERT(0 && "did not find expected number of tokens");            break;        }        // Start initializing the new record.        CItemData temp;        temp.CreateUUID();        temp.SetUser(CMyString(tokens[1].c_str()));        temp.SetPassword(CMyString(tokens[2].c_str()));        // The group and title field are concatenated.        const string &grouptitle = tokens[0];        int lastdot = grouptitle.find_last_of('.');        if (lastdot > 0) {            CMyString newgroup(ImportedPrefix);            newgroup += ".";            newgroup += grouptitle.substr(0, lastdot).c_str();            temp.SetGroup(newgroup);            temp.SetTitle(grouptitle.substr(lastdot + 1).c_str());        } else {            temp.SetGroup(ImportedPrefix);            temp.SetTitle(grouptitle.c_str());        }        // The notes field begins and ends with a double-quote, with        // no special escaping of any other internal characters.        string quotedNotes = tokens[3];        if (!quotedNotes.empty() &&            *quotedNotes.begin() == '\"' &&             *(quotedNotes.end() - 1) == '\"')        {            quotedNotes = quotedNotes.substr(1, quotedNotes.size() - 2);            temp.SetNotes(CMyString(quotedNotes.c_str()));        }        AddEntryToTail(temp);    }    ifs.close();    // TODO: maybe return an error if the full end of the file was not reached?    return SUCCESS;}int PWScore::CheckPassword(const CMyString &filename, CMyString& passkey){  PWSfile f(filename, passkey);  int status = f.CheckPassword();  switch (status) {  case PWSfile::SUCCESS:    return SUCCESS;  case PWSfile::CANT_OPEN_FILE:    return CANT_OPEN_FILE;  case PWSfile::WRONG_PASSWORD:    return WRONG_PASSWORD;  default:    ASSERT(0);    return status; // should never happen  }}intPWScore::ReadFile(const CMyString &a_filename,                   const CMyString &a_passkey){	   //That passkey had better be the same one that came from CheckPassword(...)   PWSfile in(a_filename, a_passkey);  int status;    m_ReadFileVersion = in.GetFileVersion();  if (m_ReadFileVersion == PWSfile::UNKNOWN_VERSION)    return UNKNOWN_VERSION;  status = in.OpenReadFile(m_ReadFileVersion);  if (status != PWSfile::SUCCESS)    return CANT_OPEN_FILE;    // prepare handling of pre-2.0 DEFUSERCHR conversion  if (m_ReadFileVersion == PWSfile::V17)    in.SetDefUsername(m_defusername);  else // for 2.0 & later, get pref string (possibly empty)    PWSprefs::GetInstance()->Load(in.GetPrefString());   ClearData(); //Before overwriting old data, but after opening the file...    SetPassKey(a_passkey);   CItemData temp;   status = in.ReadRecord(temp);   while (status == PWSfile::SUCCESS)   {      m_pwlist.AddTail(temp);      status = in.ReadRecord(temp);   }   in.CloseFile();   return SUCCESS;}int PWScore::RenameFile(const CMyString &oldname, const CMyString &newname){  return PWSfile::RenameFile(oldname, newname);}void PWScore::ChangePassword(const CMyString &newPassword){   SetPassKey(newPassword);  m_changed = TRUE;}// Finds stuff based on title & user fields onlyPOSITIONPWScore::Find(const CMyString &a_group,const CMyString &a_title, const CMyString &a_user){   POSITION listPos = m_pwlist.GetHeadPosition();   CMyString group, title, user;   while (listPos != NULL)   {     const CItemData &item = m_pwlist.GetAt(listPos);      group = item.GetGroup();      title = item.GetTitle();      user = item.GetUser();      if (group == a_group && title == a_title && user == a_user)         break;      else         m_pwlist.GetNext(listPos);   }   return listPos;}void PWScore::EncryptPassword(const unsigned char *plaintext, int len,			      unsigned char *ciphertext) const{  // ciphertext is ((len +7)/8)*8 bytes long  BlowFish *Algorithm = MakeBlowFish(m_session_key, sizeof(m_session_key),				     m_session_salt, sizeof(m_session_salt));  int BlockLength = ((len + 7)/8)*8;  unsigned char curblock[8];  for (int x=0;x<BlockLength;x+=8) {    int i;    if ((len == 0) ||	((len%8 != 0) && (len - x < 8))) {      //This is for an uneven last block      memset(curblock, 0, 8);      for (i = 0; i < len %8; i++)	curblock[i] = plaintext[x + i];      } else	for (i = 0; i < 8; i++)	  curblock[i] = plaintext[x + i];      Algorithm->Encrypt(curblock, curblock);      memcpy(ciphertext + x, curblock, 8);   }   trashMemory(curblock, 8);  delete Algorithm;}void PWScore::SetPassKey(const CMyString &new_passkey){  // if changing, clear old  if (m_passkey_len > 0) {    trashMemory(m_passkey, ((m_passkey_len + 7)/8)*8);    delete[] m_passkey;  }  m_passkey_len = new_passkey.GetLength();  int BlockLength = ((m_passkey_len + 7)/8)*8;  m_passkey = new unsigned char[BlockLength];  LPCTSTR plaintext = LPCTSTR(new_passkey);  EncryptPassword((const unsigned char *)plaintext, m_passkey_len,		  m_passkey);}CMyString PWScore::GetPassKey() const{  CMyString retval(_T(""));  if (m_passkey_len > 0) {    unsigned int BlockLength = ((m_passkey_len + 7)/8)*8;    BlowFish *Algorithm = MakeBlowFish(m_session_key, sizeof(m_session_key),				       m_session_salt, sizeof(m_session_salt));    unsigned char curblock[8];    for (unsigned int x = 0; x < BlockLength; x += 8) {      unsigned int i;      for (i = 0; i < 8; i++)	curblock[i] = m_passkey[x + i];      Algorithm->Decrypt(curblock, curblock);      for (i = 0; i < 8; i++)	if (x + i < m_passkey_len)	  retval += curblock[i];    }    trashMemory(curblock, 8);    delete Algorithm;  }  return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -