http: have json rpc use server api key.
This commit is contained in:
parent
18ddcc49c5
commit
bf63691fd2
@ -54,5 +54,4 @@ listen: true
|
|||||||
# http-host: 0.0.0.0
|
# http-host: 0.0.0.0
|
||||||
# api-key: 74b4147957813b62cc8987f2b711ddb31f8cb46dcbf71502033da66053c8780a
|
# api-key: 74b4147957813b62cc8987f2b711ddb31f8cb46dcbf71502033da66053c8780a
|
||||||
# wallet-auth: true
|
# wallet-auth: true
|
||||||
# rpc-user: admin
|
# no-auth: false
|
||||||
# rpc-password: bcoin
|
|
||||||
|
|||||||
@ -167,8 +167,7 @@ config.parseData = function parseData(data) {
|
|||||||
options.httpHost = str(data.httphost);
|
options.httpHost = str(data.httphost);
|
||||||
options.apiKey = str(data.apikey);
|
options.apiKey = str(data.apikey);
|
||||||
options.walletAuth = bool(data.walletauth);
|
options.walletAuth = bool(data.walletauth);
|
||||||
options.rpcUser = str(data.rpcuser);
|
options.noAuth = bool(data.noauth);
|
||||||
options.rpcPassword = str(data.rpcpassword);
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -145,8 +145,7 @@ function Fullnode(options) {
|
|||||||
host: this.options.httpHost || '0.0.0.0',
|
host: this.options.httpHost || '0.0.0.0',
|
||||||
apiKey: this.options.apiKey,
|
apiKey: this.options.apiKey,
|
||||||
walletAuth: this.options.walletAuth,
|
walletAuth: this.options.walletAuth,
|
||||||
rpcUser: this.options.rpcUser,
|
noAuth: this.options.noAuth
|
||||||
rpcPassword: this.options.rpcPassword
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -326,7 +326,7 @@ RPC.prototype.disconnectnode = function disconnectnode(args, callback) {
|
|||||||
var node, peer;
|
var node, peer;
|
||||||
|
|
||||||
if (args.help || args.length !== 1)
|
if (args.help || args.length !== 1)
|
||||||
return callback(new Error('disconnectnode "node" '));
|
return callback(new Error('disconnectnode "node"'));
|
||||||
|
|
||||||
node = String(args[0]);
|
node = String(args[0]);
|
||||||
node = IP.normalize(node);
|
node = IP.normalize(node);
|
||||||
@ -475,6 +475,7 @@ RPC.prototype.clearbanned = function clearbanned(args, callback) {
|
|||||||
if (args.help || args.length !== 0)
|
if (args.help || args.length !== 0)
|
||||||
return callback(new Error('clearbanned'));
|
return callback(new Error('clearbanned'));
|
||||||
|
|
||||||
|
this.pool.peers.ignored = {};
|
||||||
this.pool.peers.misbehaving = {};
|
this.pool.peers.misbehaving = {};
|
||||||
|
|
||||||
callback(null, null);
|
callback(null, null);
|
||||||
@ -488,13 +489,13 @@ RPC.prototype._deployment = function _deployment(id, version, status) {
|
|||||||
status: status,
|
status: status,
|
||||||
found: status ? this.network.block.majorityWindow : 0,
|
found: status ? this.network.block.majorityWindow : 0,
|
||||||
required: this.network.block.majorityEnforceUpgrade,
|
required: this.network.block.majorityEnforceUpgrade,
|
||||||
window: this.network.block.majorityWindow,
|
window: this.network.block.majorityWindow
|
||||||
},
|
},
|
||||||
reject: {
|
reject: {
|
||||||
status: status,
|
status: status,
|
||||||
found: status ? this.network.block.majorityWindow : 0,
|
found: status ? this.network.block.majorityWindow : 0,
|
||||||
required: this.network.block.majorityRejectOutdated,
|
required: this.network.block.majorityRejectOutdated,
|
||||||
winodw: this.network.block.majorityWindow,
|
window: this.network.block.majorityWindow
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -49,16 +49,8 @@ function HTTPServer(options) {
|
|||||||
this.logger = options.logger || this.node.logger;
|
this.logger = options.logger || this.node.logger;
|
||||||
this.loaded = false;
|
this.loaded = false;
|
||||||
this.apiKey = options.apiKey;
|
this.apiKey = options.apiKey;
|
||||||
this.rpcUser = options.rpcUser;
|
|
||||||
this.rpcPassword = options.rpcPassword;
|
|
||||||
this.rpc = null;
|
this.rpc = null;
|
||||||
|
|
||||||
if (!this.rpcUser)
|
|
||||||
this.rpcUser = 'admin';
|
|
||||||
|
|
||||||
if (!this.rpcPassword)
|
|
||||||
this.rpcPassword = bcoin.ec.random(20).toString('hex');
|
|
||||||
|
|
||||||
if (this.apiKey) {
|
if (this.apiKey) {
|
||||||
if (typeof this.apiKey === 'string') {
|
if (typeof this.apiKey === 'string') {
|
||||||
assert(utils.isHex(this.apiKey), 'API key must be a hex string.');
|
assert(utils.isHex(this.apiKey), 'API key must be a hex string.');
|
||||||
@ -66,8 +58,13 @@ function HTTPServer(options) {
|
|||||||
}
|
}
|
||||||
assert(Buffer.isBuffer(this.apiKey));
|
assert(Buffer.isBuffer(this.apiKey));
|
||||||
assert(this.apiKey.length === 32, 'API key must be 32 bytes.');
|
assert(this.apiKey.length === 32, 'API key must be 32 bytes.');
|
||||||
|
} else {
|
||||||
|
this.apiKey = bcoin.ec.random(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.noAuth)
|
||||||
|
this.apiKey = null;
|
||||||
|
|
||||||
options.sockets = true;
|
options.sockets = true;
|
||||||
|
|
||||||
this.server = new HTTPBase(options);
|
this.server = new HTTPBase(options);
|
||||||
@ -140,6 +137,11 @@ HTTPServer.prototype._init = function _init() {
|
|||||||
|
|
||||||
if (req.method === 'POST'
|
if (req.method === 'POST'
|
||||||
&& req.pathname === '/') {
|
&& req.pathname === '/') {
|
||||||
|
if (self.apiKey) {
|
||||||
|
assert(utils.isHex(req.password), 'API key must be a hex string.');
|
||||||
|
assert(req.password.length === 64, 'API key must be 32 bytes.');
|
||||||
|
req.password = new Buffer(req.password, 'hex');
|
||||||
|
}
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,38 +301,40 @@ HTTPServer.prototype._init = function _init() {
|
|||||||
|
|
||||||
// JSON RPC
|
// JSON RPC
|
||||||
this.post('/', function(req, res, next, send) {
|
this.post('/', function(req, res, next, send) {
|
||||||
if (req.body.method && req.body.params) {
|
if (!(req.body.method && req.body.params))
|
||||||
if (self.rpcUser) {
|
return next(new Error('Method not found.'));
|
||||||
if (!textCmp(req.username, self.rpcUser)
|
|
||||||
|| !textCmp(req.password, self.rpcPassword)) {
|
|
||||||
res.setHeader('WWW-Authenticate', 'Basic realm="rpc"');
|
|
||||||
send(401, { error: 'Bad auth.' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!self.rpc) {
|
if (self.apiKey) {
|
||||||
RPC = require('./rpc');
|
if (!utils.ccmp(req.password, self.apiKey)) {
|
||||||
self.rpc = new RPC(self.node);
|
res.setHeader('WWW-Authenticate', 'Basic realm="rpc"');
|
||||||
}
|
send(401, {
|
||||||
|
result: null,
|
||||||
return self.rpc.execute(req.body, function(err, json) {
|
error: 'Bad auth.',
|
||||||
if (err) {
|
|
||||||
return send(400, {
|
|
||||||
result: null,
|
|
||||||
error: err.message,
|
|
||||||
id: req.body.id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
send(200, {
|
|
||||||
result: json,
|
|
||||||
error: null,
|
|
||||||
id: req.body.id
|
id: req.body.id
|
||||||
});
|
});
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next(new Error('Method not found.'));
|
if (!self.rpc) {
|
||||||
|
RPC = require('./rpc');
|
||||||
|
self.rpc = new RPC(self.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.rpc.execute(req.body, function(err, json) {
|
||||||
|
if (err) {
|
||||||
|
return send(400, {
|
||||||
|
result: null,
|
||||||
|
error: err.message,
|
||||||
|
id: req.body.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
send(200, {
|
||||||
|
result: json,
|
||||||
|
error: null,
|
||||||
|
id: req.body.id
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.get('/', function(req, res, next, send) {
|
this.get('/', function(req, res, next, send) {
|
||||||
@ -1017,7 +1021,11 @@ HTTPServer.prototype._initIO = function _initIO() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
HTTPServer.prototype.open = function open(callback) {
|
HTTPServer.prototype.open = function open(callback) {
|
||||||
this.logger.info('RPC credentials: %s:%s', this.rpcUser, this.rpcPassword);
|
if (this.apiKey)
|
||||||
|
this.logger.info('API key: %s', this.apiKey.toString('hex'));
|
||||||
|
else
|
||||||
|
this.logger.warning('WARNING: Your http server is open to the world.');
|
||||||
|
|
||||||
this.server.open(callback);
|
this.server.open(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -84,8 +84,7 @@ function SPVNode(options) {
|
|||||||
host: this.options.httpHost || '0.0.0.0',
|
host: this.options.httpHost || '0.0.0.0',
|
||||||
apiKey: this.options.apiKey,
|
apiKey: this.options.apiKey,
|
||||||
walletAuth: this.options.walletAuth,
|
walletAuth: this.options.walletAuth,
|
||||||
rpcUser: this.options.rpcUser,
|
noAuth: this.options.noAuth
|
||||||
rpcPassword: this.options.rpcPassword
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user