Changeset 3903

Show
Ignore:
Timestamp:
12/14/08 22:43:10 (5 years ago)
Author:
Cyrus
Message:

Implement URL tokens
Add basic XSRF protection

Location:
luci/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • luci/trunk/libs/web/luasrc/dispatcher.lua

    r3836 r3903  
    4848-- @return      Relative URL 
    4949function build_url(...) 
    50     return luci.http.getenv("SCRIPT_NAME") .. "/" .. table.concat(arg, "/") 
     50    return context.scriptname .. "/" .. table.concat(arg, "/") 
    5151end 
    5252 
     
    124124    local ctx = context 
    125125    ctx.path = request 
     126    ctx.scriptname = luci.http.getenv("SCRIPT_NAME") or "" 
     127    ctx.urltoken   = ctx.urltoken or {} 
    126128 
    127129    require "luci.i18n".setlanguage(require "luci.config".main.lang) 
     
    138140    ctx.requestargs = ctx.requestargs or args 
    139141    local n 
     142    local t = true 
     143    local token = ctx.urltoken 
     144    local preq = {} 
    140145 
    141146    for i, s in ipairs(request) do 
    142         c = c.nodes[s] 
    143         n = i 
    144         if not c then 
    145             break 
    146         end 
    147  
    148         util.update(track, c) 
    149  
    150         if c.leaf then 
    151             break 
     147        local tkey, tval 
     148        if t then 
     149            tkey, tval = s:match(";(%w+)=(.*)") 
     150        end 
     151 
     152        if tkey then 
     153            token[tkey] = tval 
     154        else 
     155            t = false 
     156            preq[#preq+1] = s 
     157            c = c.nodes[s] 
     158            n = i 
     159            if not c then 
     160                break 
     161            end 
     162 
     163            util.update(track, c) 
     164 
     165            if c.leaf then 
     166                break 
     167            end 
    152168        end 
    153169    end 
     
    158174        end 
    159175    end 
     176 
     177    for k, v in pairs(token) do 
     178        ctx.scriptname = ctx.scriptname .. "/;" .. k .. "=" .. 
     179            http.urlencode(v) 
     180    end 
     181 
     182    ctx.path = preq 
    160183 
    161184    if track.i18n then 
     
    178201        end 
    179202 
    180         local viewns = setmetatable({}, {__index=_G}) 
     203        local viewns = setmetatable({}, {__index=function(table, key) 
     204            if key == "controller" then 
     205                return ctx.scriptname 
     206            elseif key == "REQUEST_URI" then 
     207                return ctx.scriptname .. "/" .. table.concat(ctx.requested, "/") 
     208            else 
     209                return rawget(table, key) or _G[key] 
     210            end 
     211        end}) 
    181212        tpl.context.viewns = viewns 
    182213        viewns.write       = luci.http.write 
     
    184215        viewns.translate   = function(...) return require("luci.i18n").translate(...) end 
    185216        viewns.striptags   = util.striptags 
    186         viewns.controller  = luci.http.getenv("SCRIPT_NAME") 
    187217        viewns.media       = media 
    188218        viewns.theme       = fs.basename(media) 
    189219        viewns.resource    = luci.config.main.resourcebase 
    190         viewns.REQUEST_URI = (luci.http.getenv("SCRIPT_NAME") or "") .. (luci.http.getenv("PATH_INFO") or "") 
    191220    end 
    192221 
     
    203232        local def  = (type(track.sysauth) == "string") and track.sysauth 
    204233        local accs = def and {track.sysauth} or track.sysauth 
    205         local sess = ctx.authsession or luci.http.getcookie("sysauth") 
    206         sess = sess and sess:match("^[A-F0-9]+$") 
    207         local user = sauth.read(sess) 
     234        local sess = ctx.authsession 
     235        local verifytoken = true 
     236        if not sess then 
     237            sess = luci.http.getcookie("sysauth") 
     238            sess = sess and sess:match("^[A-F0-9]+$") 
     239        end 
     240 
     241        local sdat = sauth.read(sess) 
     242        local user 
     243 
     244        if sdat then 
     245            sdat = loadstring(sdat)() 
     246            if not verifytoken or ctx.urltoken.stok == sdat.token then 
     247                user = sdat.user 
     248            end 
     249        end 
    208250 
    209251        if not util.contains(accs, user) then 
     
    216258                    luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path=/") 
    217259                    if not sess then 
    218                         sauth.write(sid, user) 
     260                        local token = luci.sys.uniqueid(16) 
     261                        sauth.write(sid, util.get_bytecode({ 
     262                            user=user, 
     263                            token=token, 
     264                            secret=luci.sys.uniqueid(16) 
     265                        })) 
     266                        ctx.scriptname = ctx.scriptname .. "/;stok="..token 
    219267                    end 
    220268                    ctx.authsession = sid 
     
    224272                return 
    225273            end 
     274        else 
     275            ctx.authsession = sess 
    226276        end 
    227277    end 
  • luci/trunk/modules/rpc/luasrc/controller/rpc.lua

    r3131 r3903  
    5353    local sys     = require "luci.sys" 
    5454    local ltn12   = require "luci.ltn12" 
     55    local util    = require "luci.util" 
    5556     
    5657    local loginstat 
    5758     
    5859    local server = {} 
    59     server.login = function(user, pass) 
    60         local sid 
    61          
     60    server.challenge = function(user, pass) 
     61        local sid, token, secret 
     62 
    6263        if sys.user.checkpasswd(user, pass) then 
    6364            sid = sys.uniqueid(16) 
     65            token = sys.uniqueid(16) 
     66            secret = sys.uniqueid(16) 
     67 
    6468            http.header("Set-Cookie", "sysauth=" .. sid.."; path=/") 
    65             sauth.write(sid, user) 
     69            sauth.write(sid, util.get_bytecode({ 
     70                user=user, 
     71                token=token, 
     72                secret=secret 
     73            })) 
    6674        end 
    6775         
    68         return sid 
     76        return sid and {sid=sid, token=token, secret=secret} 
     77    end 
     78 
     79    server.login = function(...) 
     80        local challenge = server.challenge(...) 
     81        return challenge and challenge.sid 
    6982    end 
    7083