diff options
| author | ruki <[email protected]> | 2022-04-30 11:05:37 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-04-30 11:05:37 +0800 |
| commit | 52e0611c6c6bc51fa235db770bec1583bd6a32fa (patch) | |
| tree | 880d7d0e47ee9314d52555f9d924b3eba7f700c0 | |
| parent | ffd4cc4ac71259be018ebba4a5176bb40adfc7cc (diff) | |
verify remote server user
| -rw-r--r-- | xmake/modules/private/service/client.lua | 12 | ||||
| -rw-r--r-- | xmake/modules/private/service/config.lua | 13 | ||||
| -rw-r--r-- | xmake/modules/private/service/message.lua | 39 | ||||
| -rw-r--r-- | xmake/modules/private/service/remote_build/client.lua | 42 | ||||
| -rw-r--r-- | xmake/modules/private/service/remote_build/server.lua | 11 | ||||
| -rw-r--r-- | xmake/modules/private/service/server.lua | 50 |
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!") |
