/*
*
* Panbox - encryption for cloud storage
* Copyright (C) 2014-2015 by Fraunhofer SIT and Sirrix AG
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additonally, third party code may be provided with notices and open source
* licenses from communities and third parties that govern the use of those
* portions, and any licenses granted hereunder do not alter any rights and
* obligations you may have under such open source licenses, however, the
* disclaimer of warranty and limitation of liability provisions of the GPLv3
* will apply to all the product.
*
*/
package org.panbox.desktop.common.sharemgmt;
import java.io.File;
import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import java.security.KeyPair;
import java.security.UnrecoverableKeyException;
import java.util.HashMap;
import org.apache.log4j.Logger;
import org.panbox.PanboxConstants;
import org.panbox.core.exception.DeviceListException;
import org.panbox.core.exception.ObfuscationException;
import org.panbox.core.exception.ShareMetaDataException;
import org.panbox.core.keymgmt.IVolume;
import org.panbox.core.keymgmt.Volume;
import org.panbox.core.keymgmt.VolumeParams;
import org.panbox.core.vfs.backend.VirtualVolume;
import org.panbox.desktop.common.ex.DeviceKeyException;
import org.panbox.desktop.common.gui.shares.PanboxShare;
import org.panbox.desktop.common.vfs.backend.VFSShare;
public abstract class AbstractPanboxService implements IPanboxService {
private final HashMap<String, IVolume> volumeCache = new HashMap<>();
static final Logger logger = Logger.getLogger("org.panbox");
protected abstract void registerShare(VFSShare vfsShare, VolumeParams p);
protected abstract boolean unregisterShare(VolumeParams p);
protected abstract VirtualVolume getVirtualVolume(VolumeParams p)
throws FileNotFoundException;
private synchronized IVolume createVolume(VolumeParams p)
throws IllegalArgumentException, ShareMetaDataException {
String metaDataDir = p.path + File.separator
+ PanboxConstants.PANBOX_SHARE_METADATA_DIRECTORY
+ File.separator;
IVolume result = new Volume(metaDataDir);
result.createShareMetaData(p);
this.volumeCache.put(p.path, result);
return result;
}
private synchronized IVolume getVolumeFromCache(VolumeParams p)
throws ShareMetaDataException {
IVolume volume = this.volumeCache.get(p.path);
if (volume == null) {
throw new ShareMetaDataException(
"Called a method on non-existing IVolume!");
}
return volume;
}
@Override
public synchronized PanboxShare reloadShareMetaData(VolumeParams p)
throws ShareMetaDataException, RemoteException,
FileNotFoundException {
IVolume volume = this.volumeCache.get(p.path);
if (volume == null) {
throw new ShareMetaDataException(
"Called a method on non existing IVolume!");
}
volume.reload();
return PanboxShare.fromVolume(p.shareName, p.path, volume,
volume.getOwnerKey(), p.pubSigKey, p.type);
}
@Override
public synchronized PanboxShare createShare(VolumeParams p)
throws FileNotFoundException, IllegalArgumentException,
ShareMetaDataException, RemoteException {
VirtualVolume virtualVolume = getVirtualVolume(p);
IVolume volume = createVolume(p);
VFSShare vfsShare;
try {
vfsShare = new VFSShare(p.shareName, p.path, virtualVolume, volume,
new KeyPair(p.deviceKey, p.devicePrivateKey));
} catch (DeviceKeyException e) {
// This should never ever happen:
logger.fatal("No device keys found after creating a share!", e);
throw new ShareMetaDataException(
"No device keys found after creating a share!", e);
}
registerShare(vfsShare, p);
logger.debug("PanboxService: createShare: Successfully added share to Panbox! Sharename: "
+ p.shareName);
return PanboxShare.fromVolume(p.shareName, p.path, volume, p.pubSigKey,
p.pubSigKey, p.type);
}
@Override
public synchronized PanboxShare loadShare(VolumeParams p)
throws ShareMetaDataException, RemoteException,
FileNotFoundException {
String metaDataDir = p.path + File.separator
+ PanboxConstants.PANBOX_SHARE_METADATA_DIRECTORY
+ File.separator;
IVolume volume = new Volume(metaDataDir);
Exception ex = null;
try {
volume.loadShareMetaData(p.ownerSigKey);
this.volumeCache.put(p.path, volume);
} catch (ShareMetaDataException e) {
if (e.getCause() instanceof DeviceListException) {
ex = (DeviceListException) e.getCause();
this.volumeCache.put(p.path, volume);
} else {
throw e;
}
}
VirtualVolume virtualVolume = getVirtualVolume(p);
VFSShare vfsShare;
try {
vfsShare = new VFSShare(p.shareName, p.path, virtualVolume, volume,
new KeyPair(p.deviceKey, p.devicePrivateKey));
} catch (DeviceKeyException e) {
// At this point, possibly because of a conflict, the changes of
// acceptInvitation have been reverted, so no keys for the user's
// device have been found.
throw new ShareMetaDataException(
"No Obfuscation Key found for device " + p.deviceAlias, e);
}
registerShare(vfsShare, p);
logger.debug("PanboxService : loadShare : Successfully added share to Panbox! Sharename: "
+ p.shareName);
return PanboxShare.fromVolume(p.shareName, p.path, volume,
p.ownerSigKey, p.pubSigKey, p.type, ex);
}
@Override
public synchronized PanboxShare acceptInviation(VolumeParams p)
throws ShareMetaDataException, RemoteException,
FileNotFoundException {
String metaDataDir = p.path + File.separator
+ PanboxConstants.PANBOX_SHARE_METADATA_DIRECTORY
+ File.separator;
IVolume volume = new Volume(metaDataDir);
Exception ex = null;
try {
volume.acceptInvitation(p);
this.volumeCache.put(p.path, volume);
} catch (ShareMetaDataException e) {
if (e.getCause() instanceof DeviceListException) {
ex = (DeviceListException) e.getCause();
this.volumeCache.put(p.path, volume);
} else {
throw e;
}
}
VirtualVolume virtualVolume = getVirtualVolume(p);
VFSShare vfsShare;
try {
vfsShare = new VFSShare(p.shareName, p.path, virtualVolume, volume,
new KeyPair(p.deviceKey, p.devicePrivateKey));
} catch (DeviceKeyException e) {
// At this point, possibly because of a conflict, the changes of
// acceptInvitation above have been reverted so no keys for the
// users device have been found.
throw new ShareMetaDataException(
"No Obfuscation Key found for device " + p.deviceAlias, e);
}
registerShare(vfsShare, p);
logger.debug("PanboxService : loadShare : Successfully added share to Panbox! Sharename: "
+ p.shareName);
return PanboxShare.fromVolume(p.shareName, p.path, volume,
p.ownerSigKey, p.pubSigKey, p.type, ex);
}
@Override
public synchronized PanboxShare inviteUser(VolumeParams p)
throws ShareMetaDataException, RemoteException {
IVolume volume = getVolumeFromCache(p);
volume.inviteUser(p);
logger.debug("PanboxService : inviteUser : Successfully invited user to share! Sharename: "
+ p.shareName);
return PanboxShare.fromVolume(p.shareName, p.path, volume,
volume.getOwnerKey(), p.pubSigKey, p.type);
}
@Override
public synchronized PanboxShare addDevice(VolumeParams p)
throws IllegalArgumentException, ShareMetaDataException,
RemoteException {
IVolume volume = getVolumeFromCache(p);
volume.addDevice(p);
logger.info("PanboxService : addDevice : Successfully added device to share! Sharename: "
+ p.shareName);
return PanboxShare.fromVolume(p.shareName, p.path, volume,
volume.getOwnerKey(), p.pubSigKey, p.type);
}
@Override
public synchronized PanboxShare removeDevice(VolumeParams p)
throws IllegalArgumentException, ShareMetaDataException,
UnrecoverableKeyException, RemoteException {
IVolume volume = getVolumeFromCache(p);
logger.info("PanboxService : removeDevice : Successfully removed device from share! Sharename: "
+ p.shareName);
return PanboxShare.fromVolume(p.shareName, p.path, volume,
volume.getOwnerKey(), p.pubSigKey, p.type);
}
@Override
public synchronized void removeShare(VolumeParams p) throws RemoteException {
boolean removed = unregisterShare(p);
if (removed) {
logger.debug("PanboxService : removeShare : Successfully removed share from Panbox! Sharename: "
+ p.shareName);
this.volumeCache.remove(p.path);
} else {
logger.error("PanboxService : removeShare : Failed to remove share from Panbox! Sharename: "
+ p.shareName);
throw new RuntimeException(
"Failed to remove share from Panbox! Sharename: "
+ p.shareName);
}
}
@Override
public abstract String getOnlineFilename(VolumeParams p, String fileName)
throws RemoteException, FileNotFoundException, ObfuscationException;
}