XO-Server can now drop priviledges.
This commit is contained in:
parent
ad5e68091f
commit
774b4051bc
@ -1,5 +1,35 @@
|
|||||||
# Note: Relative paths will be resolved from XO-Server's directory.
|
# Note: Relative paths will be resolved from XO-Server's directory.
|
||||||
|
|
||||||
|
#=====================================================================
|
||||||
|
|
||||||
|
# It may be necessary to run XO-Server as a priviledged user (e.g.
|
||||||
|
# `root`) for instance to allow the HTTP server to listen on a
|
||||||
|
# [priviledged ports](http://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html).
|
||||||
|
#
|
||||||
|
# To avoid security issues, XO-Server can drop its priviledges by
|
||||||
|
# changing the user and the group is running with.
|
||||||
|
#
|
||||||
|
# Note: XO-Server will change them just after reading the
|
||||||
|
# configuration.
|
||||||
|
|
||||||
|
# User to run XO-Server as.
|
||||||
|
#
|
||||||
|
# Note: The user can be specified using either its name or its numeric
|
||||||
|
# identifier.
|
||||||
|
#
|
||||||
|
# Default: undefined
|
||||||
|
#user: 'nobody'
|
||||||
|
|
||||||
|
# Group to run XO-Server as.
|
||||||
|
#
|
||||||
|
# Note: The group can be specified using either its name or its
|
||||||
|
# numeric identifier.
|
||||||
|
#
|
||||||
|
# Default: undefined
|
||||||
|
#group: 'nogroup'
|
||||||
|
|
||||||
|
#=====================================================================
|
||||||
|
|
||||||
# Configuration of the embedded HTTP server.
|
# Configuration of the embedded HTTP server.
|
||||||
http:
|
http:
|
||||||
|
|
||||||
@ -52,6 +82,8 @@ http:
|
|||||||
mounts:
|
mounts:
|
||||||
#'/': '/path/to/xo-web/dist/'
|
#'/': '/path/to/xo-web/dist/'
|
||||||
|
|
||||||
|
#=====================================================================
|
||||||
|
|
||||||
# Connection to the Redis server.
|
# Connection to the Redis server.
|
||||||
redis:
|
redis:
|
||||||
# Syntax: tcp://[db[:password]@]hostname[:port]
|
# Syntax: tcp://[db[:password]@]hostname[:port]
|
||||||
|
@ -21,7 +21,8 @@ $sleep = (ms) ->
|
|||||||
setTimeout (-> fiber.run()), ms
|
setTimeout (-> fiber.run()), ms
|
||||||
$fiber.yield()
|
$fiber.yield()
|
||||||
|
|
||||||
# Makes an asynchrouneous function synchrouneous (in a fiber).
|
# Makes an Node like asynchrouneous function synchrouneous (in a
|
||||||
|
# fiber).
|
||||||
$synchronize = (fn, ctx) ->
|
$synchronize = (fn, ctx) ->
|
||||||
fn = ctx[fn] if $_.isString fn
|
fn = ctx[fn] if $_.isString fn
|
||||||
|
|
||||||
@ -33,22 +34,46 @@ $synchronize = (fn, ctx) ->
|
|||||||
fiber.throwInto error
|
fiber.throwInto error
|
||||||
else
|
else
|
||||||
fiber.run result
|
fiber.run result
|
||||||
result = fn.apply ctx, args
|
fn.apply ctx, args
|
||||||
|
|
||||||
# A promise can only be detected once the function has been
|
|
||||||
# called.
|
|
||||||
if $isPromise result
|
|
||||||
result.then(
|
|
||||||
(result) -> fiber.run result
|
|
||||||
(error) -> fiber.throwInto error
|
|
||||||
)
|
|
||||||
|
|
||||||
$fiber.yield()
|
$fiber.yield()
|
||||||
|
|
||||||
|
# Waits for an event.
|
||||||
|
#
|
||||||
|
# Note: if the *error* event is emitted, this function will throw.
|
||||||
|
$waitEvent = (emitter, event) ->
|
||||||
|
fiber = $fiber.current
|
||||||
|
|
||||||
|
errorHandler = null
|
||||||
|
handler = (args...) ->
|
||||||
|
emitter.removeListener 'error', errorHandler
|
||||||
|
fiber.run args
|
||||||
|
errorHandler = (error) ->
|
||||||
|
emitter.removeListener event, handler
|
||||||
|
fiber.throwInto error
|
||||||
|
|
||||||
|
emitter.once event, handler
|
||||||
|
emitter.once 'error', errorHandler
|
||||||
|
|
||||||
|
$fiber.yield()
|
||||||
|
|
||||||
|
# Waits for a promise to be fulfilled or broken.
|
||||||
|
$waitPromise = (promise) ->
|
||||||
|
fiber = $fiber.current
|
||||||
|
|
||||||
|
promise.then(
|
||||||
|
(result) -> fiber.run result
|
||||||
|
(error) -> fiber.throwInto error
|
||||||
|
)
|
||||||
|
|
||||||
|
$fiber.yield()
|
||||||
|
|
||||||
#=====================================================================
|
#=====================================================================
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
$fiberize
|
$fiberize
|
||||||
$sleep
|
$sleep
|
||||||
$synchronize
|
$synchronize
|
||||||
|
$waitEvent
|
||||||
|
$waitPromise
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ $Session = require './session'
|
|||||||
$XO = require './xo'
|
$XO = require './xo'
|
||||||
|
|
||||||
# Helpers for dealing with fibers.
|
# Helpers for dealing with fibers.
|
||||||
{$fiberize, $synchronize} = require './fibers-utils'
|
{$fiberize, $synchronize, $waitEvent} = require './fibers-utils'
|
||||||
|
|
||||||
# HTTP/HTTPS server which can listen on multiple ports.
|
# HTTP/HTTPS server which can listen on multiple ports.
|
||||||
$WebServer = require './web-server'
|
$WebServer = require './web-server'
|
||||||
@ -112,6 +112,20 @@ do $fiberize ->
|
|||||||
if $nconf.get entry
|
if $nconf.get entry
|
||||||
console.warn "[Warn] `#{entry}` configuration is deprecated."
|
console.warn "[Warn] `#{entry}` configuration is deprecated."
|
||||||
|
|
||||||
|
# Creates the web server according to the configuration.
|
||||||
|
webServer = new $WebServer()
|
||||||
|
webServer.listen options for options in $nconf.get 'http:listen'
|
||||||
|
|
||||||
|
# Waits for the web server to start listening to drop priviledges.
|
||||||
|
$waitEvent webServer, 'listening'
|
||||||
|
try
|
||||||
|
if (group = $nconf.get 'group')?
|
||||||
|
process.setgid group
|
||||||
|
if (user = $nconf.get 'user')?
|
||||||
|
process.setuid user
|
||||||
|
catch error
|
||||||
|
console.warn "[WARN] Failed to change the user or group: #{error.message}"
|
||||||
|
|
||||||
# Creates the main object which will connects to Xen servers and
|
# Creates the main object which will connects to Xen servers and
|
||||||
# manages all the models.
|
# manages all the models.
|
||||||
xo = new $XO()
|
xo = new $XO()
|
||||||
@ -123,10 +137,6 @@ do $fiberize ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Creates the web server according to the configuration.
|
|
||||||
webServer = new $WebServer()
|
|
||||||
webServer.listen options for options in $nconf.get 'http:listen'
|
|
||||||
|
|
||||||
# Static file serving (e.g. for XO-Web).
|
# Static file serving (e.g. for XO-Web).
|
||||||
connect = $connect()
|
connect = $connect()
|
||||||
for urlPath, filePaths of $nconf.get 'http:mounts'
|
for urlPath, filePaths of $nconf.get 'http:mounts'
|
||||||
|
@ -42,6 +42,7 @@ class $WebServer extends $EventEmitter
|
|||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
@_servers = []
|
@_servers = []
|
||||||
|
@_notYetListening = 0
|
||||||
|
|
||||||
close: ->
|
close: ->
|
||||||
server.close() for server in @_servers
|
server.close() for server in @_servers
|
||||||
@ -65,8 +66,10 @@ class $WebServer extends $EventEmitter
|
|||||||
else
|
else
|
||||||
server.listen port, host
|
server.listen port, host
|
||||||
|
|
||||||
|
++@_notYetListening
|
||||||
|
|
||||||
# Helpful message.
|
# Helpful message.
|
||||||
server.once 'listening', ->
|
server.once 'listening', =>
|
||||||
address = server.address()
|
address = server.address()
|
||||||
if $_.isObject address
|
if $_.isObject address
|
||||||
{address, port} = address
|
{address, port} = address
|
||||||
@ -74,6 +77,10 @@ class $WebServer extends $EventEmitter
|
|||||||
|
|
||||||
console.log "WebServer listening on #{address}"
|
console.log "WebServer listening on #{address}"
|
||||||
|
|
||||||
|
# If the web server is listening on all addresses, fire the
|
||||||
|
# `listening` event.
|
||||||
|
@emit 'listening' unless --@_notYetListening
|
||||||
|
|
||||||
# Forwards events to this object.
|
# Forwards events to this object.
|
||||||
$_.each $events, (event) =>
|
$_.each $events, (event) =>
|
||||||
server.on event, (args...) => @emit event, args...
|
server.on event, (args...) => @emit event, args...
|
||||||
|
@ -28,7 +28,7 @@ $Model = require './model'
|
|||||||
$XAPI = require './xapi'
|
$XAPI = require './xapi'
|
||||||
|
|
||||||
# Helpers for dealing with fibers.
|
# Helpers for dealing with fibers.
|
||||||
{$fiberize, $synchronize} = require './fibers-utils'
|
{$fiberize, $synchronize, $waitPromise} = require './fibers-utils'
|
||||||
|
|
||||||
#=====================================================================
|
#=====================================================================
|
||||||
|
|
||||||
@ -266,8 +266,7 @@ class $XO
|
|||||||
throw error unless error[0] is 'SESSION_NOT_REGISTERED'
|
throw error unless error[0] is 'SESSION_NOT_REGISTERED'
|
||||||
|
|
||||||
# Connects to existing servers.
|
# Connects to existing servers.
|
||||||
getServers = $synchronize 'get', @servers
|
connect server for server in $waitPromise @servers.get()
|
||||||
connect server for server in getServers()
|
|
||||||
|
|
||||||
# Automatically connects to new servers.
|
# Automatically connects to new servers.
|
||||||
@servers.on 'add', (servers) ->
|
@servers.on 'add', (servers) ->
|
||||||
|
Loading…
Reference in New Issue
Block a user