CryptCodecProvider.java
- /*
- Copyright (c) 2010 Vladimir Berezniker
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package com.healthmarketscience.jackcess.crypt;
- import java.io.IOException;
- import java.nio.charset.Charset;
- import java.util.function.Supplier;
- import com.healthmarketscience.jackcess.crypt.impl.JetCryptCodecHandler;
- import com.healthmarketscience.jackcess.crypt.impl.MSISAMCryptCodecHandler;
- import com.healthmarketscience.jackcess.crypt.impl.OfficeCryptCodecHandler;
- import com.healthmarketscience.jackcess.impl.CodecHandler;
- import com.healthmarketscience.jackcess.impl.CodecProvider;
- import com.healthmarketscience.jackcess.impl.DefaultCodecProvider;
- import com.healthmarketscience.jackcess.impl.JetFormat;
- import com.healthmarketscience.jackcess.impl.PageChannel;
- /**
- * Implementation of CodecProvider with support for some forms of Microsoft
- * Access and Microsoft Money file encryption.
- * <p>
- * Note, not all "encrypted" access databases actually require passwords in
- * order to be opened. Many older forms of access "encryption" ("obfuscation"
- * would be a better term) include the keys within the access file itself. If
- * required, a password can be provided in one of two ways:
- * <ul>
- * <li>If a {@link PasswordCallback} or {@link Supplier} has been provided
- * (via the constructor or {@link #setPasswordCallback}), then
- * {@link PasswordCallback#getPassword} will be invoked to retrieve the
- * necessary password</li>
- * <li>If no password callback has been configured, then {@link #getPassword}
- * will be invoked directly on the CryptCodecProvider (which will return
- * the password configured via the constructor or {@link
- * #setPassword})</li>
- * </ul>
- *
- * @author Vladimir Berezniker
- */
- public class CryptCodecProvider implements CodecProvider, PasswordCallback
- {
- private String _password;
- private Supplier<String> _callback;
- public CryptCodecProvider() {
- this(null, null);
- }
- public CryptCodecProvider(String password) {
- this(password, null);
- }
- public CryptCodecProvider(PasswordCallback callback) {
- this(null, callback);
- }
- public CryptCodecProvider(Supplier<String> callback) {
- this(null, callback);
- }
- protected CryptCodecProvider(String password, Supplier<String> callback) {
- _password = password;
- _callback = callback;
- }
- @Override
- public String getPassword() {
- return _password;
- }
- public CryptCodecProvider setPassword(String newPassword) {
- _password = newPassword;
- return this;
- }
- public PasswordCallback getPasswordCallback() {
- return (PasswordCallback)getPasswordSupplier();
- }
- public Supplier<String> getPasswordSupplier() {
- return _callback;
- }
- public CryptCodecProvider setPasswordCallback(PasswordCallback newCallback) {
- return setPasswordSupplier(newCallback);
- }
- public CryptCodecProvider setPasswordSupplier(Supplier<String> newCallback) {
- _callback = newCallback;
- return this;
- }
- @Override
- public CodecHandler createHandler(PageChannel channel, Charset charset)
- throws IOException
- {
- // determine from where to retrieve the password
- Supplier<String> callback = getPasswordSupplier();
- if(callback == null) {
- callback = this;
- }
- JetFormat format = channel.getFormat();
- switch(format.CODEC_TYPE) {
- case NONE:
- // no encoding, all good
- return DefaultCodecProvider.DUMMY_HANDLER;
- case JET:
- return JetCryptCodecHandler.create(channel);
- case MSISAM:
- return MSISAMCryptCodecHandler.create(callback, channel, charset);
- case OFFICE:
- return OfficeCryptCodecHandler.create(callback, channel, charset);
- default:
- throw new RuntimeException("Unknown codec type " + format.CODEC_TYPE);
- }
- }
- }