Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions Manager/src/main/java/io/raspberrywallet/manager/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.raspberrywallet.contract.ServerConfig;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -24,12 +25,6 @@
@Setter(AccessLevel.PRIVATE)
final public class Configuration {

/**
* Session length in millis
*/
@JsonProperty("session-length")
private long sessionLength = 3600000;

/**
* Base path to all wallet specific files, by default equals to $HOME
*/
Expand Down Expand Up @@ -60,6 +55,12 @@ final public class Configuration {
@JsonProperty("bitcoin")
private BitcoinConfig bitcoinConfig;

/**
* Bitcoin configuration object
*/
@JsonProperty("server")
private ServerConfig serverConfig;

public Configuration() {
this(new ModulesConfiguration(), new BitcoinConfig());
}
Expand All @@ -78,20 +79,16 @@ public Configuration(ModulesConfiguration modulesConfig, BitcoinConfig bitcoinCo
println(ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE));
}

public Configuration(ModulesConfiguration modulesConfig, BitcoinConfig bitcoinConfig, long sessionLength,
String basePathPrefix, String version) {
public Configuration(ModulesConfiguration modulesConfig, BitcoinConfig bitcoinConfig,
String basePathPrefix) {
this(modulesConfig, bitcoinConfig);
this.sessionLength = sessionLength;
this.basePathPrefix = basePathPrefix;
this.version = version;
println(ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE));
}

public Configuration(long sessionLength, String basePathPrefix, String version) {
public Configuration(String basePathPrefix) {
this();
this.sessionLength = sessionLength;
this.basePathPrefix = basePathPrefix;
this.version = version;
println(ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE));
}

Expand Down Expand Up @@ -126,4 +123,5 @@ public static class BitcoinConfig {
@JsonProperty("user-agent")
private String userAgent = "RaspberryWallet";
}

}
30 changes: 7 additions & 23 deletions Manager/src/main/java/io/raspberrywallet/manager/Main.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package io.raspberrywallet.manager;

import com.stasbar.Logger;
import io.raspberrywallet.contract.WalletNotInitialized;
import io.raspberrywallet.manager.bitcoin.Bitcoin;
import io.raspberrywallet.manager.cli.Opts;
import io.raspberrywallet.manager.cryptography.common.Password;
import io.raspberrywallet.manager.cryptography.crypto.exceptions.DecryptionException;
import io.raspberrywallet.manager.cryptography.crypto.exceptions.EncryptionException;
import io.raspberrywallet.manager.database.Database;
import io.raspberrywallet.manager.linux.TemperatureMonitor;
import io.raspberrywallet.manager.modules.Module;
Expand All @@ -17,13 +13,14 @@
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

import static io.raspberrywallet.manager.cli.CliUtils.parseArgs;
import static io.raspberrywallet.server.KtorServerKt.startKtorServer;

public class Main {

public static void main(String... args) throws IOException, DecryptionException, EncryptionException, BlockStoreException {
public static void main(String... args) throws BlockStoreException, IOException {
CommandLine cmd = parseArgs(args);

File yamlConfigFile = new File(Opts.CONFIG.getValue(cmd));
Expand All @@ -36,36 +33,23 @@ public static void main(String... args) throws IOException, DecryptionException,

TemperatureMonitor temperatureMonitor = new TemperatureMonitor();

//TODO change this to read from user
Password password = new Password("changeme".toCharArray());

Database db = new Database(configuration, password);
Database db = new Database(configuration);

Manager manager = new Manager(db, modules, bitcoin, temperatureMonitor);

startKtorServer(manager);
startKtorServer(manager, configuration.getBasePathPrefix(), configuration.getServerConfig());

prepareShutdownHook(bitcoin, manager);
prepareShutdownHook(bitcoin);
}

private static void prepareShutdownHook(Bitcoin bitcoin, Manager manager) {
private static void prepareShutdownHook(Bitcoin bitcoin) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
Logger.info("Finishing...");
try {
if (manager.lockWallet())
Logger.info("Wallet Encrypted");
else
Logger.err("Failed Wallet Encryption");

if (bitcoin.getPeerGroup() != null)
bitcoin.getPeerGroup().stop();

Objects.requireNonNull(bitcoin.getPeerGroup()).stop();
} catch (NullPointerException e) {
Logger.err("Failed Wallet Encryption");
e.printStackTrace();
} catch (WalletNotInitialized walletNotInitialized) {
Logger.d("Wallet was not inited so there is nothing to encrypt");
walletNotInitialized.printStackTrace();
}
// Forcibly terminate the JVM because Orchid likes to spew non-daemon threads everywhere.
Runtime.getRuntime().exit(0);
Expand Down
49 changes: 38 additions & 11 deletions Manager/src/main/java/io/raspberrywallet/manager/Manager.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.raspberrywallet.manager.linux.WifiStatus;
import io.raspberrywallet.manager.modules.Module;
import kotlin.text.Charsets;
import lombok.Getter;
import org.bitcoinj.core.Sha256Hash;
import org.jetbrains.annotations.NotNull;
import org.spongycastle.crypto.params.KeyParameter;
Expand All @@ -38,6 +39,7 @@ public class Manager implements io.raspberrywallet.contract.Manager {
* Module id -> Module instance
*/
@NotNull
@Getter
private final ConcurrentHashMap<String, Module> modules = new ConcurrentHashMap<>();
@NotNull
private final Bitcoin bitcoin;
Expand Down Expand Up @@ -93,7 +95,7 @@ public Response nextStep(@NotNull String moduleId, Map<String, String> input) {
*/

@Override
public List<io.raspberrywallet.contract.module.Module> getModules() {
public List<io.raspberrywallet.contract.module.Module> getServerModules() {
return modules.values().stream()
.map(Module::asServerModule)
.collect(toList());
Expand Down Expand Up @@ -149,10 +151,11 @@ public void restoreFromBackupPhrase(@NotNull List<String> mnemonicCode,
@Override
public WalletStatus getWalletStatus() {
try {
if (bitcoin.isFirstTime() || database.isFirstTime()) return WalletStatus.FIRST_TIME;
return bitcoin.getWallet().isEncrypted() ?
WalletStatus.ENCRYPTED : WalletStatus.DECRYPTED;
} catch (IllegalStateException | WalletNotInitialized e) {
return WalletStatus.UNSET;
} catch (WalletNotInitialized e) {
return WalletStatus.UNLOADED;
}
}

Expand All @@ -165,22 +168,36 @@ private KeyParameter getWalletCipherKey() {
@Override
public void unlockWallet(Map<String, Map<String, String>> moduleToInputsMap) throws WalletNotInitialized {
bitcoin.ensureWalletInitialized();
fillModulesWithInputs(moduleToInputsMap);
KeyParameter key = getWalletCipherKey();
try {
bitcoin.decryptWallet(key);
} finally {
Arrays.fill(key.getKey(), (byte) 0);
}
}

@Override
public void loadWalletFromDisk(@NotNull Map<String, Map<String, String>> moduleToInputsMap) {
fillModulesWithInputs(moduleToInputsMap);
KeyParameter key = getWalletCipherKey();
try {
bitcoin.setupWalletFromFile(key);
} finally {
Arrays.fill(key.getKey(), (byte) 0);
}

}

private void fillModulesWithInputs(@NotNull Map<String, Map<String, String>> moduleToInputsMap) {
moduleToInputsMap.forEach((moduleId, inputs) -> {
Module module = modules.get(moduleId);
Logger.d("Setting inputs for " + module.getId());
inputs.forEach((name, value) -> {
Logger.d(name + ": " + value);
});
inputs.forEach(module::setInput);

});

KeyParameter key = getWalletCipherKey();
try {
bitcoin.decryptWallet(key);
} finally {
Arrays.fill(key.getKey(), (byte) 0);
}
}

@Override
Expand Down Expand Up @@ -271,6 +288,16 @@ public void tap() {
autoLockRemainingMinutes = 10;
}

@Override
public void setDatabasePassword(@NotNull String password) throws SecurityException {
try {
database.setPassword(password);
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException(e);
}
}

/* Network */

@Override
Expand Down
Loading