summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-04-30 11:05:37 +0800
committerruki <[email protected]>2022-04-30 11:05:37 +0800
commit52e0611c6c6bc51fa235db770bec1583bd6a32fa (patch)
tree880d7d0e47ee9314d52555f9d924b3eba7f700c0
parentffd4cc4ac71259be018ebba4a5176bb40adfc7cc (diff)
verify remote server user
-rw-r--r--xmake/modules/private/service/client.lua12
-rw-r--r--xmake/modules/private/service/config.lua13
-rw-r--r--xmake/modules/private/service/message.lua39
-rw-r--r--xmake/modules/private/service/remote_build/client.lua42
-rw-r--r--xmake/modules/private/service/remote_build/server.lua11
-rw-r--r--xmake/modules/private/service/server.lua50
6 files changed, 147 insertions, 20 deletions
diff --git a/xmake/modules/private/service/client.lua b/xmake/modules/private/service/client.lua
index 4b0168981..4392ca19b 100644
--- a/xmake/modules/private/service/client.lua
+++ b/xmake/modules/private/service/client.lua
@@ -43,7 +43,17 @@ function client:address_set(address)
assert(self._ADDR and self._PORT, "invalid client address!")
end
--- get the address address
+-- get user name
+function client:user()
+ return self._USER
+end
+
+-- set user name
+function client:user_set(user)
+ self._USER = user
+end
+
+-- get the ip address
function client:addr()
return self._ADDR
end
diff --git a/xmake/modules/private/service/config.lua b/xmake/modules/private/service/config.lua
index 8bb924fe1..9bdb98ad7 100644
--- a/xmake/modules/private/service/config.lua
+++ b/xmake/modules/private/service/config.lua
@@ -31,10 +31,19 @@ function _generate_configfile()
remote_build = {
server = {
listen = "0.0.0.0:9691",
- workdir = path.join(servicedir, "remote_build")
+ workdir = path.join(servicedir, "remote_build"),
+ users = {
+ root = {
+ pass = "123456",
+ known_hosts = {
+ "127.0.0.1"
+ }
+ }
+ }
},
client = {
- connect = "127.0.0.1:9691"
+ connect = "127.0.0.1:9691",
+ user = "root"
}
}
}
diff --git a/xmake/modules/private/service/message.lua b/xmake/modules/private/service/message.lua
index f0ff93f46..cbd7e54f7 100644
--- a/xmake/modules/private/service/message.lua
+++ b/xmake/modules/private/service/message.lua
@@ -89,6 +89,11 @@ function message:is_data()
return self:code() == message.CODE_DATA
end
+-- get user authorization
+function message:auth()
+ return self:body().auth
+end
+
-- is success?
function message:success()
return self:body().status == true
@@ -133,64 +138,78 @@ function _new(body)
end
-- new connect message
-function new_connect(session_id)
+function new_connect(session_id, opt)
+ opt = opt or {}
return _new({
code = message.CODE_CONNECT,
session_id = session_id,
+ auth = opt.auth,
xmakever = xmake.version():shortstr()
})
end
-- new disconnect message
-function new_disconnect(session_id)
+function new_disconnect(session_id, opt)
+ opt = opt or {}
return _new({
code = message.CODE_DISCONNECT,
- session_id = session_id
+ session_id = session_id,
+ auth = opt.auth
})
end
-- new diff message, e.g manifest = {["src/main.c"] = {sha256 = "", mtime = ""}}
-function new_diff(session_id, manifest)
+function new_diff(session_id, manifest, opt)
+ opt = opt or {}
return _new({
code = message.CODE_DIFF,
session_id = session_id,
+ auth = opt.auth,
manifest = manifest
})
end
-- new sync message, e.g. manifest = {modified = {"src/main.c"}, inserted = {}, removed = {}}
-function new_sync(session_id, manifest)
+function new_sync(session_id, manifest, opt)
+ opt = opt or {}
return _new({
code = message.CODE_SYNC,
session_id = session_id,
+ auth = opt.auth,
manifest = manifest
})
end
-- new clean message
-function new_clean(session_id)
+function new_clean(session_id, opt)
+ opt = opt or {}
return _new({
code = message.CODE_CLEAN,
- session_id = session_id
+ session_id = session_id,
+ auth = opt.auth
})
end
-- new run command message
-function new_runcmd(session_id, program, argv)
+function new_runcmd(session_id, program, argv, opt)
+ opt = opt or {}
return _new({
code = message.CODE_RUNCMD,
session_id = session_id,
+ auth = opt.auth,
program = program,
argv = argv
})
end
-- new data message
-function new_data(session_id, size)
+function new_data(session_id, size, opt)
+ opt = opt or {}
return _new({
code = message.CODE_DATA,
size = size,
- session_id = session_id
+ session_id = session_id,
+ auth = opt.auth
})
end
diff --git a/xmake/modules/private/service/remote_build/client.lua b/xmake/modules/private/service/remote_build/client.lua
index c23b0818d..fa4bfd4bf 100644
--- a/xmake/modules/private/service/remote_build/client.lua
+++ b/xmake/modules/private/service/remote_build/client.lua
@@ -20,6 +20,7 @@
-- imports
import("core.base.bytes")
+import("core.base.base64")
import("core.base.socket")
import("core.base.option")
import("core.base.scheduler")
@@ -45,6 +46,10 @@ function remote_build_client:init()
local address = assert(config.get("remote_build.client.connect"), "config(remote_build.client.connect): not found!")
super.address_set(self, address)
+ -- init user
+ local user = config.get("remote_build.client.user")
+ super.user_set(self, user)
+
-- get project directory
local projectdir = os.projectdir()
local projectfile = os.projectfile()
@@ -76,6 +81,22 @@ function remote_build_client:connect()
print("%s: has been connected!", self)
return
end
+
+ -- we need user authorization?
+ local auth
+ if self:user() then
+
+ -- get user password
+ cprint("Please input user ${bright}%s${clear} password:", self:user())
+ io.flush()
+ local pass = (io.read() or ""):trim()
+ assert(pass ~= "", "password is empty!")
+
+ -- compute user authorization
+ auth = base64.encode(self:user() .. ":" .. pass)
+ end
+
+ -- do connect
local addr = self:addr()
local port = self:port()
local sock = assert(socket.connect(addr, port), "%s: server unreachable!", self)
@@ -85,7 +106,7 @@ function remote_build_client:connect()
print("%s: connect %s:%d ..", self, addr, port)
if sock then
local stream = socket_stream(sock)
- if stream:send_msg(message.new_connect(session_id)) and stream:flush() then
+ if stream:send_msg(message.new_connect(session_id, {auth = auth})) and stream:flush() then
local msg = stream:recv_msg()
if msg then
vprint(msg:body())
@@ -107,6 +128,7 @@ function remote_build_client:connect()
local status = self:status()
status.addr = addr
status.port = port
+ status.auth = auth
status.connected = ok
status.session_id = session_id
self:status_save()
@@ -132,7 +154,7 @@ function remote_build_client:disconnect()
print("%s: disconnect %s:%d ..", self, addr, port)
if sock then
local stream = socket_stream(sock)
- if stream:send_msg(message.new_disconnect(session_id)) and stream:flush() then
+ if stream:send_msg(message.new_disconnect(session_id, {auth = self:auth()})) and stream:flush() then
local msg = stream:recv_msg()
if msg then
vprint(msg:body())
@@ -156,6 +178,7 @@ function remote_build_client:disconnect()
-- update status
local status = self:status()
+ status.auth = nil
status.connected = not ok
self:status_save()
end
@@ -195,7 +218,7 @@ function remote_build_client:sync()
-- do sync
cprint("Uploading files with ${bright}%d${clear} bytes ..", os.filesize(archive_diff_file))
local send_ok = false
- if stream:send_msg(message.new_sync(session_id, diff_files)) and stream:flush() then
+ if stream:send_msg(message.new_sync(session_id, diff_files, {auth = self:auth()})) and stream:flush() then
if stream:send_file(archive_diff_file) and stream:flush() then
send_ok = true
end
@@ -236,7 +259,7 @@ function remote_build_client:clean()
local ok = false
print("%s: clean files in %s:%d ..", self, addr, port)
local stream = socket_stream(sock)
- if stream:send_msg(message.new_clean(session_id)) and stream:flush() then
+ if stream:send_msg(message.new_clean(session_id, {auth = self:auth()})) and stream:flush() then
local msg = stream:recv_msg()
if msg then
vprint(msg:body())
@@ -268,7 +291,7 @@ function remote_build_client:runcmd(program, argv)
local leftstr = ""
cprint("%s: run ${bright}%s${clear} in %s:%d ..", self, command, addr, port)
local stream = socket_stream(sock)
- if stream:send_msg(message.new_runcmd(session_id, program, argv)) and stream:flush() then
+ if stream:send_msg(message.new_runcmd(session_id, program, argv, {auth = self:auth()})) and stream:flush() then
local stdin_opt = {stop = false}
scheduler.co_start(self._read_stdin, self, stream, stdin_opt)
while true do
@@ -351,6 +374,11 @@ function remote_build_client:workdir()
return self._WORKDIR
end
+-- get user auth
+function remote_build_client:auth()
+ return self:status().auth
+end
+
-- get the session id, only for unique project
function remote_build_client:session_id()
return self:status().session_id or hash.uuid():split("-", {plain = true})[1]:lower()
@@ -371,7 +399,7 @@ function remote_build_client:_diff_files(stream)
local count = 0
local result, errors
cprint("Comparing ${bright}%d${clear} files ..", filecount)
- if stream:send_msg(message.new_diff(session_id, manifest)) and stream:flush() then
+ if stream:send_msg(message.new_diff(session_id, manifest, {auth = self:auth()})) and stream:flush() then
local msg = stream:recv_msg()
if msg and msg:success() then
result = msg:body().manifest
@@ -435,7 +463,7 @@ function remote_build_client:_read_stdin(stream, opt)
if line and #line > 0 then
local ok = false
local data = bytes(line)
- if stream:send_msg(message.new_data(0, data:size())) then
+ if stream:send_msg(message.new_data(0, data:size(), {auth = self:auth()})) then
if stream:send(data) and stream:flush() then
ok = true
end
diff --git a/xmake/modules/private/service/remote_build/server.lua b/xmake/modules/private/service/remote_build/server.lua
index 085dc1e42..de2b05cd0 100644
--- a/xmake/modules/private/service/remote_build/server.lua
+++ b/xmake/modules/private/service/remote_build/server.lua
@@ -41,6 +41,10 @@ function remote_build_server:init(daemon)
local address = assert(config.get("remote_build.server.listen"), "config(remote_build.server.listen): not found!")
super.address_set(self, address)
+ -- init users
+ local users = config.get("remote_build.server.users")
+ super.users_set(self, users)
+
-- init handler
super.handler_set(self, self._on_handle)
@@ -65,6 +69,13 @@ function remote_build_server:_on_handle(stream, msg)
local session_ok = try
{
function()
+ if self:need_verfiy() then
+ local ok, errors = self:verify_user(msg:auth())
+ if not ok then
+ session_errs = errors
+ return false
+ end
+ end
if msg:is_connect() then
session:open()
elseif msg:is_disconnect() then
diff --git a/xmake/modules/private/service/server.lua b/xmake/modules/private/service/server.lua
index 4a80cd98a..92ebdec82 100644
--- a/xmake/modules/private/service/server.lua
+++ b/xmake/modules/private/service/server.lua
@@ -21,6 +21,7 @@
-- imports
import("core.base.object")
import("core.base.bytes")
+import("core.base.base64")
import("core.base.socket")
import("core.base.scheduler")
import("private.service.message")
@@ -67,6 +68,55 @@ function server:port()
return self._PORT
end
+-- set users
+function server:users_set(users)
+ self._USERS = users
+end
+
+-- get the user information
+function server:user(name)
+ if name and self._USERS then
+ return self._USERS[name]
+ end
+end
+
+-- we need verify user
+function server:need_verfiy()
+ return self._USERS ~= nil
+end
+
+-- verify user
+function server:verify_user(auth)
+ if not auth then
+ return false, "client has no authorization, this remote server need user authorization!"
+ end
+
+ -- decode authorization
+ local authstr = base64.decode(auth)
+ local splitinfo = authstr:str():split(":")
+ if not splitinfo or #splitinfo ~= 2 then
+ return false, "invalid authorization!"
+ end
+
+ -- get client user and password
+ local client_user = splitinfo[1]
+ local client_pass = splitinfo[2]
+ if not client_user or not client_pass then
+ return false, "invalid user and password!"
+ end
+
+ -- get server user and password
+ local server_userinfo = self:user(client_user)
+ assert(server_userinfo, "user(%s) is unknown!", client_user)
+ local server_pass = server_userinfo.pass
+ if client_pass ~= server_pass then
+ return false, "password is incorrect!"
+ end
+
+ -- TODO check known_hosts
+ return true
+end
+
-- run main loop
function server:runloop()
assert(self._HANDLER, "no handler found!")