001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hssf.record;
019:
020: import org.apache.poi.util.LittleEndian;
021:
022: /**
023: * Title: Password Record<P>
024: * Description: stores the encrypted password for a sheet or workbook (HSSF doesn't support encryption)
025: * REFERENCE: PG 371 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
026: * @author Andrew C. Oliver (acoliver at apache dot org)
027: * @version 2.0-pre
028: */
029:
030: public class PasswordRecord extends Record {
031: public final static short sid = 0x13;
032: private short field_1_password; // not sure why this is only 2 bytes, but it is... go figure
033:
034: public PasswordRecord() {
035: }
036:
037: /**
038: * Constructs a Password record and sets its fields appropriately.
039: * @param in the RecordInputstream to read the record from
040: */
041:
042: public PasswordRecord(RecordInputStream in) {
043: super (in);
044: }
045:
046: protected void validateSid(short id) {
047: if (id != sid) {
048: throw new RecordFormatException("NOT A PASSWORD RECORD");
049: }
050: }
051:
052: protected void fillFields(RecordInputStream in) {
053: field_1_password = in.readShort();
054: }
055:
056: //this is the world's lamest "security". thanks to Wouter van Vugt for making me
057: //not have to try real hard. -ACO
058: public static short hashPassword(String password) {
059: byte[] passwordCharacters = password.getBytes();
060: int hash = 0;
061: if (passwordCharacters.length > 0) {
062: int charIndex = passwordCharacters.length;
063: while (charIndex-- > 0) {
064: hash = ((hash >> 14) & 0x01) | ((hash << 1) & 0x7fff);
065: hash ^= passwordCharacters[charIndex];
066: }
067: // also hash with charcount
068: hash = ((hash >> 14) & 0x01) | ((hash << 1) & 0x7fff);
069: hash ^= passwordCharacters.length;
070: hash ^= (0x8000 | ('N' << 8) | 'K');
071: }
072: return (short) hash;
073: }
074:
075: /**
076: * set the password
077: *
078: * @param password representing the password
079: */
080:
081: public void setPassword(short password) {
082: field_1_password = password;
083: }
084:
085: /**
086: * get the password
087: *
088: * @return short representing the password
089: */
090: public short getPassword() {
091: return field_1_password;
092: }
093:
094: public String toString() {
095: StringBuffer buffer = new StringBuffer();
096:
097: buffer.append("[PASSWORD]\n");
098: buffer.append(" .password = ").append(
099: Integer.toHexString(getPassword())).append("\n");
100: buffer.append("[/PASSWORD]\n");
101: return buffer.toString();
102: }
103:
104: public int serialize(int offset, byte[] data) {
105: LittleEndian.putShort(data, 0 + offset, sid);
106: LittleEndian.putShort(data, 2 + offset, ((short) 0x02)); // 2 bytes (6 total)
107: LittleEndian.putShort(data, 4 + offset, getPassword());
108: return getRecordSize();
109: }
110:
111: public int getRecordSize() {
112: return 6;
113: }
114:
115: public short getSid() {
116: return sid;
117: }
118:
119: /**
120: * Clone this record.
121: */
122: public Object clone() {
123: PasswordRecord clone = new PasswordRecord();
124: clone.setPassword(field_1_password);
125: return clone;
126: }
127:
128: }
|