예제 #1
0
StringX PWSAuxParse::GetAutoTypeString(const CItemData &ci,
                                       const PWScore &core,
                                       std::vector<size_t> &vactionverboffsets)
{
  // Set up all the data (a shortcut entry will change all of them!)
  StringX sxgroup = ci.GetGroup();
  StringX sxtitle = ci.GetTitle();
  StringX sxuser = ci.GetUser();
  StringX sxpwd = ci.GetPassword();
  StringX sxnotes = ci.GetNotes();
  StringX sxurl = ci.GetURL();
  StringX sxemail = ci.GetEmail();
  StringX sxautotype = ci.GetAutoType();

  if (ci.IsAlias()) {
    const CItemData *pbci = core.GetBaseEntry(&ci);
    if (pbci != NULL) {
      sxpwd = pbci->GetPassword();
    } else { // Problem - alias entry without a base!
      ASSERT(0);
    }
  } else if (ci.IsShortcut()) {
    const CItemData *pbci = core.GetBaseEntry(&ci);
    if (pbci != NULL) {
      sxgroup = pbci->GetGroup();
      sxtitle = pbci->GetTitle();
      sxuser = pbci->GetUser();
      sxpwd = pbci->GetPassword();
      sxnotes = pbci->GetNotes();
      sxurl = pbci->GetURL();
      sxemail = pbci->GetEmail();
      sxautotype = pbci->GetAutoType();
    } else { // Problem - shortcut entry without a base!
      ASSERT(0);
    }
  } // ci.IsShortcut()

  // If empty, try the database default
  if (sxautotype.empty()) {
    sxautotype = PWSprefs::GetInstance()->
              GetPref(PWSprefs::DefaultAutotypeString);

    // If still empty, take this default
    if (sxautotype.empty()) {
      // checking for user and password for default settings
      if (!sxpwd.empty()){
        if (!sxuser.empty())
          sxautotype = DEFAULT_AUTOTYPE;
        else
          sxautotype = _T("\\p\\n");
      }
    }
  }
  return PWSAuxParse::GetAutoTypeString(sxautotype, sxgroup,
                                        sxtitle, sxuser, sxpwd,
                                        sxnotes, sxurl, sxemail,
                                        vactionverboffsets);
}
예제 #2
0
static void ParseNotes(StringX &sxNotes,
                       std::vector<StringX> &vsxnotes_lines)
{
  if (!sxNotes.empty()) {
    // Use \n and \r to tokenise this line
    StringX::size_type st_start(0), st_end(0);
    const StringX sxdelim = _T("\r\n");
    StringX sxline;
    StringX::size_type st_index;
    while (st_end != StringX::npos) {
      st_end = sxNotes.find(sxdelim, st_start);
      sxline = (sxNotes.substr(st_start, 
                   (st_end == StringX::npos) ? StringX::npos : st_end - st_start));
      st_index = 0;
      // Remove all tabs - \t
      for (;;) {
        st_index = sxline.find(_T("\\t"), st_index);
        if (st_index == StringX::npos)
          break;
        sxline.replace(st_index, 2, _T(""));
        st_index += 1;
      }
      vsxnotes_lines.push_back(sxline);
      st_start = ((st_end > (StringX::npos - sxdelim.size()))
                          ? StringX::npos : st_end + sxdelim.size());
    }
  }
}
예제 #3
0
파일: PWSfile.cpp 프로젝트: soundsrc/pwsafe
int PWSfile::CheckPasskey(const StringX &filename, const StringX &passkey, VERSION &version)
{
  /**
   * We start with V3 because it's the quickest to rule out
   * due to header/footer.
   * V4 can take a looong time if the iter value's too big.
   * XXX Need to address this later with a popup prompting the user.
   */
  if (passkey.empty())
    return WRONG_PASSWORD;

  int status;
  version = UNKNOWN_VERSION;
  status = PWSfileV3::CheckPasskey(filename, passkey);
  if (status == SUCCESS) {
    version = V30;
  } else {
    status = PWSfileV4::CheckPasskey(filename, passkey);
    if (status == SUCCESS)
      version = V40;
    else {
      status = PWSfileV1V2::CheckPasskey(filename, passkey);
      if (status == SUCCESS)
        version = V20; // or V17?
    }
  }
  return status;
}
예제 #4
0
void EditShortcut::ItemFieldsToDialog()
{
  // Populate the combo box
  std::vector<stringT> aryGroups;
  m_core.GetUniqueGroups(aryGroups);
  for (size_t igrp = 0; igrp < aryGroups.size(); igrp++) {
    m_groupCtrl->Append(aryGroups[igrp].c_str());
  }
  // select relevant group
  const StringX group = m_item->GetGroup();
  if (!group.empty())
    for (size_t igrp = 0; igrp < aryGroups.size(); igrp++)
      if (group == aryGroups[igrp].c_str()) {
        m_groupCtrl->SetSelection(reinterpret_cast<int &>(igrp));
        break;
      }
  
  m_title = m_item->GetTitle().c_str();
  m_user = m_item->GetUser().c_str();
  m_created = m_item->GetCTimeL().c_str();
  m_lastAccess = m_item->GetATimeL().c_str();
  m_lastAny = m_item->GetRMTimeL().c_str();
  const CItemData *base = m_core.GetBaseEntry(m_item);
  if (base != NULL) {
    m_lastChanged = base->GetRMTimeL().c_str();
  } else {
    m_lastChanged = _("Unknown"); // Internal error
  }
}
예제 #5
0
static StringX ReMergeNotes(const CItemData &item)
{
  StringX notes = item.GetNotes();
  const StringX url(item.GetURL());
  if (!url.empty()) {
    notes += _T("\r\n"); notes += url;
  }
  const StringX at(item.GetAutoType());
  if (!at.empty()) {
    stringT cs_autotype;
    LoadAString(cs_autotype, IDSC_AUTOTYPE);
    notes += _T("\r\n");
    notes += cs_autotype.c_str();
    notes += at;
  }
  return notes;
}
예제 #6
0
stringT CPasswordCharPool::GetDefaultSymbols()
{
  stringT symbols;
  const StringX sx_symbols = PWSprefs::GetInstance()->GetPref(PWSprefs::DefaultSymbols);
  if (!sx_symbols.empty())
    symbols = sx_symbols.c_str();
  else
    symbols = std_symbol_chars;
  return symbols;
}
예제 #7
0
파일: diff.cpp 프로젝트: soundsrc/pwsafe
lines_vec stream2vec(StringXStream &wss) {
    lines_vec vlines;
    do {
        StringX line;
        std::getline(wss, line);
        if ( !line.empty() ) vlines.push_back(line);
    }
    while( !wss.eof() );
    return vlines;
}
void PasswordSafeFrame::DoCopyEmail(CItemData &item)
{
  const StringX mailto = item.IsEmailEmpty()?
                      (item.IsURLEmail()? item.GetURL(): StringX())
                      : item.GetEmail();

  if (!mailto.empty()) {
    PWSclipboard::GetInstance()->SetData(mailto);
    UpdateAccessTime(item);
  }
}
bool CRUEList::GetAllMenuItemStrings(vector<RUEntryData> &ListofAllMenuStrings) const
{
  RUEntryData ruentrydata;
  bool retval = false;

  RUEListConstIter iter;

  for (iter = m_RUEList.begin(); iter != m_RUEList.end(); iter++) {
    ItemListConstIter pw_listpos = m_core.Find(*iter);
    if (pw_listpos == m_core.GetEntryEndIter()) {
      ruentrydata.string = L"";
      ruentrydata.image = -1;
      ruentrydata.pci = NULL;
    } else {
      const CItemData &ci = m_core.GetEntry(pw_listpos);
      StringX group = ci.GetGroup();
      StringX title = ci.GetTitle();
      StringX user = ci.GetUser();

      if (group.empty())
        group = L" ";

      if (title.empty())
        title = L" ";

      if (user.empty())
        user = L" ";

      // Looks similar to <g><t><u>
      ruentrydata.string = L"\xab" + group + L"\xbb " + 
                           L"\xab" + title + L"\xbb " + 
                           L"\xab" + user  + L"\xbb";
      ruentrydata.image = app.GetMainDlg()->GetEntryImage(ci);
      ruentrydata.pci = (CItemData *)&ci;
    }
    ListofAllMenuStrings.push_back(ruentrydata);
    retval = true;
  }
  return retval;
}
wxTreeItemId PWSTreeCtrl::AddGroup(const StringX &group)
{
  wxTreeItemId ti = GetRootItem();
  if (!ti.IsOk())
    ti=AddRoot(wxString());

  // Add a group at the end of path
  wxTreeItemId si;
  if (!group.empty()) {
    StringX path = group;
    StringX s;
    do {
      s = GetPathElem(path);
      if (!ExistsInTree(ti, s, si)) {
        ti = AppendItem(ti, s.c_str());
        wxTreeCtrl::SetItemImage(ti, NODE_II);
      } else
        ti = si;
    } while (!path.empty());
  }
  return ti;
}
예제 #11
0
파일: diff.cpp 프로젝트: soundsrc/pwsafe
inline wostream& print_field_value(wostream &os, wchar_t tag,
                                    const CItemData &item, CItemData::FieldType ft)
{
  StringX fieldValue;
  switch (ft) {
    case CItemData::DCA:
    case CItemData::SHIFTDCA:
    {
      int16 dca = -1;
      if (item.GetDCA(dca) != -1) {
        LoadAString(fieldValue, dca2str(dca));
      }
      break;
    }
    case CItemData::PWHIST:
    {
      const StringX pwh_str = item.GetPWHistory();
      if (!pwh_str.empty()) {
        StringXStream value_stream;
        size_t ignored;
        PWHistList pwhl;
        const bool save_pwhistory = CreatePWHistoryList(pwh_str, ignored, ignored, pwhl, PWSUtil::TMC_LOCALE);
        value_stream << L"Save: " << (save_pwhistory? L"Yes" : L"No");
        if ( !pwhl.empty() ) value_stream << endl;
        for( const auto &pwh: pwhl) value_stream << pwh.changedate << L": " << pwh.password << endl;
        fieldValue = value_stream.str();
      }
      break;
    }
    case CItemData::POLICY:
    {
        PWPolicy policy;
        item.GetPWPolicy(policy);
        fieldValue = policy.GetDisplayString();
        break;
    }
    default:
      fieldValue = item.GetFieldValue(ft);
      break;
  }
  const StringX sep1{L' '}, sep2{L": "};
  StringXStream tmpStream;
  tmpStream << tag << L' ' << item.FieldName(ft) << L": " << fieldValue;
  const auto offset = 1 /*tag*/ + sep1.size() + sep2.size() + item.FieldName(ft).size();
  lines_vec lines{ stream2vec(tmpStream)};
  if ( lines.size() > 1) {
    std::for_each( lines.begin()+1, lines.end(), [offset](StringX &line) { line.insert(0, offset, L' '); });
  }
  for( const auto &line: lines ) os << line << endl;
  return os;
}
예제 #12
0
int PWSfile::CheckPasskey(const StringX &filename,
                          const StringX &passkey, VERSION &version)
{

  if (passkey.empty())
    return WRONG_PASSWORD;

  int status;
  version = UNKNOWN_VERSION;
  status = PWSfileV3::CheckPasskey(filename, passkey);
  if (status == SUCCESS)
    version = V30;
  if (status == NOT_PWS3_FILE) {
    status = PWSfileV1V2::CheckPasskey(filename, passkey);
    if (status == SUCCESS)
      version = V20; // or V17?
  }
  return status;
}
예제 #13
0
파일: diff.cpp 프로젝트: soundsrc/pwsafe
/////////////////////////////////////////////////////////////////
// Context diff
////////
inline wchar_t context_tag(CItem::FieldType ft, const CItemData::FieldBits &fields,
                const CItemData &item, const CItemData &otherItem)
{
  // The two items were compared & found to be differing on this field
  // only show this tag for fields there were compared
  if (fields.test(ft))
    return '!';

  const StringX val{item.GetFieldValue(ft)};

  // This field was not compared, it could be different. Print it only if
  // it is the same in both items
  if (val == otherItem.GetFieldValue(ft))
    return L' ';

  if (val.empty())
    return L'+';

  // Don't print it
  return L'-';
}
예제 #14
0
bool PWSRun::issuecmd(const StringX &sxFile, const StringX &sxParameters, 
                      const bool &bAutotype) const
{
  SHELLEXECUTEINFO si;
  ZeroMemory(&si, sizeof(SHELLEXECUTEINFO));
  si.cbSize = sizeof(SHELLEXECUTEINFO);
  si.nShow = SW_SHOWNORMAL;
  si.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST;

  si.lpFile = sxFile.c_str();
  if (!sxParameters.empty()) {
    si.lpParameters = sxParameters.c_str();
  }

  BOOL bAT_init(FALSE);

  if (bAutotype && isValid()) {
    if (pImpl->pInit != NULL && pImpl->pUnInit != NULL &&
        pImpl->hCBWnd != NULL) {
      // OK - try and make it tell us!  Won't if another instance of
      // PWS is doing this at exactly the same time - silly user!
      bAT_init = pImpl->pInit(pImpl->hCBWnd);
      pws_os::Trace(_T("PWSRun::issuecmd - AT_HK_Initialise: %s\n"),
                    bAT_init == TRUE ? _T("OK") : _T("FAILED"));
    }
  }

  BOOL shellExecStatus = ::ShellExecuteEx(&si);
  if (shellExecStatus != TRUE) {
    // ShellExecute writes its own message on failure!
    if (bAT_init) {
      bAT_init = pImpl->pUnInit(pImpl->hCBWnd);
      pws_os::Trace(_T("PWSRun::issuecmd - AT_HK_UnInitialise: %s\n"),
                    bAT_init == TRUE ? _T("OK") : _T("FAILED"));
    }
    return false;
  }
  return true;
}
예제 #15
0
bool CUTF8Conv::ToUTF8(const StringX &data,
                       const unsigned char *&utf8, size_t &utf8Len)
{
    // If we're not in Unicode, call MultiByteToWideChar to get from
    // current codepage to Unicode, and then WideCharToMultiByte to
    // get to UTF-8 encoding.
    
    if (data.empty()) {
        utf8Len = 0;
        return true;
    }
    
    wchar_t *wcPtr = const_cast<wchar_t *>(data.c_str());
    size_t wcLen = data.length()+1;
    // first get needed utf8 buffer size
    size_t mbLen = pws_os::wcstombs(NULL, 0, wcPtr, wcLen);
    
    if (mbLen == 0) { // uh-oh
        ASSERT(0);
        m_utf8Len = 0;
        return false;
    }
    // Allocate buffer (if previous allocation was smaller)
    if (mbLen > m_utf8MaxLen) {
        if (m_utf8 != NULL)
            trashMemory(m_utf8, m_utf8MaxLen);
        delete[] m_utf8;
        m_utf8 = new unsigned char[mbLen];
        m_utf8MaxLen = mbLen;
    }
    // Finally get result
    m_utf8Len = pws_os::wcstombs(reinterpret_cast<char *>(m_utf8), mbLen, wcPtr, wcLen);
    ASSERT(m_utf8Len != 0);
    m_utf8Len--; // remove unneeded null termination
    utf8 = m_utf8;
    utf8Len = m_utf8Len;
    return true;
}
예제 #16
0
HTREEITEM CCWTreeCtrl::AddGroup(const CString &group)
{
  // Add a group at the end of path
  HTREEITEM ti = TVI_ROOT;
  HTREEITEM si;
  if (!group.IsEmpty()) {
    StringX sxPath = group;
    StringX sxTemp, sxPath2Root(L"");
    do {
      sxTemp = GetFirstPathElem(sxPath);
      if (sxPath2Root.empty())
        sxPath2Root = sxTemp;
      else
        sxPath2Root += GROUP_SEP2 + sxTemp;

      if (!ExistsInTree(ti, sxTemp, si)) {
        ti = InsertItem(sxTemp.c_str(), ti, TVI_SORT);
        SetItemImage(ti, CCWTreeCtrl::GROUP, CCWTreeCtrl::GROUP);
      } else
        ti = si;
    } while (!sxPath.empty());
  }
  return ti;
}
예제 #17
0
bool CUTF8Conv::ToUTF8(const StringX &data,
                       const unsigned char *&utf8, size_t &utf8Len)
{
  // If we're not in Unicode, call MultiByteToWideChar to get from
  // current codepage to Unicode, and then WideCharToMultiByte to
  // get to UTF-8 encoding.

  if (data.empty()) {
    utf8Len = 0;
    return true;
  }
  wchar_t *wcPtr; // to hide UNICODE differences
  size_t wcLen; // number of wide chars needed
#ifndef UNICODE
  // first get needed wide char buffer size
  wcLen = pws_os::mbstowcs(NULL, 0, data.c_str(), size_t(-1), false);
  if (wcLen == 0) { // uh-oh
    ASSERT(0);
    m_utf8Len = 0;
    return false;
  }
  // Allocate buffer (if previous allocation was smaller)
  if (wcLen > m_wcMaxLen) {
    if (m_wc != NULL)
      trashMemory(m_wc, m_wcMaxLen * sizeof(m_wc[0]));
    delete[] m_wc;
    m_wc = new wchar_t[wcLen];
    m_wcMaxLen = wcLen;
  }
  // next translate to buffer
  wcLen = pws_os::mbstowcs(m_wc, wcLen, data.c_str(), size_t(-1), false);
  ASSERT(wcLen != 0);
  wcPtr = m_wc;
#else
  wcPtr = const_cast<wchar_t *>(data.c_str());
  wcLen = data.length()+1;
#endif
  // first get needed utf8 buffer size
  size_t mbLen = pws_os::wcstombs(NULL, 0, wcPtr, wcLen);

  if (mbLen == 0) { // uh-oh
    ASSERT(0);
    m_utf8Len = 0;
    return false;
  }
  // Allocate buffer (if previous allocation was smaller)
  if (mbLen > m_utf8MaxLen) {
    if (m_utf8 != NULL)
      trashMemory(m_utf8, m_utf8MaxLen);
    delete[] m_utf8;
    m_utf8 = new unsigned char[mbLen];
    m_utf8MaxLen = mbLen;
  }
  // Finally get result
  m_utf8Len = pws_os::wcstombs(reinterpret_cast<char *>(m_utf8), mbLen, wcPtr, wcLen);
  ASSERT(m_utf8Len != 0);
  m_utf8Len--; // remove unneeded null termination
  utf8 = m_utf8;
  utf8Len = m_utf8Len;
  return true;
}
예제 #18
0
// In following, char * is managed by caller.
bool CUTF8Conv::FromUTF8(const unsigned char *utf8, size_t utf8Len,
                         StringX &data)
{
  // Call MultiByteToWideChar to get from UTF-8 to Unicode.
  // If we're not in Unicode, call WideCharToMultiByte to
  // get to current codepage.
  //
  // Due to a bug in pre-3.08 versions, data may be in ACP
  // instead of UTF-8. We try to detect and workaround this.

  if (utf8Len == 0 || (utf8Len == 1 && utf8[0] == '\0')) {
    data = _T("");
    return true;
  }

  ASSERT(utf8 != NULL);

  // first get needed wide char buffer size
  size_t wcLen = pws_os::mbstowcs(NULL, 0,
                                  reinterpret_cast<const char *>(utf8),
                                  size_t(-1), !m_cp_acp);
  if (wcLen == 0) { // uh-oh
    // it seems that this always returns non-zero, even if encoding
    // broken. Therefore, we'll give a conservative value here,
    // and try to recover later
    pws_os::Trace0(_T("FromUTF8: Couldn't get buffer size - guessing!"));
    wcLen = sizeof(StringX::value_type) * (utf8Len + 1);
  }
  // Allocate buffer (if previous allocation was smaller)
  if (wcLen > m_wcMaxLen) {
    if (m_wc != NULL)
      trashMemory(m_wc, m_wcMaxLen);
    delete[] m_wc;
    m_wc = new wchar_t[wcLen];
    m_wcMaxLen = wcLen;
  }
  // next translate to buffer
  wcLen = pws_os::mbstowcs(m_wc, wcLen,
                           reinterpret_cast<const char *>(utf8),
                           size_t(-1), !m_cp_acp);
#ifdef _WIN32
  if (wcLen == 0) {
    DWORD errCode = GetLastError();
    switch (errCode) {
    case ERROR_INSUFFICIENT_BUFFER:
      pws_os::Trace0(_T("INSUFFICIENT BUFFER")); break;
    case ERROR_INVALID_FLAGS:
      pws_os::Trace0(_T("INVALID FLAGS")); break;
    case ERROR_INVALID_PARAMETER:
      pws_os::Trace0(_T("INVALID PARAMETER")); break;
    case ERROR_NO_UNICODE_TRANSLATION:
      // try to recover
      pws_os::Trace0(_T("NO UNICODE TRANSLATION"));
      wcLen = MultiByteToWideChar(CP_ACP,        // code page
                                  0,             // character-type options
                                  LPSTR(utf8),   // string to map
                                  -1,            // -1 means null-terminated
                                  m_wc,          // output buffer
                                  reinterpret_cast<int &>(wcLen));  // output buffer size
      if (wcLen > 0) {
        pws_os::Trace0(_T("FromUTF8: recovery succeeded!"));
      }
      break;
    default:
      ASSERT(0);
    }
  }
  ASSERT(wcLen != 0);
#endif /* _WIN32 */
#ifdef UNICODE
  if (wcLen != 0) {
    m_wc[wcLen - 1] = TCHAR('\0');
    data = m_wc;
    return true;
  } else
    return false;
#else /* Go from Unicode to Locale encoding */
  // first get needed utf8 buffer size
  size_t mbLen = pws_os::wcstombs(NULL, 0, m_wc, size_t(-1), false);
  if (mbLen == 0) { // uh-oh
    ASSERT(0);
    data = _T("");
    return false;
  }
  // Allocate buffer (if previous allocation was smaller)
  if (mbLen > m_tmpMaxLen) {
    if (m_tmp != NULL)
      trashMemory(m_tmp, m_tmpMaxLen);
    delete[] m_tmp;
    m_tmp = new unsigned char[mbLen];
    m_tmpMaxLen = mbLen;
  }
  // Finally get result
  size_t tmpLen = pws_os::wcstombs((char *)m_tmp, mbLen, m_wc, size_t(-1), false);
  ASSERT(tmpLen == mbLen);
  m_tmp[mbLen - 1] = '\0'; // char, no need to _T()...
  data = (char *)m_tmp;
  ASSERT(!data.empty());
  return true;
#endif /* !UNICODE */
}
예제 #19
0
StringX PWSAuxParse::GetAutoTypeString(const StringX &sx_in_autotype,
                                       const StringX &sx_group,
                                       const StringX &sx_title,
                                       const StringX &sx_user,
                                       const StringX &sx_pwd,
                                       const StringX &sx_notes,
                                       const StringX &sx_url,
                                       const StringX &sx_email,
                                       std::vector<size_t> &vactionverboffsets)
{
  StringX sxtmp(_T(""));
  StringX sxNotes(sx_notes);
  TCHAR curChar;
  StringX sx_autotype(sx_in_autotype);
  StringX::size_type st_index;
  std::vector<StringX> vsxnotes_lines;

  vactionverboffsets.clear();

  // If empty, try the database default
  if (sx_autotype.empty()) {
    sx_autotype = PWSprefs::GetInstance()->
              GetPref(PWSprefs::DefaultAutotypeString);

    // If still empty, take this default
    if (sx_autotype.empty()) {
      // checking for user and password for default settings
      if (!sx_pwd.empty()){
        if (!sx_user.empty())
          sx_autotype = DEFAULT_AUTOTYPE;
        else
          sx_autotype = _T("\\p\\n");
      }
    }
  }

  // No recursive substitution (e.g. \p or \u), although '\t' will be replaced by a tab
  if (!sx_notes.empty()) {
    // Use \n and \r to tokenise this line
    StringX::size_type st_start(0), st_end(0);
    const StringX sxdelim = _T("\r\n");
    StringX sxline;
    while (st_end != StringX::npos) {
      st_end = sxNotes.find_first_of(sxdelim, st_start);
      sxline = (sxNotes.substr(st_start, (st_end == StringX::npos) ? 
                              StringX::npos : st_end - st_start));
      st_index = 0;
      for (;;) {
        st_index = sxline.find(_T("\\t"), st_index);
        if (st_index == StringX::npos)
          break;
        sxline.replace(st_index, 2, _T("\t"));
        st_index += 1;
      }
      vsxnotes_lines.push_back(sxline);
      // If we just hit a "\r\n", move past it.  Or else, it is a "\r" without
      // a following "\n" or a "\n", so just move past one single char
      if (st_end != StringX::npos) {
        st_start = st_end + (sxNotes.compare(st_end, 2, sxdelim) == 0 ? 2 : 1);
        if (st_start >= sxNotes.length())
          break;
      }
    }
    // Now change '\n' to '\r' in the complete notes field
    st_index = 0;
    for (;;) {
      st_index = sxNotes.find(sxdelim, st_index);
      if (st_index == StringX::npos)
        break;
      sxNotes.replace(st_index, 2, _T("\r"));
      st_index += 1;
    }
    st_index = 0;
    for (;;) {
      st_index = sxNotes.find(_T("\\t"), st_index);
      if (st_index == StringX::npos)
        break;
      sxNotes.replace(st_index, 2, _T("\t"));
      st_index += 1;
    }
  }

  const size_t N = sx_autotype.length();
  const StringX sxZeroes = _T("000");
  int gNumIts;

  for (size_t n = 0; n < N; n++){
    curChar = sx_autotype[n];
    if (curChar == TCHAR('\\')) {
      n++;
      if (n < N)
        curChar = sx_autotype[n];

      switch (curChar){
        case TCHAR('\\'):
          sxtmp += TCHAR('\\');
          break;
        case TCHAR('n'):
        case TCHAR('r'):
          sxtmp += TCHAR('\r');
          break;
        case TCHAR('t'):
          sxtmp += TCHAR('\t');
          break;
        case TCHAR('s'):
          sxtmp += TCHAR('\v');
          break;
        case TCHAR('g'):
          sxtmp += sx_group;
          break;
        case TCHAR('i'):
          sxtmp += sx_title;
          break;
        case TCHAR('u'):
          sxtmp += sx_user;
          break;
        case TCHAR('p'):
          sxtmp += sx_pwd;
          break;
        case TCHAR('l'):
          sxtmp += sx_url;
          break;
        case TCHAR('m'):
          sxtmp += sx_email;
          break;

        case TCHAR('o'):
        {
          if (n == (N - 1)) {
            // This was the last character - send the lot!
            sxtmp += sxNotes;
            break;
          }
          size_t line_number(0);
          gNumIts = 0;
          for (n++; n < N && (gNumIts < 3); ++gNumIts, n++) {
            if (_istdigit(sx_autotype[n])) {
              line_number *= 10;
              line_number += (sx_autotype[n] - TCHAR('0'));
            } else
              break; // for loop
          }
          if (line_number == 0) {
            // Send the lot
            sxtmp += sx_notes;
          } else
          if (line_number <= vsxnotes_lines.size()) {
            // User specifies a too big a line number - ignore the lot
            sxtmp += vsxnotes_lines[line_number - 1];
          }

          // Backup the extra character that delimited the \oNNN string
          n--;
          break; // case 'o'
        }

        // Action Verbs:
        // These are the only ones processed specially by the UI as they involve
        // actions it performs whilst doing the key sending.
        // Copy them to output string unchanged.
        case TCHAR('b'):  // backspace!
        case TCHAR('z'):  // Use older method
          vactionverboffsets.push_back(sxtmp.length());
          sxtmp += _T("\\");
          sxtmp += curChar;
          break; // case 'b' & 'z'

        case TCHAR('d'):  // Delay
        case TCHAR('w'):  // Wait milli-seconds
        case TCHAR('W'):  // Wait seconds
        {
          // Need to ensure that the field length is 3, even if it wasn't
          vactionverboffsets.push_back(sxtmp.length());
          sxtmp += _T("\\");
          sxtmp += curChar;

          gNumIts = 0;
          size_t i = n;
          for (i++; i < N && (gNumIts < 3); ++gNumIts, i++) {
            if (!_istdigit(sx_autotype[i]))
              break;
          }
          // Insert sufficient zeroes to ensure field is 3 characters long
          sxtmp += sxZeroes.substr(0, 3 - gNumIts);
          break; // case 'd', 'w' & 'W'
        }

        // Also copy explicit control characters to output string unchanged.
        case TCHAR('a'): // bell (can't hear it during testing!)
        case TCHAR('v'): // vertical tab
        case TCHAR('f'): // form feed
        case TCHAR('e'): // escape
        case TCHAR('x'): // hex digits (\xNN)
        // and any others we have forgotten!
        // '\cC', '\uXXXX', '\OOO', '\<any other charatcer not recognised above>'
        default:
          sxtmp += L'\\';
          sxtmp += curChar;
          break;
      }
    } else
      sxtmp += curChar;
  }

  vsxnotes_lines.clear();
  return sxtmp;
}
std::string PWSFilters::GetFilterXMLHeader(const StringX &currentfile,
                                           const PWSfile::HeaderRecord &hdr)
{
  CUTF8Conv utf8conv;
  const unsigned char *utf8 = NULL;
  size_t utf8Len = 0;

  ostringstream oss;
  stringT cs_tmp;
  time_t time_now;

  time(&time_now);
  const StringX now = PWSUtil::ConvertToDateTimeString(time_now, PWSUtil::TMC_XML);

  oss << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
  oss << endl;

  oss << "<filters version=\"";
  oss << PWS_XML_FILTER_VERSION;
  oss << "\"" << endl;
  
  if (!currentfile.empty()) {
    cs_tmp = currentfile.c_str();
    Replace(cs_tmp, stringT(_T("&")), stringT(_T("&amp;")));

    utf8conv.ToUTF8(cs_tmp.c_str(), utf8, utf8Len);
    oss << "Database=\"";
    oss << reinterpret_cast<const char *>(utf8);
    oss << "\"" << endl;
    utf8conv.ToUTF8(now, utf8, utf8Len);
    oss << "ExportTimeStamp=\"";
    oss << reinterpret_cast<const char *>(utf8);
    oss << "\"" << endl;
    oss << "FromDatabaseFormat=\"";
    oss << hdr.m_nCurrentMajorVersion
        << "." << setw(2) << setfill('0')
        << hdr.m_nCurrentMinorVersion;
    oss << "\"" << endl;
    if (!hdr.m_lastsavedby.empty() || !hdr.m_lastsavedon.empty()) {
      stringT wls(_T(""));
      Format(wls,
             L"%ls on %ls",
             hdr.m_lastsavedby.c_str(), hdr.m_lastsavedon.c_str());
      utf8conv.ToUTF8(wls.c_str(), utf8, utf8Len);
      oss << "WhoSaved=\"";
      oss << reinterpret_cast<const char *>(utf8);
      oss << "\"" << endl;
    }
    if (!hdr.m_whatlastsaved.empty()) {
      utf8conv.ToUTF8(hdr.m_whatlastsaved, utf8, utf8Len);
      oss << "WhatSaved=\"";
      oss << reinterpret_cast<const char *>(utf8);
      oss << "\"" << endl;
    }
    if (hdr.m_whenlastsaved != 0) {
      StringX wls = PWSUtil::ConvertToDateTimeString(hdr.m_whenlastsaved,
                                                     PWSUtil::TMC_XML);
      utf8conv.ToUTF8(wls.c_str(), utf8, utf8Len);
      oss << "WhenLastSaved=\"";
      oss << reinterpret_cast<const char *>(utf8);
      oss << "\"" << endl;
    }

    CUUID huuid(*hdr.m_file_uuid.GetARep(), true); // true to print canonically

    oss << "Database_uuid=\"" << huuid << "\"" << endl;
  }
  oss << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" << endl;
  oss << "xsi:noNamespaceSchemaLocation=\"pwsafe_filter.xsd\">" << endl;
  oss << endl;

  return oss.str().c_str();
}
예제 #21
0
int PWSfileV1V2::WriteRecord(const CItemData &item)
{
  ASSERT(m_fd != NULL);
  ASSERT(m_curversion != UNKNOWN_VERSION);
  int status = SUCCESS;

  switch (m_curversion) {
    case V17:
    {
      // 1.x programs totally ignore the type byte, hence safe to write it
      // (no need for two WriteCBC functions)
      // Note that 2.0 format still requires that the header be in this format,
      // So that old programs reading new databases won't crash,
      // This introduces a small security issue, in that the header is known text,
      // making the password susceptible to a dictionary attack on the first block,
      // rather than the hash^n in the beginning of the file.
      // we can help minimize this here by writing a random byte in the "type"
      // byte of the first block.

      StringX name = item.GetName();
      // If name field already exists - use it. This is for the 2.0 header, as well as for files
      // that were imported and re-exported.
      if (name.empty()) {
        // The name in 1.7 consists of title + SPLTCHR + username
        // DEFUSERNAME was used in previous versions, but 2.0 converts this upon import
        // so it is not an issue here.
        // Prepend 2.0 group field to name, if not empty
        // i.e. group "finances" name "broker" -> "finances.broker"
        StringX group = item.GetGroup();
        StringX title = item.GetTitle();
        if (!group.empty()) {
          group += _T(".");
          group += title;
          title = group;
        }
        name = title;
        name += SPLTCHR;
        name += item.GetUser();
      }
      unsigned char dummy_type;
      PWSrand::GetInstance()->GetRandomData(&dummy_type, 1);
      WriteCBC(dummy_type, name);
      WriteCBC(CItemData::PASSWORD, item.GetPassword());
      WriteCBC(CItemData::NOTES, ReMergeNotes(item));
      break;
    }
    case V20:
    {
      {
        uuid_array_t uuid_array;
        item.GetUUID(uuid_array);
        PWSfile::WriteCBC(CItemData::UUID, uuid_array, sizeof(uuid_array_t));
      }
      WriteCBC(CItemData::GROUP, item.GetGroup());
      WriteCBC(CItemData::TITLE, item.GetTitle());
      WriteCBC(CItemData::USER, item.GetUser());
      WriteCBC(CItemData::PASSWORD, item.GetPassword());
      WriteCBC(CItemData::NOTES, ReMergeNotes(item));
      WriteCBC(CItemData::END, _T(""));
      break;
    }
    default:
      ASSERT(0);
      status = UNSUPPORTED_VERSION;
  }
  return status;
}
예제 #22
0
//-----------------------------------------------------------------
// Internal functions
//-----------------------------------------------------------------
static UINT ParseRunCommand(const StringX &sxInputString,
                            std::vector<st_RunCommandTokens> &v_rctokens,
                            bool &bDoAutoType, StringX &sxAutoType,
                            stringT &serrmsg, StringX::size_type &st_column)
{
  // tokenize into separate elements
  std::vector<st_RunCommandTokens>::iterator rc_iter;
  std::vector<size_t> v_pos;
  StringX::iterator str_Iter;
  st_RunCommandTokens st_rctoken;
  size_t st_num_quotes(0);

  UINT uierr(0);
  int var_index(0);

  const stringT alphanum =
    _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");

  if (sxInputString.empty()) {
  // String is empty!
    uierr = IDSC_EXS_INPUTEMPTY;
    goto exit;
  }

  for (StringX::size_type l = 0; l < sxInputString.length(); l++) {
    if (sxInputString[l] == _T('"'))
      st_num_quotes++;
  }

  if (st_num_quotes % 2 != 0) {
    st_column = sxInputString.find(_T('"'));
    // Unmatched quotes
    uierr = IDSC_EXS_UNMATCHEDQUOTES;
    goto exit;
  }

  // tokenize into separate elements using $ as the field separator
  for (StringX::size_type st_startpos = 0;
       st_startpos < sxInputString.size();
       /* st_startpos advanced in body */) {
    StringX::size_type st_next = sxInputString.find(_T('$'), st_startpos);
    if (st_next == StringX::npos)
      st_next = sxInputString.size();
    if (st_next > 0) {
      st_rctoken.sxname = sxInputString.substr(st_startpos, st_next - st_startpos);
      st_rctoken.sxindex = _T("");
      st_rctoken.index = 0;
      st_rctoken.is_variable  = st_startpos == 0 ? false : true;
      st_rctoken.has_brackets = false;
      v_rctokens.push_back(st_rctoken);
      v_pos.push_back(st_startpos);
    }
    st_startpos = st_next + 1; // too complex for for statement
  } // tokenization for loop

  // Check if escaped - ending character of previous token == '\'
  // Make sure this '\' is not escaped itself!
  for (size_t st_idx = v_rctokens.size() - 1; st_idx > 0 ; st_idx--) {
    st_RunCommandTokens &st_rctokens = v_rctokens[st_idx - 1];
    StringX::size_type name_len = st_rctokens.sxname.length();
    if (name_len == 0 || (name_len >= 2 &&
            st_rctokens.sxname.substr(name_len - 2, 2).compare(_T("\\\\")) == 0))
      continue;

    if (st_rctokens.sxname.substr(name_len - 1, 1).compare(_T("\\")) == 0) {
      st_rctokens.sxname = st_rctokens.sxname.substr(0, name_len - 1) + 
                         _T("$") + v_rctokens[st_idx].sxname;
      v_rctokens.erase(v_rctokens.begin() + st_idx);
    }
  }

  // Check if variable enclosed in curly brackets
  for (size_t st_idx = 0; st_idx < v_rctokens.size(); st_idx++) {
    if (v_rctokens[st_idx].sxname.length() == 0)
      continue;

    str_Iter = v_rctokens[st_idx].sxname.begin();
    // Does it start with a curly bracket?
    if (*str_Iter == _T('{')) {
      v_rctokens[st_idx].has_brackets = true;
      StringX sxvar, sxnonvar, sxindex(_T(""));
      // Yes - Find end curly bracket
      StringX::size_type st_end_cb = v_rctokens[st_idx].sxname.find(_T('}'));
      if (st_end_cb == StringX::npos) {
        st_column = v_pos[st_idx] + v_rctokens[st_idx].sxname.length();
        // Missing end curly bracket
        uierr = IDSC_EXS_MISSINGCURLYBKT;
        goto exit;
      }
      // Now see if there is an Index here
      StringX::size_type st_start_sb = v_rctokens[st_idx].sxname.find(_T('['));
      if (st_start_sb != StringX::npos) {
        // Yes  - find end square bracket
        if (st_start_sb > st_end_cb) {
          // Square backet after end of variable
          sxvar = v_rctokens[st_idx].sxname.substr(1, st_end_cb - 1);
          sxnonvar = v_rctokens[st_idx].sxname.substr(st_end_cb + 1);
          v_rctokens[st_idx].sxname = sxvar;
          if (sxnonvar.length() > 0) {
            st_rctoken.sxname = sxnonvar;
            st_rctoken.sxindex = _T("");
            st_rctoken.index = 0;
            st_rctoken.is_variable = false;
            st_rctoken.has_brackets = false;
            v_rctokens.insert(v_rctokens.begin() + st_idx + 1, st_rctoken);
            v_pos.insert(v_pos.begin() + st_idx + 1, v_pos[st_idx] + st_end_cb);
          }
          continue;
        }
        StringX::size_type st_end_sb = v_rctokens[st_idx].sxname.find(_T(']'), st_start_sb);
        if (st_end_sb == StringX::npos) {
          st_column = v_pos[st_idx] + 1;
          // Missing end square bracket
          uierr = IDSC_EXS_MISSINGSQUAREBKT;
          goto exit;
        }
        // The end-curly backet must immediately follow the end-square bracket
        if (st_end_cb != st_end_sb + 1) {
          st_column = v_pos[st_idx] + st_end_sb + 1;
          // Characters between ']' and ')'
          uierr = IDSC_EXS_INVALIDBRACKETS;
          goto exit;
        }
        sxindex = v_rctokens[st_idx].sxname.substr(st_start_sb + 1, st_end_sb - st_start_sb - 1);
        v_rctokens[st_idx].sxindex = sxindex;
        // Now check index
        uierr = ProcessIndex(sxindex, var_index, st_column);
        if (uierr > 0) {
          st_column += v_pos[st_idx];
          goto exit;
        }

        v_rctokens[st_idx].index = var_index;
        sxvar = v_rctokens[st_idx].sxname.substr(1, st_start_sb - 1);
        sxnonvar = v_rctokens[st_idx].sxname.substr(st_end_cb + 1);
      } else {
        // No square bracket
        // Split current token into 'variable' and 'non-variable' parts
        sxvar = v_rctokens[st_idx].sxname.substr(1, st_end_cb - 1);
        sxnonvar = v_rctokens[st_idx].sxname.substr(st_end_cb + 1);
      }
      v_rctokens[st_idx].sxname = sxvar;
      if (sxnonvar.length() > 0) {
        st_rctoken.sxname = sxnonvar;
        st_rctoken.sxindex = _T("");
        st_rctoken.index = 0;
        st_rctoken.is_variable = false;
        st_rctoken.has_brackets = false;
        v_rctokens.insert(v_rctokens.begin() + st_idx + 1, st_rctoken);
        v_pos.insert(v_pos.begin() + st_idx + 1, v_pos[st_idx] + st_end_cb);
      }
    }
  }

  // Now use rules of variables to get the real variable
  for (size_t st_idx = 0; st_idx < v_rctokens.size(); st_idx++) {
    if (!v_rctokens[st_idx].is_variable)
      continue;

    if (v_rctokens[st_idx].sxname.length() == 0) {
      st_column = v_pos[st_idx];
      // Variable name is empty
      uierr = IDSC_EXS_VARNAMEEMPTY;
      goto exit;
    }

    str_Iter = v_rctokens[st_idx].sxname.begin();
    if (!isalpha(*str_Iter)) {
      st_column = v_pos[st_idx];
      // First character of variable is not alphabetic
      uierr = IDSC_EXS_FIRSTNOTALPHA;
      goto exit;
    }
    StringX::size_type st_next = v_rctokens[st_idx].sxname.find_first_not_of(alphanum.c_str());
    if (st_next != StringX::npos) {
      // Split current token into 'variable' and 'non-variable' parts
      StringX sxvar = v_rctokens[st_idx].sxname.substr(0, st_next);
      StringX sxnonvar = v_rctokens[st_idx].sxname.substr(st_next);
      v_rctokens[st_idx].sxname = sxvar;
      // Before saving non-variable part - check if it is an Index e.g. var[i]
      if (sxnonvar.c_str()[0] == _T('[')) {
        // Find ending square bracket
        StringX::size_type st_end_sb = sxnonvar.find(_T(']'));
        if (st_end_sb == StringX::npos) {
          st_column = v_pos[st_idx] + sxvar.length() + 2;
          // Missing end square bracket
          uierr = IDSC_EXS_MISSINGSQUAREBKT;
          goto exit;
        }
        StringX sxindex = sxnonvar.substr(1, st_end_sb - 1);
        v_rctokens[st_idx].sxindex = sxindex;
        // Now check index
        uierr = ProcessIndex(sxindex, var_index, st_column);
        if (uierr > 0) {
          st_column += v_pos[st_idx] + sxvar.length();
          goto exit;
        }

        v_rctokens[st_idx].index = var_index;
        sxnonvar = sxnonvar.substr(st_end_sb + 1);
      } else {
        // Not a square bracket
        if (v_rctokens[st_idx].has_brackets) {
          st_column = v_pos[st_idx] + st_next + 1;
          // Variable must be alphanumeric
          uierr = IDSC_EXS_VARNAMEINVALID;
          goto exit;
        }
      }
      if (!sxnonvar.empty()) {
        st_rctoken.sxname = sxnonvar;
        st_rctoken.sxindex = _T("");
        st_rctoken.index = 0;
        st_rctoken.is_variable = false;
        st_rctoken.has_brackets = false;
        v_rctokens.insert(v_rctokens.begin() + st_idx + 1, st_rctoken);
        v_pos.insert(v_pos.begin() + st_idx + 1, v_pos[st_idx] + st_next);
      }
    }
  }

  // Special Autotype processing
  bDoAutoType = false;
  sxAutoType = _T("");
  for (size_t st_idx = 0; st_idx < v_rctokens.size(); st_idx++) {
    if (!v_rctokens[st_idx].is_variable)
      continue;

    // Is it a autotype variable?
    if (v_rctokens[st_idx].sxname == _T("a") ||
        v_rctokens[st_idx].sxname == _T("autotype")) {
      bDoAutoType = true;
      // Is the next token text and starts with '('?
      if (st_idx + 1 < v_rctokens.size() &&
          !v_rctokens[st_idx + 1].is_variable &&
          v_rctokens[st_idx + 1].sxname.c_str()[0] == _T('(')) {
        // Find ending round bracket
        StringX sx_autotype = v_rctokens[st_idx + 1].sxname;
        StringX::size_type st_end_rb = sx_autotype.find(_T(')'));
        if (st_end_rb == StringX::npos) {
          st_column = v_pos[st_idx + 1] + sx_autotype.length() + 2;
          // Missing end round bracket
          uierr = IDSC_EXS_MISSINGROUNDBKT;
          goto exit;
        }
        sxAutoType = sx_autotype.substr(1, st_end_rb - 1);
        v_rctokens[st_idx + 1].sxname = sx_autotype.substr(st_end_rb + 1);
        // Check if anything left in this text - none -> delete
        if (v_rctokens[st_idx + 1].sxname.length() == 0)
          v_rctokens.erase(v_rctokens.begin() + st_idx + 1);
        // Now delete Autotype variable
        v_rctokens.erase(v_rctokens.begin() + st_idx);
        break;
      }
    }
  }

exit:
  if (uierr != 0)
    LoadAString(serrmsg, uierr);
  else
    serrmsg = _T("");

  if (uierr > 0) {
    v_rctokens.clear();
  }
  v_pos.clear();
  return uierr;
}
stringT PWScore::Merge(PWScore *pothercore,
                       const bool &subgroup_bset,
                       const stringT &subgroup_name,
                       const int &subgroup_object, const int &subgroup_function,
                       CReport *pRpt, bool *pbCancel)
{
  std::vector<StringX> vs_added;
  std::vector<StringX> vs_AliasesAdded;
  std::vector<StringX> vs_ShortcutsAdded;
  std::vector<StringX> vs_PoliciesAdded;
  std::map<StringX, StringX> mapRenamedPolicies;

  const StringX sxMerge_DateTime = PWSUtil::GetTimeStamp(true).c_str();

  stringT str_timestring;  // To append to title if already in current database
  str_timestring = sxMerge_DateTime.c_str();
  Remove(str_timestring, _T('/'));
  Remove(str_timestring, _T(':'));

  /*
    Purpose:
      Merge entries from otherCore to m_core

    Algorithm:
      Foreach entry in otherCore
        Find in m_core based on group/title/username
          if match found {
            if all other fields match {
              no merge
            } else {
              add to m_core with new title suffixed with -merged-YYYYMMDD-HHMMSS
            }
          } else {
            add to m_core directly
          }
   */

  int numAdded = 0;
  int numConflicts = 0;
  int numAliasesAdded = 0;
  int numShortcutsAdded = 0;
  uuid_array_t base_uuid, new_base_uuid;
  bool bTitleRenamed(false);
  StringX sx_merged;
  LoadAString(sx_merged, IDSC_MERGED);

  MultiCommands *pmulticmds = MultiCommands::Create(this);
  Command *pcmd1 = UpdateGUICommand::Create(this, UpdateGUICommand::WN_UNDO,
                                            UpdateGUICommand::GUI_UNDO_MERGESYNC);
  pmulticmds->Add(pcmd1);

  ItemListConstIter otherPos;
  for (otherPos = pothercore->GetEntryIter();
       otherPos != pothercore->GetEntryEndIter();
       otherPos++) {
    // See if user has cancelled
    if (pbCancel != NULL && *pbCancel) {
      delete pmulticmds;
      return _T("");
    }

    CItemData otherItem = pothercore->GetEntry(otherPos);
    CItemData::EntryType et = otherItem.GetEntryType();

    // Need to check that entry keyboard shortcut not already in use!
    int32 iKBShortcut;
    otherItem.GetKBShortcut(iKBShortcut);
    CUUID kbshortcut_uuid = GetKBShortcut(iKBShortcut);
    bool bKBShortcutInUse = (iKBShortcut != 0&& kbshortcut_uuid != CUUID::NullUUID());

    // Handle Aliases and Shortcuts when processing their base entries
    if (otherItem.IsDependent())
      continue;

    if (subgroup_bset &&
        !otherItem.Matches(subgroup_name, subgroup_object, subgroup_function))
      continue;

    const StringX sx_otherGroup = otherItem.GetGroup();
    const StringX sx_otherTitle = otherItem.GetTitle();
    const StringX sx_otherUser = otherItem.GetUser();

    StringX sxMergedEntry;
    Format(sxMergedEntry, GROUPTITLEUSERINCHEVRONS,
                sx_otherGroup.c_str(), sx_otherTitle.c_str(), sx_otherUser.c_str());

    ItemListConstIter foundPos = Find(sx_otherGroup, sx_otherTitle, sx_otherUser);

    otherItem.GetUUID(base_uuid);
    memcpy(new_base_uuid, base_uuid, sizeof(new_base_uuid));
    bTitleRenamed = false;

    if (foundPos != GetEntryEndIter()) {
      // Found a match, see if other fields also match
      CItemData curItem = GetEntry(foundPos);

      // Can't merge into a protected entry.  If we were going to - add instead
      unsigned char ucprotected;
      curItem.GetProtected(ucprotected);

      stringT str_diffs(_T("")), str_temp;
      int diff_flags = 0;
      int32 cxtint, oxtint;
      time_t cxt, oxt;
      if (otherItem.GetPassword() != curItem.GetPassword()) {
        diff_flags |= MRG_PASSWORD;
        LoadAString(str_temp, IDSC_FLDNMPASSWORD);
        str_diffs += str_temp + _T(", ");
      }

      if (otherItem.GetNotes() != curItem.GetNotes()) {
        diff_flags |= MRG_NOTES;
        LoadAString(str_temp, IDSC_FLDNMNOTES);
        str_diffs += str_temp + _T(", ");
      }

      if (otherItem.GetURL() != curItem.GetURL()) {
        diff_flags |= MRG_URL;
        LoadAString(str_temp, IDSC_FLDNMURL);
        str_diffs += str_temp + _T(", ");
      }

      if (otherItem.GetAutoType() != curItem.GetAutoType()) {
        diff_flags |= MRG_AUTOTYPE;
        LoadAString(str_temp, IDSC_FLDNMAUTOTYPE);
        str_diffs += str_temp + _T(", ");
      }

      if (otherItem.GetPWHistory() != curItem.GetPWHistory()) {
        diff_flags |= MRG_HISTORY;
        LoadAString(str_temp, IDSC_FLDNMPWHISTORY);
        str_diffs += str_temp + _T(", ");
      }

      // Don't test policy or symbols if either entry is using a named policy
      // as these are meaningless to compare
      if (otherItem.GetPolicyName().empty() && curItem.GetPolicyName().empty()) {
        PWPolicy cur_pwp, oth_pwp;
        if (curItem.GetPWPolicy().empty())
          cur_pwp = PWSprefs::GetInstance()->GetDefaultPolicy();
        else
          curItem.GetPWPolicy(cur_pwp);
        if (otherItem.GetPWPolicy().empty())
          oth_pwp = PWSprefs::GetInstance()->GetDefaultPolicy(true);
        else
          otherItem.GetPWPolicy(oth_pwp);
        if (cur_pwp != oth_pwp) {
          diff_flags |= MRG_POLICY;
          LoadAString(str_temp, IDSC_FLDNMPWPOLICY);
          str_diffs += str_temp + _T(", ");
        }
      }

      otherItem.GetXTime(oxt);
      curItem.GetXTime(cxt);
      if (oxt != cxt) {
        diff_flags |= MRG_XTIME;
        LoadAString(str_temp, IDSC_FLDNMXTIME);
        str_diffs += str_temp + _T(", ");
      }

      otherItem.GetXTimeInt(oxtint);
      curItem.GetXTimeInt(cxtint);
      if (oxtint != cxtint) {
        diff_flags |= MRG_XTIME_INT;
        LoadAString(str_temp, IDSC_FLDNMXTIMEINT);
        str_diffs += str_temp + _T(", ");
      }

      if (otherItem.GetRunCommand() != curItem.GetRunCommand()) {
        diff_flags |= MRG_EXECUTE;
        LoadAString(str_temp, IDSC_FLDNMRUNCOMMAND);
        str_diffs += str_temp + _T(", ");
      }

      // Must use integer values not compare strings
      short other_hDCA, cur_hDCA;
      otherItem.GetDCA(other_hDCA);
      curItem.GetDCA(cur_hDCA);
      if (other_hDCA != cur_hDCA) {
        diff_flags |= MRG_DCA;
        LoadAString(str_temp, IDSC_FLDNMDCA);
        str_diffs += str_temp + _T(", ");
      }

      if (otherItem.GetEmail() != curItem.GetEmail()) {
        diff_flags |= MRG_EMAIL;
        LoadAString(str_temp, IDSC_FLDNMEMAIL);
        str_diffs += str_temp + _T(", ");
      }

      if (otherItem.GetSymbols() != curItem.GetSymbols()) {
        diff_flags |= MRG_SYMBOLS;
        LoadAString(str_temp, IDSC_FLDNMSYMBOLS);
        str_diffs += str_temp + _T(", ");
      }

      otherItem.GetShiftDCA(other_hDCA);
      curItem.GetShiftDCA(cur_hDCA);
      if (other_hDCA != cur_hDCA) {
        diff_flags |= MRG_SHIFTDCA;
        LoadAString(str_temp, IDSC_FLDNMSHIFTDCA);
        str_diffs += str_temp + _T(", ");
      }

      PWPolicy st_to_pp, st_from_pp;
      StringX sxCurrentPolicyName = curItem.GetPolicyName();
      StringX sxOtherPolicyName = otherItem.GetPolicyName();
      bool bCurrent(false), bOther(false);

      if (!sxCurrentPolicyName.empty())
        bCurrent = GetPolicyFromName(sxCurrentPolicyName, st_to_pp);
      if (!sxOtherPolicyName.empty())
        bOther = pothercore->GetPolicyFromName(sxOtherPolicyName, st_from_pp);

      /*
        There will be differences if only one has a named password policy, or
        both have policies but the new entry's one is not in our database, or
        both have the same policy but they are different
      */
      if ((bCurrent && !bOther) || (!bCurrent && bOther) ||
          sxCurrentPolicyName != sxOtherPolicyName ||
          (bCurrent && bOther && st_to_pp != st_from_pp)) {
        diff_flags |= MRG_POLICYNAME;
        LoadAString(str_temp, IDSC_FLDNMPWPOLICYNAME);
        str_diffs += str_temp + _T(", ");
      }

      if (diff_flags != 0) {
        // have a match on group/title/user, but not on other fields
        // add an entry suffixed with -merged-YYYYMMDD-HHMMSS
        StringX sx_newTitle;
        Format(sx_newTitle, L"%ls-%ls-%ls", sx_otherTitle.c_str(), sx_merged.c_str(),
                            str_timestring.c_str());

        // note it as an issue for the user
        stringT strWarnMsg;
        Format(strWarnMsg, IDSC_MERGECONFLICTS,
                       sx_otherGroup.c_str(), sx_otherTitle.c_str(), sx_otherUser.c_str(),
                       sx_otherGroup.c_str(), sx_newTitle.c_str(), sx_otherUser.c_str(),
                       str_diffs.c_str());

        // log it
        if (pRpt != NULL)
          pRpt->WriteLine(strWarnMsg.c_str());

        // Check no conflict of unique uuid
        if (Find(base_uuid) != GetEntryEndIter()) {
          otherItem.CreateUUID();
          otherItem.GetUUID(new_base_uuid);
        }

        // Special processing for password policies (default & named)
        bool bUpdated; // not needed for Merge

        Command *pPolicyCmd = ProcessPolicyName(pothercore, otherItem,
                             mapRenamedPolicies, vs_PoliciesAdded,
                             sxOtherPolicyName, bUpdated,
                             sxMerge_DateTime, IDSC_MERGEPOLICY);

        if (pPolicyCmd != NULL)
          pmulticmds->Add(pPolicyCmd);

        // About to add entry - check keyboard shortcut
        if (bKBShortcutInUse) {
          // Remove it
          otherItem.SetKBShortcut(0);
          //  Tell user via the report
          ItemListIter iter = Find(kbshortcut_uuid);
          if (iter != m_pwlist.end()) {
            StringX sxTemp, sxExistingEntry;
            Format(sxExistingEntry, GROUPTITLEUSERINCHEVRONS,
                iter->second.GetGroup().c_str(), iter->second.GetTitle().c_str(),
                iter->second.GetUser().c_str());
            Format(sxTemp, IDSC_KBSHORTCUT_REMOVED, sx_merged.c_str(), sxMergedEntry.c_str(),
                          sxExistingEntry.c_str(), sx_merged.c_str());
            pRpt->WriteLine(sxTemp.c_str());
          }
        }
        
        otherItem.SetTitle(sx_newTitle);
        otherItem.SetStatus(CItemData::ES_ADDED);
        Command *pcmd = AddEntryCommand::Create(this, otherItem);
        pcmd->SetNoGUINotify();
        pmulticmds->Add(pcmd);

        // Update the Wizard page
        UpdateWizard(sxMergedEntry.c_str());

        numConflicts++;
      }
    } else {
      // Didn't find any match...add it directly
      // Check no conflict of unique uuid
      if (Find(base_uuid) != GetEntryEndIter()) {
        otherItem.CreateUUID();
        otherItem.GetUUID(new_base_uuid);
      }

      // Special processing for password policies (default & named)
      bool bUpdated;  // Not needed for Merge
      StringX sxOtherPolicyName = otherItem.GetPolicyName();

      Command *pPolicyCmd = ProcessPolicyName(pothercore, otherItem,
                           mapRenamedPolicies, vs_PoliciesAdded,
                           sxOtherPolicyName, bUpdated,
                           sxMerge_DateTime, IDSC_MERGEPOLICY);

      if (pPolicyCmd != NULL)
        pmulticmds->Add(pPolicyCmd);

      // About to add entry - check keyboard shortcut
      if (bKBShortcutInUse) {
        // Remove it
        otherItem.SetKBShortcut(0);
        //  Tell user via the report
        ItemListIter iter = Find(kbshortcut_uuid);
        if (iter != m_pwlist.end()) {
          StringX sxTemp, sxExistingEntry;
          Format(sxExistingEntry, GROUPTITLEUSERINCHEVRONS,
                iter->second.GetGroup().c_str(), iter->second.GetTitle().c_str(),
                iter->second.GetUser().c_str());
          Format(sxTemp, IDSC_KBSHORTCUT_REMOVED, sx_merged.c_str(), sxMergedEntry.c_str(),
                        sxExistingEntry.c_str(), sx_merged.c_str());
          pRpt->WriteLine(sxTemp.c_str());
        }
      }
      
      otherItem.SetStatus(CItemData::ES_ADDED);
      Command *pcmd = AddEntryCommand::Create(this, otherItem);
      pcmd->SetNoGUINotify();
      pmulticmds->Add(pcmd);

      StringX sx_added;
      Format(sx_added, GROUPTITLEUSERINCHEVRONS,
                sx_otherGroup.c_str(), sx_otherTitle.c_str(), sx_otherUser.c_str());
      vs_added.push_back(sx_added);

      // Update the Wizard page
      UpdateWizard(sx_added.c_str());
      numAdded++;
    }

    if (et == CItemData::ET_ALIASBASE)
      numAliasesAdded += MergeDependents(pothercore, pmulticmds,
                      base_uuid, new_base_uuid,
                      bTitleRenamed, str_timestring, CItemData::ET_ALIAS,
                      vs_AliasesAdded);

    if (et == CItemData::ET_SHORTCUTBASE)
      numShortcutsAdded += MergeDependents(pothercore, pmulticmds,
                      base_uuid, new_base_uuid,
                      bTitleRenamed, str_timestring, CItemData::ET_SHORTCUT,
                      vs_ShortcutsAdded);
  } // iteration over other core's entries

  stringT str_results;
  if (numAdded > 0 && pRpt != NULL) {
    std::sort(vs_added.begin(), vs_added.end(), MergeSyncGTUCompare);
    stringT str_singular_plural_type, str_singular_plural_verb;
    LoadAString(str_singular_plural_type, numAdded == 1 ? IDSC_ENTRY : IDSC_ENTRIES);
    LoadAString(str_singular_plural_verb, numAdded == 1 ? IDSC_WAS : IDSC_WERE);
    Format(str_results, IDSC_MERGEADDED, str_singular_plural_type.c_str(),
                    str_singular_plural_verb.c_str());
    pRpt->WriteLine(str_results.c_str());
    for (size_t i = 0; i < vs_added.size(); i++) {
      Format(str_results, L"\t%ls", vs_added[i].c_str());
      pRpt->WriteLine(str_results.c_str());
    }
  }

  if (numAliasesAdded > 0 && pRpt != NULL) {
    std::sort(vs_AliasesAdded.begin(), vs_AliasesAdded.end(), MergeSyncGTUCompare);
    stringT str_singular_plural_type, str_singular_plural_verb;
    LoadAString(str_singular_plural_type, numAliasesAdded == 1 ? IDSC_ENTRY : IDSC_ENTRIES);
    LoadAString(str_singular_plural_verb, numAliasesAdded == 1 ? IDSC_WAS : IDSC_WERE);
    Format(str_results, IDSC_MERGEADDED, str_singular_plural_type.c_str(),
                    str_singular_plural_verb.c_str());
    pRpt->WriteLine(str_results.c_str());
    for (size_t i = 0; i < vs_AliasesAdded.size(); i++) {
      Format(str_results, _T("\t%ls"), vs_AliasesAdded[i].c_str());
      pRpt->WriteLine(str_results.c_str());
    }
  }

  if (numShortcutsAdded > 0 && pRpt != NULL) {
    std::sort(vs_ShortcutsAdded.begin(), vs_ShortcutsAdded.end(), MergeSyncGTUCompare);
    stringT str_singular_plural_type, str_singular_plural_verb;
    LoadAString(str_singular_plural_type, numShortcutsAdded == 1 ? IDSC_ENTRY : IDSC_ENTRIES);
    LoadAString(str_singular_plural_verb, numShortcutsAdded == 1 ? IDSC_WAS : IDSC_WERE);
    Format(str_results, IDSC_MERGEADDED, str_singular_plural_type.c_str(),
                    str_singular_plural_verb.c_str());
    pRpt->WriteLine(str_results.c_str());
    for (size_t i = 0; i < vs_ShortcutsAdded.size(); i++) {
      Format(str_results, L"\t%ls", vs_ShortcutsAdded[i].c_str());
      pRpt->WriteLine(str_results.c_str());
    }
  }

  // See if user has cancelled
  if (pbCancel != NULL && *pbCancel) {
    delete pmulticmds;
    return _T("");
  }

  Command *pcmd2 = UpdateGUICommand::Create(this, UpdateGUICommand::WN_REDO,
                                            UpdateGUICommand::GUI_REDO_MERGESYNC);
  pmulticmds->Add(pcmd2);
  Execute(pmulticmds);

  // See if user has cancelled too late - reset flag so incorrect information not given to user
  if (pbCancel != NULL && *pbCancel) {
    *pbCancel = false;
  }

  // Tell the user we're done & provide short merge report
  stringT str_entries, str_conflicts, str_aliases, str_shortcuts;
  int totalAdded = numAdded + numConflicts + numAliasesAdded + numShortcutsAdded;
  LoadAString(str_entries, totalAdded == 1 ? IDSC_ENTRY : IDSC_ENTRIES);
  LoadAString(str_conflicts, numConflicts == 1 ? IDSC_CONFLICT : IDSC_CONFLICTS);
  LoadAString(str_aliases, numAliasesAdded == 1 ? IDSC_ALIAS : IDSC_ALIASES);
  LoadAString(str_shortcuts, numShortcutsAdded == 1 ? IDSC_SHORTCUT : IDSC_SHORTCUTS);

  Format(str_results, IDSC_MERGECOMPLETED,
                   totalAdded, str_entries.c_str(),
                   numConflicts, str_conflicts.c_str(),
                   numAliasesAdded, str_aliases.c_str(),
                   numShortcutsAdded, str_shortcuts.c_str());
  pRpt->WriteLine(str_results.c_str());

  return str_results;
}
예제 #24
0
bool PWSRun::runcmd(const StringX &run_command, const bool &bAutotype) const
{
  // Get first parameter either enclosed by quotes or delimited by a space
  StringX full_string(run_command), first_part(_T("")), the_rest(_T(""));
  StringX env_var, sx_temp(_T(""));
  StringX::size_type end_delim;
  bool bfound(true);

  TrimLeft(full_string, _T(" "));
  if (full_string.c_str()[0] == _T('"')) {
    end_delim = full_string.find(_T('"'), 1);
    first_part = full_string.substr(1, end_delim - 1);
    the_rest = full_string.substr(end_delim + 1);
  } else {
    end_delim = full_string.find(_T(' '));
    if (end_delim != StringX::npos) {
      first_part = full_string.substr(0, end_delim);
      the_rest = full_string.substr(end_delim + 1);
    } else
      first_part = full_string;
  }

  // tokenize into separate elements using % as the field separator.
  // If this corresponds to a set envrionmental variable - replace it
  // and rebuild the command
  for (StringX::size_type st_startpos = 0;
       st_startpos < first_part.size();
       /* st_startpos advanced in body */) {
    StringX::size_type st_next = first_part.find(_T('%'), st_startpos);
    if (st_next == StringX::npos) {
      sx_temp += first_part.substr(st_startpos);
      break;
    }
    if (st_next > 0) {
      env_var = first_part.substr(st_startpos, st_next - st_startpos);
      size_t mblen = pws_os::wcstombs(NULL, 0, env_var.c_str(), size_t(-1), false);
      unsigned char * mbtemp = new unsigned char[mblen + 1];
      // Finally get result
      size_t tmplen = pws_os::wcstombs((char *)mbtemp, mblen, env_var.c_str(),
                                       size_t(-1), false);
      if (tmplen != mblen) {
        return false;
      }
      mbtemp[mblen - 1] = '\0';
      StringX envar = (pws_os::getenv((char *)mbtemp, false)).c_str();
      if (!envar.empty()) {
        sx_temp += envar;
      } else {
        sx_temp += StringX(_T("%")) + env_var + StringX(_T("%"));
      }
    }
    st_startpos = st_next + 1; // too complex for for statement
  } // tokenization for loop

  // Replace string by rebuilt string
  first_part = sx_temp;

  first_part = getruncmd(first_part, bfound);

  bool rc;
  if (bfound)
    rc = issuecmd(first_part, the_rest, bAutotype);
  else
    rc = issuecmd(full_string, _T(""), bAutotype);

  return rc;
}
예제 #25
0
UINT CAddEdit_Basic::ExternalEditorThread(LPVOID me) // static method!
{
    CAddEdit_Basic *self = (CAddEdit_Basic *)me;

    wchar_t szExecName[MAX_PATH + 1];
    wchar_t lpPathBuffer[4096];
    DWORD dwBufSize(4096);

    StringX sxEditor = PWSprefs::GetInstance()->GetPref(PWSprefs::AltNotesEditor);
    if (sxEditor.empty()) {
        // Find out the users default editor for "txt" files
        DWORD dwSize(MAX_PATH);
        HRESULT stat = ::AssocQueryString(0, ASSOCSTR_EXECUTABLE, L".txt", L"Open",
                                          szExecName, &dwSize);
        if (int(stat) != S_OK) {
#ifdef _DEBUG
            CGeneralMsgBox gmb;
            gmb.AfxMessageBox(L"oops");
#endif
            // Send error return (WPARAM != 0)
            self->PostMessage(PWS_MSG_EXTERNAL_EDITOR_ENDED, 16, 0);
            return 16;
        }
        sxEditor = szExecName;
    }

    DWORD dwResult = ExpandEnvironmentStrings(sxEditor.c_str(), szExecName, MAX_PATH + 1);
    if (dwResult == 0 || dwResult > (MAX_PATH + 1)) {
        CGeneralMsgBox gmb;
        CString cs_msg, cs_title(MAKEINTRESOURCE(IDS_EDITEXTERNALLY));
        cs_msg.Format(IDS_CANT_FIND_EXT_EDITOR, sxEditor.c_str());
        gmb.MessageBox(cs_msg, cs_title, MB_OK | MB_ICONEXCLAMATION);

        // Send error return (WPARAM != 0)
        self->PostMessage(PWS_MSG_EXTERNAL_EDITOR_ENDED, 16, 0);
        return 0;
    }

    sxEditor = szExecName;

    if (!pws_os::FileExists(sxEditor.c_str())) {
        CGeneralMsgBox gmb;
        CString cs_msg, cs_title(MAKEINTRESOURCE(IDS_EDITEXTERNALLY));
        cs_msg.Format(IDS_CANT_FIND_EXT_EDITOR, sxEditor.c_str());
        gmb.MessageBox(cs_msg, cs_title, MB_OK | MB_ICONEXCLAMATION);

        // Send error return (WPARAM != 0)
        self->PostMessage(PWS_MSG_EXTERNAL_EDITOR_ENDED, 16, 0);
        return 0;
    }

    // Now we know the editor exists - go copy the data for it!
    // Get the temp path
    GetTempPath(dwBufSize,          // length of the buffer
                lpPathBuffer);      // buffer for path

    // Create a temporary file.
    GetTempFileName(lpPathBuffer,          // directory for temp files
                    L"NTE",                // temp file name prefix
                    0,                     // create unique name
                    self->m_szTempName);   // buffer for name

    FILE *fd;

    if ((fd = pws_os::FOpen(self->m_szTempName, _T("w+b"))) == NULL) {
        return 0;
    }

    // Write BOM
    const unsigned int iBOM = 0xFEFF;
    putwc(iBOM, fd);

    // Write out text
    fwrite(reinterpret_cast<const void *>((LPCWSTR)self->M_realnotes()), sizeof(BYTE),
           self->M_realnotes().GetLength() * sizeof(TCHAR), fd);

    // Close file before invoking editor
    fclose(fd);

    // Create an Edit process
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

    DWORD dwCreationFlags(0);
    dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;

    CString cs_CommandLine;

    // Make the command line = "<program>" "file"
    cs_CommandLine.Format(L"\"%s\" \"%s\"", sxEditor.c_str(), self->m_szTempName);
    int ilen = cs_CommandLine.GetLength();
    LPWSTR pszCommandLine = cs_CommandLine.GetBuffer(ilen);

    if (!CreateProcess(NULL, pszCommandLine, NULL, NULL, FALSE, dwCreationFlags,
                       NULL, lpPathBuffer, &si, &pi)) {
        pws_os::IssueError(L"External Editor CreateProcess", false);
        CGeneralMsgBox gmb;
        gmb.AfxMessageBox(IDS_CANT_FIND_EXT_EDITOR, MB_OK | MB_ICONEXCLAMATION);

        // Delete temporary file
        _wremove(self->m_szTempName);
        SecureZeroMemory(self->m_szTempName, sizeof(self->m_szTempName));

        // Send error return (WPARAM != 0)
        self->PostMessage(PWS_MSG_EXTERNAL_EDITOR_ENDED, 16, 0);
        return 0;
    }

    pws_os::Trace(L"%d\n", sizeof(self->m_szTempName));
    WaitForInputIdle(pi.hProcess, INFINITE);

    // Wait until child process exits.
    WaitForSingleObject(pi.hProcess, INFINITE);

    // Close process and thread handles.
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    cs_CommandLine.ReleaseBuffer();

    self->PostMessage(PWS_MSG_EXTERNAL_EDITOR_ENDED, 0, 0);
    return 0;
}
예제 #26
0
void PasswordSafeSearch::FindMatches(const StringX& searchText, bool fCaseSensitive, SearchPointer& searchPtr,
                                       const CItemData::FieldBits& bsFields, bool fUseSubgroups, const wxString& subgroupText,
                                       CItemData::FieldType subgroupObject, PWSMatch::MatchRule subgroupFunction,
                                       bool subgroupFunctionCaseSensitive, Iter begin, Iter end, Accessor afn)
{
  if (searchText.empty())
      return;

  searchPtr.Clear();

  typedef StringX (CItemData::*ItemDataFuncT)() const;

  struct {
      CItemData::FieldType type;
      ItemDataFuncT        func;
  } ItemDataFields[] = {  {CItemData::GROUP,     &CItemData::GetGroup},
                          {CItemData::TITLE,     &CItemData::GetTitle},
                          {CItemData::USER,      &CItemData::GetUser},
                          {CItemData::PASSWORD,  &CItemData::GetPassword},
//                        {CItemData::NOTES,     &CItemData::GetNotes},
                          {CItemData::URL,       &CItemData::GetURL},
                          {CItemData::EMAIL,     &CItemData::GetEmail},
                          {CItemData::RUNCMD,    &CItemData::GetRunCommand},
                          {CItemData::AUTOTYPE,  &CItemData::GetAutoType},
                          {CItemData::XTIME_INT, &CItemData::GetXTimeInt},

                      };

  for ( Iter itr = begin; itr != end; ++itr) {

    const int fn = (subgroupFunctionCaseSensitive? -subgroupFunction: subgroupFunction);
    if (fUseSubgroups && !afn(itr).Matches(stringT(subgroupText.c_str()), subgroupObject, fn))
        continue;

    bool found = false;
    for (size_t idx = 0; idx < NumberOf(ItemDataFields) && !found; ++idx) {
      if (bsFields.test(ItemDataFields[idx].type)) {
          const StringX str = (afn(itr).*ItemDataFields[idx].func)();
          found = fCaseSensitive? str.find(searchText) != StringX::npos: FindNoCase(searchText, str);
      }
    }

    if (!found && bsFields.test(CItemData::NOTES)) {
        StringX str = afn(itr).GetNotes();
        found = fCaseSensitive? str.find(searchText) != StringX::npos: FindNoCase(searchText, str);
    }

    if (!found && bsFields.test(CItemData::PWHIST)) {
        size_t pwh_max, err_num;
        PWHistList pwhistlist;
        CreatePWHistoryList(afn(itr).GetPWHistory(), pwh_max, err_num,
                            pwhistlist, PWSUtil::TMC_XML);
        for (PWHistList::iterator iter = pwhistlist.begin(); iter != pwhistlist.end(); iter++) {
          PWHistEntry pwshe = *iter;
          found = fCaseSensitive? pwshe.password.find(searchText) != StringX::npos: FindNoCase(searchText, pwshe.password );
          if (found)
            break;  // break out of for loop
        }
        pwhistlist.clear();
    }

    if (found) {
        uuid_array_t uuid;
        afn(itr).GetUUID(uuid);
        searchPtr.Add(pws_os::CUUID(uuid));
    }
  }
}
예제 #27
0
//-----------------------------------------------------------------
// Externally visible functions
//-----------------------------------------------------------------
StringX PWSAuxParse::GetExpandedString(const StringX &sxRun_Command,
                                       const StringX &sxCurrentDB, 
                                       const CItemData *pci, bool &bAutoType,
                                       StringX &sxAutotype, stringT &serrmsg, 
                                       StringX::size_type &st_column,
                                       bool &bURLSpecial)
{
  std::vector<st_RunCommandTokens> v_rctokens;
  std::vector<st_RunCommandTokens>::iterator rc_iter;
  StringX sxretval(_T("")), sxurl;
  stringT spath, sdrive, sdir, sfname, sextn;
  stringT sdbdir;
  bURLSpecial = false;

  UINT uierr = ParseRunCommand(sxRun_Command, v_rctokens, 
                               bAutoType, sxAutotype, 
                               serrmsg, st_column);

  // if called with NULL ci, then we just parse to validate
  if (uierr > 0 || pci == NULL || sxCurrentDB.empty()) {
    v_rctokens.clear();
    return sxretval;
  }

  // derive current db's directory and basename:
  spath = sxCurrentDB.c_str();
  pws_os::splitpath(spath, sdrive, sdir, sfname, sextn);
  sdbdir = pws_os::makepath(sdrive, sdir, _T(""), _T(""));

  for (rc_iter = v_rctokens.begin(); rc_iter < v_rctokens.end(); rc_iter++) {
    st_RunCommandTokens &st_rctoken = *rc_iter;

    if (!st_rctoken.is_variable) {
      sxretval += st_rctoken.sxname.c_str();
      continue;
    }

    if (st_rctoken.sxname == _T("appdir")) {
      sxretval += pws_os::getexecdir().c_str();
    } else
    if (st_rctoken.sxname == _T("dbdir")) {
      sxretval += sdbdir.c_str();
    } else
    if (st_rctoken.sxname == _T("fulldb")) {
      sxretval += spath.c_str();
    } else
    if (st_rctoken.sxname == _T("dbname")) {
      sxretval += sfname.c_str();
    } else
    if (st_rctoken.sxname == _T("dbextn")) {
      sxretval += sextn.c_str();
    } else
    if (st_rctoken.sxname == _T("g") || st_rctoken.sxname == _T("group")) {
      sxretval += pci->GetGroup();
    } else
    if (st_rctoken.sxname == _T("G") || st_rctoken.sxname == _T("GROUP")) {
      StringX sxg = pci->GetGroup();
      StringX::size_type st_index;
      st_index = sxg.rfind(_T("."));
      if (st_index != StringX::npos) {
        sxg = sxg.substr(st_index + 1);
      }
      sxretval += sxg;
    } else
    if (st_rctoken.sxname == _T("t") || st_rctoken.sxname == _T("title")) {
      sxretval += pci->GetTitle();
    } else
    if (st_rctoken.sxname == _T("u") || st_rctoken.sxname == _T("user")) {
      sxretval += pci->GetUser();
    } else
    if (st_rctoken.sxname == _T("p") || st_rctoken.sxname == _T("password")) {
      sxretval += pci->GetPassword();
    } else
      if (st_rctoken.sxname == _T("e") || st_rctoken.sxname == _T("email")) {
      sxretval += pci->GetEmail();
    } else
    if (st_rctoken.sxname == _T("a") || st_rctoken.sxname == _T("autotype")) {
      // Do nothing - autotype variable handled elsewhere
    } else
    if (st_rctoken.sxname == _T("url")) {
      sxurl = pci->GetURL();
      if (sxurl.length() > 0) {
        // Remove 'Browse to' specifics
        StringX::size_type ipos;
        ipos = sxurl.find(_T("[alt]"));
        if (ipos != StringX::npos) {
          bURLSpecial = true;
          sxurl.erase(ipos, 5);
        }
        ipos = sxurl.find(_T("[ssh]"));
        if (ipos != StringX::npos) {
          bURLSpecial = true;
          sxurl.erase(ipos, 5);
        }
        ipos = sxurl.find(_T("{alt}"));
        if (ipos != StringX::npos) {
          bURLSpecial = true;
          sxurl.erase(ipos, 5);
        }
        ipos = sxurl.find(_T("[autotype]"));
        if (ipos != StringX::npos) {
          sxurl.erase(ipos, 10);
        }
        ipos = sxurl.find(_T("[xa]"));
        if (ipos != StringX::npos) {
          sxurl.erase(ipos, 4);
        }
        sxretval += sxurl;
      }
    } else
    if (st_rctoken.sxname == _T("n") || st_rctoken.sxname == _T("notes")) {
      StringX sx_notes = pci->GetNotes();

      if (st_rctoken.index == 0) {
        sxretval += sx_notes;
      } else {
        std::vector<StringX> vsxnotes_lines;
        ParseNotes(sx_notes, vsxnotes_lines);
        // If line there - use it; otherwise ignore it
        if (st_rctoken.index > 0 && st_rctoken.index <= static_cast<int>(vsxnotes_lines.size())) {
          sxretval += vsxnotes_lines[st_rctoken.index - 1];
        } else
        if (st_rctoken.index < 0 &&
            abs(st_rctoken.index) <= static_cast<int>(vsxnotes_lines.size())) {
          sxretval += vsxnotes_lines[vsxnotes_lines.size() + st_rctoken.index];
        }
      }
    } else {
      // Unknown variable name - rebuild it
      sxretval += _T("$");
      if (st_rctoken.has_brackets)
        sxretval += _T("(");
      sxretval += st_rctoken.sxname.c_str();
      if (st_rctoken.index != 0)
        sxretval += st_rctoken.sxindex.c_str();
      if (st_rctoken.has_brackets)
        sxretval += _T(")");
    }
  }
  v_rctokens.clear();
  return sxretval;
}