Example #1
0
  private KdbContext EndXmlElement(KdbContext ctx, XmlPullParser xpp)
      throws XmlPullParserException {
    assert (xpp.getEventType() == XmlPullParser.END_TAG);

    String name = xpp.getName();
    if (ctx == KdbContext.KeePassFile && name.equalsIgnoreCase(ElemDocNode)) {
      return KdbContext.Null;
    } else if (ctx == KdbContext.Meta && name.equalsIgnoreCase(ElemMeta)) {
      return KdbContext.KeePassFile;
    } else if (ctx == KdbContext.Root && name.equalsIgnoreCase(ElemRoot)) {
      return KdbContext.KeePassFile;
    } else if (ctx == KdbContext.MemoryProtection && name.equalsIgnoreCase(ElemMemoryProt)) {
      return KdbContext.Meta;
    } else if (ctx == KdbContext.CustomIcons && name.equalsIgnoreCase(ElemCustomIcons)) {
      return KdbContext.Meta;
    } else if (ctx == KdbContext.CustomIcon && name.equalsIgnoreCase(ElemCustomIconItem)) {
      if (!customIconID.equals(PwDatabaseV4.UUID_ZERO)) {
        PwIconCustom icon = new PwIconCustom(customIconID, customIconData);
        db.customIcons.add(icon);
        db.iconFactory.put(icon);
      } else assert (false);

      customIconID = PwDatabaseV4.UUID_ZERO;
      customIconData = null;

      return KdbContext.CustomIcons;
    } else if (ctx == KdbContext.Binaries && name.equalsIgnoreCase(ElemBinaries)) {
      return KdbContext.Meta;
    } else if (ctx == KdbContext.CustomData && name.equalsIgnoreCase(ElemCustomData)) {
      return KdbContext.Meta;
    } else if (ctx == KdbContext.CustomDataItem && name.equalsIgnoreCase(ElemStringDictExItem)) {
      if (customDataKey != null && customDataValue != null) {
        db.customData.put(customDataKey, customDataValue);
      } else assert (false);

      customDataKey = null;
      customDataValue = null;

      return KdbContext.CustomData;
    } else if (ctx == KdbContext.Group && name.equalsIgnoreCase(ElemGroup)) {
      if (ctxGroup.uuid == null || ctxGroup.uuid.equals(PwDatabaseV4.UUID_ZERO)) {
        ctxGroup.uuid = UUID.randomUUID();
      }

      ctxGroups.pop();

      if (ctxGroups.size() == 0) {
        ctxGroup = null;
        return KdbContext.Root;
      } else {
        ctxGroup = ctxGroups.peek();
        return KdbContext.Group;
      }
    } else if (ctx == KdbContext.GroupTimes && name.equalsIgnoreCase(ElemTimes)) {
      return KdbContext.Group;
    } else if (ctx == KdbContext.Entry && name.equalsIgnoreCase(ElemEntry)) {
      if (ctxEntry.uuid == null || ctxEntry.uuid.equals(PwDatabaseV4.UUID_ZERO)) {
        ctxEntry.uuid = UUID.randomUUID();
      }

      if (entryInHistory) {
        ctxEntry = ctxHistoryBase;
        return KdbContext.EntryHistory;
      }

      return KdbContext.Group;
    } else if (ctx == KdbContext.EntryTimes && name.equalsIgnoreCase(ElemTimes)) {
      return KdbContext.Entry;
    } else if (ctx == KdbContext.EntryString && name.equalsIgnoreCase(ElemString)) {
      ctxEntry.strings.put(ctxStringName, ctxStringValue);
      ctxStringName = null;
      ctxStringValue = null;

      return KdbContext.Entry;
    } else if (ctx == KdbContext.EntryBinary && name.equalsIgnoreCase(ElemBinary)) {
      ctxEntry.binaries.put(ctxBinaryName, ctxBinaryValue);
      ctxBinaryName = null;
      ctxBinaryValue = null;

      return KdbContext.Entry;
    } else if (ctx == KdbContext.EntryAutoType && name.equalsIgnoreCase(ElemAutoType)) {
      return KdbContext.Entry;
    } else if (ctx == KdbContext.EntryAutoTypeItem && name.equalsIgnoreCase(ElemAutoTypeItem)) {
      ctxEntry.autoType.put(ctxATName, ctxATSeq);
      ctxATName = null;
      ctxATSeq = null;

      return KdbContext.EntryAutoType;
    } else if (ctx == KdbContext.EntryHistory && name.equalsIgnoreCase(ElemHistory)) {
      entryInHistory = false;
      return KdbContext.Entry;
    } else if (ctx == KdbContext.RootDeletedObjects && name.equalsIgnoreCase(ElemDeletedObjects)) {
      return KdbContext.Root;
    } else if (ctx == KdbContext.DeletedObject && name.equalsIgnoreCase(ElemDeletedObject)) {
      ctxDeletedObject = null;
      return KdbContext.RootDeletedObjects;
    } else {
      assert (false);

      throw new RuntimeException("Invalid end element");
    }
  }
Example #2
0
  private KdbContext ReadXmlElement(KdbContext ctx, XmlPullParser xpp)
      throws XmlPullParserException, IOException, InvalidDBException {
    String name = xpp.getName();
    switch (ctx) {
      case Null:
        if (name.equalsIgnoreCase(ElemDocNode)) {
          return SwitchContext(ctx, KdbContext.KeePassFile, xpp);
        } else ReadUnknown(xpp);
        break;

      case KeePassFile:
        if (name.equalsIgnoreCase(ElemMeta)) {
          return SwitchContext(ctx, KdbContext.Meta, xpp);
        } else if (name.equalsIgnoreCase(ElemRoot)) {
          return SwitchContext(ctx, KdbContext.Root, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Meta:
        if (name.equalsIgnoreCase(ElemGenerator)) {
          ReadString(xpp); // Ignore
        } else if (name.equalsIgnoreCase(ElemHeaderHash)) {
          String encodedHash = ReadString(xpp);
          if (!EmptyUtils.isNullOrEmpty(encodedHash) && (hashOfHeader != null)) {
            byte[] hash = Base64Coder.decode(encodedHash);
            if (!Arrays.equals(hash, hashOfHeader)) {
              throw new InvalidDBException();
            }
          }
        } else if (name.equalsIgnoreCase(ElemDbName)) {
          db.name = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemDbNameChanged)) {
          db.nameChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemDbDesc)) {
          db.description = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemDbDescChanged)) {
          db.descriptionChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemDbDefaultUser)) {
          db.defaultUserName = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemDbDefaultUserChanged)) {
          db.defaultUserNameChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemDbColor)) {
          // TODO: Add support to interpret the color if we want to allow changing the database
          // color
          db.color = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemDbMntncHistoryDays)) {
          db.maintenanceHistoryDays = ReadUInt(xpp, DEFAULT_HISTORY_DAYS);
        } else if (name.equalsIgnoreCase(ElemDbKeyChanged)) {
          db.keyLastChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemDbKeyChangeRec)) {
          db.keyChangeRecDays = ReadLong(xpp, -1);
        } else if (name.equalsIgnoreCase(ElemDbKeyChangeForce)) {
          db.keyChangeForceDays = ReadLong(xpp, -1);
        } else if (name.equalsIgnoreCase(ElemMemoryProt)) {
          return SwitchContext(ctx, KdbContext.MemoryProtection, xpp);
        } else if (name.equalsIgnoreCase(ElemCustomIcons)) {
          return SwitchContext(ctx, KdbContext.CustomIcons, xpp);
        } else if (name.equalsIgnoreCase(ElemRecycleBinEnabled)) {
          db.recycleBinEnabled = ReadBool(xpp, true);
        } else if (name.equalsIgnoreCase(ElemRecycleBinUuid)) {
          db.recycleBinUUID = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemRecycleBinChanged)) {
          db.recycleBinChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemEntryTemplatesGroup)) {
          db.entryTemplatesGroup = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemEntryTemplatesGroupChanged)) {
          db.entryTemplatesGroupChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemHistoryMaxItems)) {
          db.historyMaxItems = ReadInt(xpp, -1);
        } else if (name.equalsIgnoreCase(ElemHistoryMaxSize)) {
          db.historyMaxSize = ReadLong(xpp, -1);
        } else if (name.equalsIgnoreCase(ElemEntryTemplatesGroupChanged)) {
          db.entryTemplatesGroupChanged = ReadTime(xpp);
        } else if (name.equalsIgnoreCase(ElemLastSelectedGroup)) {
          db.lastSelectedGroup = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemLastTopVisibleGroup)) {
          db.lastTopVisibleGroup = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemBinaries)) {
          return SwitchContext(ctx, KdbContext.Binaries, xpp);
        } else if (name.equalsIgnoreCase(ElemCustomData)) {
          return SwitchContext(ctx, KdbContext.CustomData, xpp);
        }
        break;

      case MemoryProtection:
        if (name.equalsIgnoreCase(ElemProtTitle)) {
          db.memoryProtection.protectTitle = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtUserName)) {
          db.memoryProtection.protectUserName = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtPassword)) {
          db.memoryProtection.protectPassword = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtURL)) {
          db.memoryProtection.protectUrl = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtNotes)) {
          db.memoryProtection.protectNotes = ReadBool(xpp, false);
        } else if (name.equalsIgnoreCase(ElemProtAutoHide)) {
          db.memoryProtection.autoEnableVisualHiding = ReadBool(xpp, false);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case CustomIcons:
        if (name.equalsIgnoreCase(ElemCustomIconItem)) {
          return SwitchContext(ctx, KdbContext.CustomIcon, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case CustomIcon:
        if (name.equalsIgnoreCase(ElemCustomIconItemID)) {
          customIconID = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemCustomIconItemData)) {
          String strData = ReadString(xpp);
          if (strData != null && strData.length() > 0) {
            customIconData = Base64Coder.decode(strData);
          } else {
            assert (false);
          }
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Binaries:
        if (name.equalsIgnoreCase(ElemBinary)) {
          String key = xpp.getAttributeValue(null, AttrId);
          if (key != null) {
            ProtectedBinary pbData = ReadProtectedBinary(xpp);
            binPool.put(key, pbData);
          } else {
            ReadUnknown(xpp);
          }
        } else {
          ReadUnknown(xpp);
        }

        break;

      case CustomData:
        if (name.equalsIgnoreCase(ElemStringDictExItem)) {
          return SwitchContext(ctx, KdbContext.CustomDataItem, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case CustomDataItem:
        if (name.equalsIgnoreCase(ElemKey)) {
          customDataKey = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemValue)) {
          customDataValue = ReadString(xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Root:
        if (name.equalsIgnoreCase(ElemGroup)) {
          assert (ctxGroups.size() == 0);
          if (ctxGroups.size() != 0) throw new IOException("Group list should be empty.");

          db.rootGroup = new PwGroupV4();
          ctxGroups.push((PwGroupV4) db.rootGroup);
          ctxGroup = ctxGroups.peek();

          return SwitchContext(ctx, KdbContext.Group, xpp);
        } else if (name.equalsIgnoreCase(ElemDeletedObjects)) {
          return SwitchContext(ctx, KdbContext.RootDeletedObjects, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Group:
        if (name.equalsIgnoreCase(ElemUuid)) {
          ctxGroup.uuid = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemName)) {
          ctxGroup.name = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemNotes)) {
          ctxGroup.notes = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemIcon)) {
          ctxGroup.icon = db.iconFactory.getIcon((int) ReadUInt(xpp, 0));
        } else if (name.equalsIgnoreCase(ElemCustomIconID)) {
          ctxGroup.customIcon = db.iconFactory.getIcon(ReadUuid(xpp));
        } else if (name.equalsIgnoreCase(ElemTimes)) {
          return SwitchContext(ctx, KdbContext.GroupTimes, xpp);
        } else if (name.equalsIgnoreCase(ElemIsExpanded)) {
          ctxGroup.isExpanded = ReadBool(xpp, true);
        } else if (name.equalsIgnoreCase(ElemGroupDefaultAutoTypeSeq)) {
          ctxGroup.defaultAutoTypeSequence = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemEnableAutoType)) {
          ctxGroup.enableAutoType = StringToBoolean(ReadString(xpp));
        } else if (name.equalsIgnoreCase(ElemEnableSearching)) {
          ctxGroup.enableSearching = StringToBoolean(ReadString(xpp));
        } else if (name.equalsIgnoreCase(ElemLastTopVisibleEntry)) {
          ctxGroup.lastTopVisibleEntry = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemGroup)) {
          ctxGroup = new PwGroupV4();
          ctxGroups.peek().AddGroup(ctxGroup, true);
          ctxGroups.push(ctxGroup);

          return SwitchContext(ctx, KdbContext.Group, xpp);
        } else if (name.equalsIgnoreCase(ElemEntry)) {
          ctxEntry = new PwEntryV4();
          ctxGroup.AddEntry(ctxEntry, true);

          entryInHistory = false;
          return SwitchContext(ctx, KdbContext.Entry, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case Entry:
        if (name.equalsIgnoreCase(ElemUuid)) {
          ctxEntry.setUUID(ReadUuid(xpp));
        } else if (name.equalsIgnoreCase(ElemIcon)) {
          ctxEntry.icon = db.iconFactory.getIcon((int) ReadUInt(xpp, 0));
        } else if (name.equalsIgnoreCase(ElemCustomIconID)) {
          ctxEntry.customIcon = db.iconFactory.getIcon(ReadUuid(xpp));
        } else if (name.equalsIgnoreCase(ElemFgColor)) {
          ctxEntry.foregroundColor = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemBgColor)) {
          ctxEntry.backgroupColor = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemOverrideUrl)) {
          ctxEntry.overrideURL = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemTags)) {
          ctxEntry.tags = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemTimes)) {
          return SwitchContext(ctx, KdbContext.EntryTimes, xpp);
        } else if (name.equalsIgnoreCase(ElemString)) {
          return SwitchContext(ctx, KdbContext.EntryString, xpp);
        } else if (name.equalsIgnoreCase(ElemBinary)) {
          return SwitchContext(ctx, KdbContext.EntryBinary, xpp);
        } else if (name.equalsIgnoreCase(ElemAutoType)) {
          return SwitchContext(ctx, KdbContext.EntryAutoType, xpp);
        } else if (name.equalsIgnoreCase(ElemHistory)) {
          assert (!entryInHistory);

          if (!entryInHistory) {
            ctxHistoryBase = ctxEntry;
            return SwitchContext(ctx, KdbContext.EntryHistory, xpp);
          } else {
            ReadUnknown(xpp);
          }
        } else {
          ReadUnknown(xpp);
        }
        break;

      case GroupTimes:
      case EntryTimes:
        ITimeLogger tl;
        if (ctx == KdbContext.GroupTimes) {
          tl = ctxGroup;
        } else {
          tl = ctxEntry;
        }

        if (name.equalsIgnoreCase(ElemLastModTime)) {
          tl.setLastModificationTime(ReadTime(xpp));
        } else if (name.equalsIgnoreCase(ElemCreationTime)) {
          tl.setCreationTime(ReadTime(xpp));
        } else if (name.equalsIgnoreCase(ElemLastAccessTime)) {
          tl.setLastAccessTime(ReadTime(xpp));
        } else if (name.equalsIgnoreCase(ElemExpiryTime)) {
          tl.setExpiryTime(ReadTime(xpp));
        } else if (name.equalsIgnoreCase(ElemExpires)) {
          tl.setExpires(ReadBool(xpp, false));
        } else if (name.equalsIgnoreCase(ElemUsageCount)) {
          tl.setUsageCount(ReadULong(xpp, 0));
        } else if (name.equalsIgnoreCase(ElemLocationChanged)) {
          tl.setLocationChanged(ReadTime(xpp));
        } else {
          ReadUnknown(xpp);
        }
        break;

      case EntryString:
        if (name.equalsIgnoreCase(ElemKey)) {
          ctxStringName = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemValue)) {
          ctxStringValue = ReadProtectedString(xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case EntryBinary:
        if (name.equalsIgnoreCase(ElemKey)) {
          ctxBinaryName = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemValue)) {
          ctxBinaryValue = ReadProtectedBinary(xpp);
        }
        break;

      case EntryAutoType:
        if (name.equalsIgnoreCase(ElemAutoTypeEnabled)) {
          ctxEntry.autoType.enabled = ReadBool(xpp, true);
        } else if (name.equalsIgnoreCase(ElemAutoTypeObfuscation)) {
          ctxEntry.autoType.obfuscationOptions = ReadUInt(xpp, 0);
        } else if (name.equalsIgnoreCase(ElemAutoTypeDefaultSeq)) {
          ctxEntry.autoType.defaultSequence = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemAutoTypeItem)) {
          return SwitchContext(ctx, KdbContext.EntryAutoTypeItem, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case EntryAutoTypeItem:
        if (name.equalsIgnoreCase(ElemWindow)) {
          ctxATName = ReadString(xpp);
        } else if (name.equalsIgnoreCase(ElemKeystrokeSequence)) {
          ctxATSeq = ReadString(xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case EntryHistory:
        if (name.equalsIgnoreCase(ElemEntry)) {
          ctxEntry = new PwEntryV4();
          ctxHistoryBase.history.add(ctxEntry);

          entryInHistory = true;
          return SwitchContext(ctx, KdbContext.Entry, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case RootDeletedObjects:
        if (name.equalsIgnoreCase(ElemDeletedObject)) {
          ctxDeletedObject = new PwDeletedObject();
          db.deletedObjects.add(ctxDeletedObject);

          return SwitchContext(ctx, KdbContext.DeletedObject, xpp);
        } else {
          ReadUnknown(xpp);
        }
        break;

      case DeletedObject:
        if (name.equalsIgnoreCase(ElemUuid)) {
          ctxDeletedObject.uuid = ReadUuid(xpp);
        } else if (name.equalsIgnoreCase(ElemDeletionTime)) {
          ctxDeletedObject.setDeletionTime(ReadTime(xpp));
        } else {
          ReadUnknown(xpp);
        }
        break;

      default:
        ReadUnknown(xpp);
        break;
    }

    return ctx;
  }