Commit 5f21bf5a authored by Cédric Moreau's avatar Cédric Moreau

Add Wizard configuration helper

parent f58b1509
#!/bin/bash
gpg --armor --export-secret-key $1
\ No newline at end of file
#!/bin/bash
gpg --list-secret-keys --fingerprint
\ No newline at end of file
......@@ -29,7 +29,10 @@ module.exports.pgp = openpgp;
var privateKey;
module.exports.privateKey = function () {
module.exports.privateKey = function (pvKey) {
if (pvKey) {
privateKey = pvKey;
}
return privateKey;
};
......@@ -38,9 +41,14 @@ module.exports.publicKey = function () {
return privateKey ? privateKey.toPublic().armor() : "";
};
module.exports.fingerprint = function () {
module.exports.cert = function () {
var ascciiPubkey = module.exports.publicKey();
return ascciiPubkey ? jpgp().certificate(ascciiPubkey).fingerprint : '';
return ascciiPubkey ? jpgp().certificate(ascciiPubkey) : null;
};
module.exports.fingerprint = function () {
var cert = module.exports.cert();
return cert ? cert.fingerprint : '';
};
module.exports.sign = function (message, done) {
......@@ -161,6 +169,68 @@ module.exports.services = {
init: initServices
};
module.exports.checkConf = function (conf, loggingMethod) {
var errors = [];
var privateKey = openpgp.key.readArmored(conf.pgpkey).keys[0];
if (conf.pgppasswd == null) {
conf.pgppasswd = "";
}
if (!privateKey) {
errors.push('This node requires a private key to work.');
}
try {
if(privateKey && !privateKey.decrypt(conf.pgppasswd)) {
errors.push('Wrong private key password.');
}
} catch(ex) {
errors.push('Not a valid private key, message was: "' + ex.message + '"');
}
if (!conf.currency) {
errors.push('No currency name was given.');
}
if(!conf.ipv4 && !conf.ipv6){
errors.push("No interface to listen to.");
}
if(!conf.remoteipv4 && !conf.remoteipv6){
errors.push('No interface for remote contact.');
}
if (!conf.remoteport) {
errors.push('No port for remote contact.');
}
if (conf.sync.AMDaemon == "ON") {
if (!conf.sync.AMStart) {
errors.push('Autovoting enabled but starting date not given');
}
if (!conf.sync.AMFreq) {
errors.push('Autovoting enabled but amendment frequency not given');
}
if (!conf.sync.UDFreq) {
errors.push('Autovoting enabled but dividend frequency not given');
}
if (!conf.sync.UD0) {
errors.push('Autovoting enabled but initial dividend not given');
}
if (!conf.sync.UDPercent) {
errors.push('Autovoting enabled but %dividend not given');
}
if (!conf.sync.Consensus) {
errors.push('Autovoting enabled but %required votes not given');
}
if (!conf.sync.MSExpires) {
errors.push('Autovoting enabled but membership validity not given');
}
if (!conf.sync.VTExpires) {
errors.push('Autovoting enabled but voting validity not given');
}
}
if (typeof loggingMethod == 'function') {
errors.forEach(loggingMethod);
}
return errors;
}
module.exports.express = {
app: function (conf, onLoaded) {
......@@ -170,73 +240,15 @@ module.exports.express = {
var currency = conf.currency;
// Checking configuration
privateKey = openpgp.key.readArmored(conf.pgpkey).keys[0];
if (conf.pgppasswd == null) {
conf.pgppasswd = "";
}
if (!privateKey) {
onLoaded('A private key for this node is mandatory. Relaunch with --pgpkey <pathToKey>.');
var confErrors = module.exports.checkConf(conf);
if (confErrors.length > 0) {
onLoaded(confErrors[0]);
return;
}
try {
if(!privateKey.decrypt(conf.pgppasswd)) {
onLoaded('Wrong private key password. Relaunch with --pgppasswd <password>.');
return;
}
} catch(ex) {
onLoaded('Not a valid private key, message was: "' + ex.message + '"');
return;
}
if (!conf.currency) {
onLoaded('No currency name was given. Relaunch with --currency <currencyName> parameter.');
return;
}
if(!conf.ipv4 && !conf.ipv6){
onLoaded("No interface to listen to. Relaunch with either --ipv4 or --ipv6 parameters.");
return;
}
if(!conf.remoteipv4 && !conf.remoteipv6){
onLoaded('Either --remote4 or --remote6 must be given');
return;
}
if (!conf.remoteport) {
onLoaded('--remotep is mandatory');
return;
}
if (conf.sync.AMDaemon == "ON") {
if (!conf.sync.AMStart) {
onLoaded('--amstart is mandatory when --amdaemon is set to ON');
return;
}
if (!conf.sync.AMFreq) {
onLoaded('--amfreq is mandatory when --amdaemon is set to ON');
return;
}
if (!conf.sync.UDFreq) {
onLoaded('--udfreq is mandatory when --amdaemon is set to ON');
return;
}
if (!conf.sync.UD0) {
onLoaded('--ud0 is mandatory when --amdaemon is set to ON');
return;
}
if (!conf.sync.UDPercent) {
onLoaded('--udpercent is mandatory when --amdaemon is set to ON');
return;
}
if (!conf.sync.Consensus) {
onLoaded('--consensus is mandatory when --amdaemon is set to ON');
return;
}
if (!conf.sync.MSExpires) {
onLoaded('--msvalidity is mandatory when --amdaemon is set to ON');
return;
}
if (!conf.sync.VTExpires) {
onLoaded('--vtvalidity is mandatory when --amdaemon is set to ON');
return;
}
}
// Private key extraction
privateKey = openpgp.key.readArmored(conf.pgpkey).keys[0];
privateKey.decrypt(conf.pgppasswd);
// all environments
app.set('conf', conf);
......@@ -351,6 +363,7 @@ module.exports.express = {
logger.info('Connecting on interface %s...', conf.ipv6);
http.createServer(app).listen(conf.port, conf.ipv6, function(){
logger.info('uCoin server listening on ' + conf.ipv6 + ' port ' + conf.port);
next();
});
}
else next();
......
This diff is collapsed.
#!/usr/bin/env node
var server = require('../app/lib/server');
var jpgp = require('../app/lib/jpgp');
var wizard = require('../app/lib/wizard');
var fs = require('fs');
var os = require('os');
var async = require('async');
var _ = require('underscore');
var program = require('commander');
var mongoose = require('mongoose');
var moment = require('moment');
var inquirer = require('inquirer');
var openpgp = require('openpgp');
var logger = require('../app/lib/logger')('ucoind');
var service = require('../app/service');
......@@ -43,6 +47,41 @@ program
.option('--vtvalidity <timestamp>', 'Duration of a valid voter, in seconds', parseInt)
;
program
.command('wizard [step]')
.description('Launch the configuration Wizard')
.action(connect(function (step, conf) {
var wiz = wizard();
var task = {
'currency': wiz.configCurrency,
'network': wiz.configNetwork,
'key': wiz.configKey,
'autovote': wiz.configAutovote
};
var wizDo = task[step] || wiz.configAll;
async.waterfall([
function (next){
wizDo(conf, next);
},
function (next){
conf.save(function (err) {
!err && logger.debug("Configuration saved.");
next(err);
});
},
function (next) {
server.checkConf(conf, function (err) {
logger.warn(err);
});
next();
}
], function (err, result) {
err && logger.error(err);
server.database.disconnect();
process.exit();
});
}));
program
.command('sync [host] [port]')
.description('Tries to synchronise data with remote uCoin node')
......@@ -129,6 +168,18 @@ function handleKey (conf, key, isManaged, message) {
});
}
program
.command('check-config')
.description('Checks the node\'s configuration')
.action(connect(function (conf) {
server.checkConf(conf, function (err) {
logger.warn(err);
});
server.database.disconnect();
process.exit();
return;
}));
program
.command('config')
.description('Register configuration in database')
......@@ -246,10 +297,10 @@ function overrideConf(conf) {
conf.port = cli.server.port || conf.port;
conf.pgpkey = cli.server.pgp.key || conf.pgpkey;
conf.pgppasswd = cli.server.pgp.password != undefined ? cli.server.pgp.password : conf.pgppasswd;
conf.remotehost = cli.server.remote.host != undefined ? cli.server.remote.host : (conf.remotehost || conf.host);
conf.remoteipv4 = cli.server.remote.ipv4 != undefined ? cli.server.remote.ipv4 : (conf.remoteipv4 || conf.ipv4);
conf.remoteipv6 = cli.server.remote.ipv6 != undefined ? cli.server.remote.ipv6 : (conf.remoteipv6 || conf.ipv6);
conf.remoteport = cli.server.remote.port != undefined ? cli.server.remote.port : (conf.remoteport || conf.port);
conf.remotehost = cli.server.remote.host != undefined ? cli.server.remote.host : conf.remotehost;
conf.remoteipv4 = cli.server.remote.ipv4 != undefined ? cli.server.remote.ipv4 : conf.remoteipv4;
conf.remoteipv6 = cli.server.remote.ipv6 != undefined ? cli.server.remote.ipv6 : conf.remoteipv6;
conf.remoteport = cli.server.remote.port != undefined ? cli.server.remote.port : conf.remoteport;
conf.kmanagement = cli.policy.keys || conf.kmanagement;
conf.kaccept = cli.policy.pubkeys || conf.kaccept;
conf.sync = {
......
# Manual configuration
To add mnually configuration parameters to uCoin, use `config` command:
```bash
$ ucoind config
```
## Currency
First of all, tell uCoin which currency to be used through command:
```bash
$ ucoind config --currency mycurrency
```
Replace `mycurrency` by the name of the currency you want to manage.
> This is **crucial** data. Be careful on the case and **do not change it** thereafter otherwise your node will have incoherent data & behaviors.
## Network parameters
By default, ucoin runs on port 8033. You may change it using the --port parameter:
```bash
$ ucoind config --port 80
```
(may require root access to launch on port 80)
It is also possible to specify the IPv4 interface:
```bash
$ ucoind config -p 8888 --ipv4 127.0.0.1
```
Or IPv6 interface:
```bash
$ ucoind config -p 8888 --ipv6 ::1
```
Or both:
```bash
$ ucoind config -p 8888 --ipv4 127.0.0.1 --ipv6 ::1
```
Launching uCoin (when completely configured) will results:
```bash
$ ucoind start
uCoin server listening on 127.0.0.1 port 8888
uCoin server listening on ::1 port 8888
```
Note too that listening to multiple interfaces doesn't imply mutiple program instances: only *one* is running on multiple interfaces.
## Remote parameters
### Peering informations
uCoin protocol uses peering mecanisms, hence needs any ucoin node to be reachable through the network.
As the server may be behind a reverse proxy, or because hosts may change of address, remote informations are likely to be different from listening host and port parameters. ucoin software defines 4 remote parameters you need to precise for your ucoin instance to be working:
* `--remoteh`
* `--remote4`
* `--remote6`
* `--remotep`
You must define at least `--remote4` and `--remotep` not to have any error. Here is an example:
```bash
$ ucoind config --remoteh "some.remote.url" --remotep "8844" --remote4 "11.11.11.11" --remote6 "::1"
```
Note that this is not required and may be removed in the future, as uCoin protocol already include peering mecanisms giving network informations.
### Authentication
uCoin protocol requires your responses to be signed in order to be interpreted. Such a feature is very important to authenticate nodes' messages. To use this feature, just configure uCoin using `--pgpkey` parameter:
```bash
$ ucoind config --pgpkey /path/to/private/key
```
Eventually, you might need to give a password, otherwise uCoin will crash:
```bash
$ ucoind config --pgppasswd "ultr[A]!%HiGhly-s3cuR3-p4ssw0d"
```
Resulting in:
```bash
$ ucoind start
Signed requests with PGP: enabled.
uCoin server listening on 127.0.0.1 port 8888
uCoin server listening on ::1 port 8888
```
\ No newline at end of file
......@@ -40,7 +40,8 @@
"vucoin": "~0.17.0",
"request": "~2.31.0",
"log4js": "~0.6.9",
"moment": "~2.6.0"
"moment": "~2.6.0",
"inquirer": "~0.5.0"
},
"devDependencies": {
"mocha": "",
......
......@@ -97,117 +97,77 @@ $ sudo npm install ./ucoin -g
All uCoin configuration is stored in its database, i.e. MongoDB.
To add configuration parameters to uCoin, use `config` command:
To start configuring your node, use following command:
```bash
$ ucoind config
ucoind wizard
```
The default database name is "ucoin_default". Thus, when using above command, the targeted database is "ucoin_default".
To deal with another database, just add `--mdb` parameter:
This will start a command prompt asking for parameters value & validate all of them at the end. Thus, you won't forget one:
```bash
$ ucoind --mdb mycurrency config
$ ucoind wizard
[?] Currency name: beta_brousouf
[?] IPv4 interface: wlan1 192.168.1.14
[?] IPv6 interface: wlan1 2a01:e35:8a37:f2b0:dd48:5620:5d3c:ce2c
[?] Port: 8080
[?] Remote IPv4 88.163.127.43
[?] Remote IPv6 None
[?] Remote port: 9101
[?] Private key: cgeek (ubot1;udid2;c;MOREAU;CEDRIC;1988-04-29;e+47.47-000.56;0) <cgeek@yopmail.com>
[?] Key's passphrase: ************************
[?] Autovoting: Yes
[?] Amendment start: 1398895200
[?] Amendment frequency: 86400
[?] Dividend frequency: 172800
[?] Consensus %required: 0.67
[?] Initial dividend: 3
[?] Universal Dividend %growth: 0.007376575
[?] Membership validity duration: 15778800
[?] Voting request validity duration: 2629800
[2014-05-19 17:29:21.139] [DEBUG] ucoind - Configuration saved.
```
This will alter `mycurrency` database *only*.
Any parameter given to this command will be stored in the database.
### Currency
### Target only few wizard's steps
First of all, tell uCoin which currency to be used through command:
Wizard is composed of 4 steps: `currency`, `network`, `key`, `autovote`. By adding one of those words to `wizard` command, you will only do the attached steps:
```bash
$ ucoind config --currency mycurrency
$ ucoind wizard network
[?] IPv4 interface: wlan1 192.168.1.14
[?] IPv6 interface: wlan1 2a01:e35:8a37:f2b0:dd48:5620:5d3c:ce2c
[?] Port: 8080
[?] Remote IPv4 88.163.127.43
[?] Remote IPv6 None
[?] Remote port: 9101
[2014-05-19 17:32:46.799] [DEBUG] ucoind - Configuration saved.
```
Replace `mycurrency` by the name of the currency you want to manage.
> This is **crucial** data. Be careful on the case and **do not change it** thereafter otherwise your node will have incoherent data & behaviors.
### Network parameters
By default, ucoin runs on port 8033. You may change it using the --port parameter:
```bash
$ ucoind config --port 80
```
(may require root access to launch on port 80)
It is also possible to specify the IPv4 interface:
```bash
$ ucoind config -p 8888 --ipv4 127.0.0.1
```
Or IPv6 interface:
```bash
$ ucoind config -p 8888 --ipv6 ::1
```
Or both:
```bash
$ ucoind config -p 8888 --ipv4 127.0.0.1 --ipv6 ::1
```
### Launching the node
Launching uCoin (when completely configured) will results:
Finally, you just need to use `start` command to launch the node:
```bash
$ ucoind start
uCoin server listening on 127.0.0.1 port 8888
uCoin server listening on ::1 port 8888
```
Note too that listening to multiple interfaces doesn't imply mutiple program instances: only *one* is running on multiple interfaces.
### Remote parameters
#### Peering informations
uCoin protocol uses peering mecanisms, hence needs any ucoin node to be reachable through the network.
As the server may be behind a reverse proxy, or because hosts may change of address, remote informations are likely to be different from listening host and port parameters. ucoin software defines 4 remote parameters you need to precise for your ucoin instance to be working:
* `--remoteh`
* `--remote4`
* `--remote6`
* `--remotep`
You must define at least `--remote4` and `--remotep` not to have any error. Here is an example:
```bash
$ ucoind config --remoteh "some.remote.url" --remotep "8844" --remote4 "11.11.11.11" --remote6 "::1"
[2014-05-19 17:42:33.494] [DEBUG] service - Loaded service: Contract
...
[2014-05-19 17:42:33.613] [DEBUG] ucoind - Server ready!
```
Note that this is not required and may be removed in the future, as uCoin protocol already include peering mecanisms giving network informations.
#### Authentication
uCoin protocol requires your responses to be signed in order to be interpreted. Such a feature is very important to authenticate nodes' messages. To use this feature, just configure uCoin using `--pgpkey` parameter:
### Change of database
```bash
$ ucoind config --pgpkey /path/to/private/key
```
The default database name is "ucoin_default". Thus, when using any command, the targeted database is "ucoin_default".
Eventually, you might need to give a password, otherwise uCoin will crash:
To deal with another database, just add `--mdb` parameter:
```bash
$ ucoind config --pgppasswd "ultr[A]!%HiGhly-s3cuR3-p4ssw0d"
$ ucoind --mdb mycurrency wizard
```
This will launch wizard on `mycurrency` database *only*.
Resulting in:
### Manual configuration
```bash
$ ucoind start
Signed requests with PGP: enabled.
uCoin server listening on 127.0.0.1 port 8888
uCoin server listening on ::1 port 8888
```
You might also want to do your configuration manually, using CLI options. [Here is a document](./doc/manual-config.md) on how to achieve this.
### Initial data
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment