/* * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, * and the EPL 1.0 (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.dev.util; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel.MapMode; import org.h2.engine.Constants; import org.h2.security.SHA256; import org.h2.store.fs.FileUtils; import org.h2.util.MathUtils; import org.h2.util.StringUtils; import org.h2.util.Utils; /** * A tool that removes passwords from an unencrypted database. */ public class RemovePasswords { /** * Run the tool. * * @param args the command line arguments */ public static void main(String... args) throws Exception { execute(args[0]); } private static void execute(String fileName) throws IOException { fileName = FileUtils.toRealPath(fileName); RandomAccessFile f = new RandomAccessFile(fileName, "rw"); long length = f.length(); MappedByteBuffer buff = f.getChannel() .map(MapMode.READ_WRITE, 0, length); byte[] data = new byte[200]; for (int i = 0; i < length - 200; i++) { if (buff.get(i) != 'C' || buff.get(i + 1) != 'R' || buff.get(i + 7) != 'U' || buff.get(i + 8) != 'S') { continue; } buff.position(i); buff.get(data); String s = new String(data, "UTF-8"); if (!s.startsWith("CREATE USER ")) { continue; } int saltIndex = Utils.indexOf(s.getBytes(), "SALT ".getBytes(), 0); if (saltIndex < 0) { continue; } String userName = s.substring("CREATE USER ".length(), s.indexOf("SALT ") - 1); if (userName.startsWith("IF NOT EXISTS ")) { userName = userName.substring("IF NOT EXISTS ".length()); } if (userName.startsWith("\"")) { // TODO doesn't work for all cases ("" inside // user name) userName = userName.substring(1, userName.length() - 1); } System.out.println("User: " + userName); byte[] userPasswordHash = SHA256.getKeyPasswordHash(userName, "".toCharArray()); byte[] salt = MathUtils.secureRandomBytes(Constants.SALT_LEN); byte[] passwordHash = SHA256 .getHashWithSalt(userPasswordHash, salt); StringBuilder b = new StringBuilder(); b.append("SALT '").append(StringUtils.convertBytesToHex(salt)) .append("' HASH '") .append(StringUtils.convertBytesToHex(passwordHash)) .append('\''); byte[] replacement = b.toString().getBytes(); buff.position(i + saltIndex); buff.put(replacement, 0, replacement.length); } f.close(); } }