From 0d1c3a64d17eb41b55cd4b8ff31499f612efe88a Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Sun, 13 Jul 2014 21:02:23 +0800 Subject: [PATCH] bugfix --- examples/login/client.lua | 10 ++++++-- examples/login/logind.lua | 44 ++++++++++++++++++++++++----------- examples/login/msggate.lua | 4 ++-- lualib-src/lua-crypt.c | 2 +- lualib/gamefw/loginserver.lua | 38 ++++++++++++++++-------------- 5 files changed, 63 insertions(+), 35 deletions(-) diff --git a/examples/login/client.lua b/examples/login/client.lua index 85a8ab36..7a72a036 100644 --- a/examples/login/client.lua +++ b/examples/login/client.lua @@ -14,7 +14,6 @@ package.cpath = "luaclib/?.so" ]] local socket = require "clientsocket" -local cjson = require "cjson" local crypt = require "crypt" local last @@ -61,7 +60,14 @@ local token = { pass = "password", } -local etoken = crypt.desencode(secret, cjson.encode(token)) +local function encode_token(token) + return string.format("%s@%s:%s", + crypt.base64encode(token.user), + crypt.base64encode(token.server), + crypt.base64encode(token.pass)) +end + +local etoken = crypt.desencode(secret, encode_token(token)) local b = crypt.base64encode(etoken) socket.writeline(fd, crypt.base64encode(etoken)) diff --git a/examples/login/logind.lua b/examples/login/logind.lua index 2ff79c48..b28c6721 100644 --- a/examples/login/logind.lua +++ b/examples/login/logind.lua @@ -1,5 +1,4 @@ local login = require "gamefw.loginserver" -local json = require "cjson" local crypt = require "crypt" local skynet = require "skynet" @@ -12,32 +11,51 @@ local server = { local server_list = {} local user_online = {} +local server_mt = {} +server_mt.__index = server_mt + +function server_mt:kick(uid) + skynet.call(self.address, "lua", "kick", self.name, uid) +end + +function server_mt:login(uid, secret) + skynet.call(self.address, "lua", "login", self.name, uid, secret) +end + function server.auth_handler(token) - token = json.decode(token) - assert(token.user) - assert(token.pass == "password") - return token.server, token.user + -- the token is base64(user)@base64(server):base64(password) + local user, server, password = token:match("([^@]+)@([^:]+):(.+)") + user = crypt.base64decode(user) + server = crypt.base64decode(server) + password = crypt.base64decode(password) + assert(password == "password") + return server, user end function server.login_handler(server, uid, secret) print(string.format("%s@%s is login, secret is %s", uid, server, crypt.hexencode(secret))) local u = user_online[uid] if u then - local gameserver = server_list[u.server] - skynet.call(gameserver, "lua", "kick", server, uid) + u:kick(uid) end - local gameserver = assert(server_list[server]) - skynet.call(gameserver, "lua", "login", server, uid, secret) + assert(user_online[uid] == nil, "kick failed") + local gameserver = assert(server_list[server], "Unknown server") + gameserver:login(uid, secret) + user_online[uid] = gameserver end local CMD = {} -function CMD.register_gate(source, name) - server_list[name] = source +function CMD.register_gate(server, address) + server_list[server] = setmetatable( { name = server, address = address }, server_mt ) end -function CMD.logout(source, uid, server) - print(string.format("%s@%s is logout", uid, server)) +function CMD.logout(uid) + local u = user_online[uid] + if u then + print(string.format("%s@%s is logout", uid, u.name)) + user_online[uid] = nil + end end function server.command_handler(command, source, ...) diff --git a/examples/login/msggate.lua b/examples/login/msggate.lua index 85c3d4af..fb74ffc2 100644 --- a/examples/login/msggate.lua +++ b/examples/login/msggate.lua @@ -140,7 +140,7 @@ handler.error = handler.close function handler.open(source, conf) login_master = assert(conf.loginserver) local servername = assert(conf.servername) - skynet.call(login_master, "lua", "register_gate", servername) + skynet.call(login_master, "lua", "register_gate", servername, skynet.self()) end @@ -162,7 +162,7 @@ end function CMD.logout(source) local c = agent[source] if c then - skynet.call(login_master, "lua", "logout", c.server, c.uid) + skynet.call(login_master, "lua", "logout", c.uid) if c.fd then gateserver.closeclient(c.fd) end diff --git a/lualib-src/lua-crypt.c b/lualib-src/lua-crypt.c index 34a190e7..5d2f12f9 100644 --- a/lualib-src/lua-crypt.c +++ b/lualib-src/lua-crypt.c @@ -729,7 +729,7 @@ lb64encode(lua_State *L) { } int i,j; j=0; - for (i=0;i> 18]; buffer[j+1] = encoding[(v >> 12) & 0x3f]; diff --git a/lualib/gamefw/loginserver.lua b/lualib/gamefw/loginserver.lua index 7f022508..a7384105 100644 --- a/lualib/gamefw/loginserver.lua +++ b/lualib/gamefw/loginserver.lua @@ -2,18 +2,21 @@ local skynet = require "skynet" local socket = require "socket" local crypt = require "crypt" -local function launch_slave(auth_handler) - local cmd = {} +local function write(fd, text) + assert(socket.write(fd, text), "socket error") +end +local function launch_slave(auth_handler) -- set socket buffer limit (8K) -- If the attacker send large package, close the socket socket.limit(8192) - function cmd.auth(fd, addr) + local function auth(fd, addr) + fd = assert(tonumber(fd)) skynet.error(string.format("connect from %s (fd = %d)", addr, fd)) socket.start(fd) local challenge = crypt.randomkey() - socket.write(fd, crypt.base64encode(challenge).."\n") + write(fd, crypt.base64encode(challenge).."\n") local handshake = assert(socket.readline(fd), "socket closed") local clientkey = crypt.base64decode(handshake) @@ -21,7 +24,7 @@ local function launch_slave(auth_handler) error "Invalid client key" end local serverkey = crypt.randomkey() - socket.write(fd, crypt.base64encode(crypt.dhexchange(serverkey)).."\n") + write(fd, crypt.base64encode(crypt.dhexchange(serverkey)).."\n") local secret = crypt.dhsecret(clientkey, serverkey) @@ -29,7 +32,7 @@ local function launch_slave(auth_handler) local hmac = crypt.hmac64(challenge, secret) if hmac ~= crypt.base64decode(response) then - socket.write(fd, "400 Bad Request\n") + write(fd, "400 Bad Request\n") error "challenge failed" end @@ -43,26 +46,27 @@ local function launch_slave(auth_handler) return ok, server, uid, secret end - skynet.dispatch("lua", function(_,_,command,...) - local f = assert(cmd[command]) - skynet.ret(skynet.pack(f(...))) + skynet.dispatch("lua", function(_,_,...) + skynet.ret(skynet.pack(auth(...))) end) end local function accept(conf, s, fd, addr) - local ok, server, uid, secret = skynet.call(s, "lua", "auth", fd, addr) + -- call slave auth + local ok, server, uid, secret = skynet.call(s, "lua", fd, addr) + socket.start(fd) + if not ok then - socket.write(fd, "401 Unauthorized\n") + write(fd, "401 Unauthorized\n") error(server) end - socket.start(fd) - local ok, err = pcall(conf.login_handler, server, uid, secret) if ok then - socket.write(fd, "200 OK\n") + err = err or "" + write(fd, "200 "..crypt.base64encode(err).."\n") else - socket.write(fd, "406 Not Acceptable\n") + write(fd, "406 Not Acceptable\n") error(err) end end @@ -80,7 +84,7 @@ local function launch_master(conf) table.insert(slave, source) skynet.ret(skynet.pack(nil)) else - skynet.ret(skynet.pack(conf.command_handler(command, source, ...))) + skynet.ret(skynet.pack(conf.command_handler(command, ...))) end end) @@ -104,7 +108,7 @@ local function launch_master(conf) end) end -local function login (conf) +local function login(conf) local name = "." .. (conf.name or "login") skynet.start(function() local loginmaster = skynet.localname(name)