Beispiel #1
0
bool CreatePWHistoryList(const StringX &pwh_str,
                         size_t &pwh_max, size_t &num_err,
                         PWHistList &pwhl, PWSUtil::TMC time_format)
{
  // Return boolean value stating if PWHistory status is active
  pwh_max = num_err = 0;
  pwhl.clear();
  StringX pwh_s = pwh_str;
  const size_t len = pwh_s.length();

  if (len < 5) {
    num_err = len != 0 ? 1 : 0;
    return false;
  }
  bool bStatus = pwh_s[0] != charT('0');

  int n;
  iStringXStream ism(StringX(pwh_s, 1, 2)); // max history 1 byte hex
  ism >> hex >> pwh_max;
  if (!ism)
    return false;

  iStringXStream isn(StringX(pwh_s, 3, 2)); // cur # entries 1 byte hex
  isn >> hex >> n;
  if (!isn)
    return false;

  // Sanity check: Each entry has at least 12 bytes representing
  // time + pw length
  // so if pwh_s isn't long enough check if it contains integral number of history records
  if (len - 5 < unsigned(12 * n)) {
    size_t offset = 5;
    bool err=false;
    while (offset < len) {
      offset += 8; //date
      if (offset + 4 >= len) { //passwd len
        err = true;
        break;
      }
      iStringXStream ispwlen(StringX(pwh_s, offset, 4)); // pw length 2 byte hex
      if (!ispwlen){
        err = true;
        break;
      }
      int ipwlen = 0;
      ispwlen >> hex >> ipwlen;
      if ( (ipwlen <= 0) || (offset + 4 + ipwlen > len) ) {
        err = true;
        break;
      }
      offset += 4 + ipwlen;
    }
    if ( err || (offset != len) ) {
      num_err = n;
      return false;
    }
    //number of errors will be counted later
  }
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));
    }
  }
}