parsav  Diff

Differences From Artifact [4721bcd333]:

To Artifact [9e0d1b7489]:


     1      1   -- vim: ft=terra
     2      2   local util = lib.util
     3      3   local secmode = lib.enum { 'public', 'private', 'lockdown', 'isolate' }
     4      4   local pstring = lib.mem.ptr(int8)
     5      5   local struct srv
     6      6   local struct cfgcache {
     7      7   	secret: lib.mem.ptr(int8)
     8         -	instance: lib.mem.ptr(int8)
     9         -	overlord: &srv
    10      8   	pol_sec: secmode.t
    11      9   	pol_reg: bool
           10  +	credmgd: bool
           11  +	maxupsz: intptr
           12  +	instance: lib.mem.ptr(int8)
           13  +	overlord: &srv
    12     14   }
    13     15   local struct srv {
    14     16   	sources: lib.mem.ptr(lib.store.source)
    15     17   	webmgr: lib.net.mg_mgr
    16     18   	webcon: &lib.net.mg_connection
    17     19   	cfg: cfgcache
    18     20   	id: rawstring
................................................................................
   108    110   end)
   109    111   
   110    112   local struct convo {
   111    113   	srv: &srv
   112    114   	con: &lib.net.mg_connection
   113    115   	msg: &lib.net.mg_http_message
   114    116   	aid: uint64 -- 0 if logged out
          117  +	aid_issue: lib.store.timepoint
   115    118   	who: &lib.store.actor -- who we're logged in as, if aid ~= 0
   116    119   	peer: lib.store.inet
   117    120   	reqtype: lib.http.mime.t -- negotiated content type
   118    121   -- cache
   119    122   	navbar: lib.mem.ptr(int8)
   120    123   	actorcache: lib.mem.cache(lib.mem.ptr(lib.store.actor),32) -- naive cache to avoid unnecessary queries
   121    124   -- private
................................................................................
   154    157   
   155    158   	body:send(self.con, 303, [lib.mem.ptr(lib.http.header)] {
   156    159   		ptr = &hdrs[0], ct = [hdrs.type.N] - lib.trn(cookie == nil,1,0)
   157    160   	})
   158    161   end
   159    162   
   160    163   terra convo:reroute(dest: rawstring) self:reroute_cookie(dest,nil) end
          164  +
          165  +terra convo:installkey(dest: rawstring, aid: uint64)
          166  +	var sesskey: int8[lib.session.maxlen + #lib.session.cookiename + #"=; Path=/" + 1]
          167  +	do var p = &sesskey[0]
          168  +		p = lib.str.ncpy(p, [lib.session.cookiename .. '='], [#lib.session.cookiename + 1])
          169  +		p = p + lib.session.cookie_gen(self.srv.cfg.secret, aid, lib.osclock.time(nil), p)
          170  +		lib.dbg('sending cookie ',{&sesskey[0],15})
          171  +		p = lib.str.ncpy(p, '; Path=/', 9)
          172  +	end
          173  +	self:reroute_cookie(dest, &sesskey[0])
          174  +end
   161    175    
   162    176   terra convo:complain(code: uint16, title: rawstring, msg: rawstring)
   163    177   	var hdrs = array(
   164    178   		lib.http.header { key = 'Content-Type', value = 'text/html; charset=UTF-8' },
   165    179   		lib.http.header { key = 'Cache-Control', value = 'no-store' }
   166    180   	)
   167    181   
................................................................................
   232    246   		var r = self.vbofs
   233    247   		self.vbofs = self.vbofs + o + 1
   234    248   		@(self.vbofs - 1) = 0
   235    249   		var norm = lib.str.normalize([lib.mem.ptr(int8)]{ptr = r, ct = o})
   236    250   		return norm.ptr, norm.ct
   237    251   	else return nil, 0 end
   238    252   end
          253  +terra convo:ppostv(name: rawstring)
          254  +	var s,l = self:postv(name)
          255  +	return pstring { ptr = s, ct = l }
          256  +end
   239    257   
   240    258   terra convo:getv(name: rawstring)
   241    259   	if self.varbuf.ptr == nil then
   242    260   		self.varbuf = lib.mem.heapa(int8, self.msg.query.len + self.msg.body.len)
   243    261   		self.vbofs = self.varbuf.ptr
   244    262   	end
   245    263   	var o = lib.net.mg_http_get_var(&self.msg.query, name, self.vbofs, self.varbuf.ct - (self.vbofs - self.varbuf.ptr))
................................................................................
   247    265   		var r = self.vbofs
   248    266   		self.vbofs = self.vbofs + o + 1
   249    267   		@(self.vbofs - 1) = 0
   250    268   		var norm = lib.str.normalize([lib.mem.ptr(int8)]{ptr = r, ct = o})
   251    269   		return norm.ptr, norm.ct
   252    270   	else return nil, 0 end
   253    271   end
          272  +terra convo:pgetv(name: rawstring)
          273  +	var s,l = self:getv(name)
          274  +	return pstring { ptr = s, ct = l }
          275  +end
   254    276   
   255    277   local urimatch = macro(function(uri, ptn)
   256    278   	return `lib.net.mg_globmatch(ptn, [#ptn], uri.ptr, uri.ct+1)
   257    279   end)
   258    280   
   259    281   local route = {} -- these are defined in route.t, as they need access to renderers
   260    282   terra route.dispatch_http ::  {&convo, lib.mem.ptr(int8), lib.http.method.t} -> {}
................................................................................
   303    325   
   304    326   		switch event do
   305    327   			case lib.net.MG_EV_HTTP_MSG then
   306    328   				lib.dbg('routing HTTP request')
   307    329   				var msg = [&lib.net.mg_http_message](p)
   308    330   				var co = convo {
   309    331   					con = con, srv = server, msg = msg;
   310         -					aid = 0, who = nil, peer = peer;
          332  +					aid = 0, aid_issue = 0, who = nil;
   311    333   					reqtype = lib.http.mime.none;
          334  +					peer = peer;
   312    335   				} co.varbuf.ptr = nil
   313    336   				  co.navbar.ptr = nil
   314    337   				  co.actorcache.top = 0
   315    338   				  co.actorcache.cur = 0
   316    339   
   317    340   				-- first, check for an accept header. if it's there, we need to
   318    341   				-- iterate over the values and pick the highest-priority one
................................................................................
   388    411   					end
   389    412   					if val.ptr == nil then goto nocookie end
   390    413   					val.ct = (cookies + i) - val.ptr
   391    414   					if lib.str.ncmp(key.ptr, lib.session.cookiename, lib.math.biggest([#lib.session.cookiename], key.ct)) ~= 0 then
   392    415   						goto nocookie
   393    416   					end
   394    417   					::foundcookie:: do
   395         -						var aid = lib.session.cookie_interpret(server.cfg.secret,
          418  +						var aid, tp = lib.session.cookie_interpret(server.cfg.secret,
   396    419   							[lib.mem.ptr(int8)]{ptr=val.ptr,ct=val.ct},
   397    420   							lib.osclock.time(nil))
   398         -						if aid ~= 0 then co.aid = aid end
          421  +						if aid ~= 0 then co.aid = aid co.aid_issue = tp end
   399    422   					end ::nocookie::;
   400    423   				end
   401    424   
   402    425   				if co.aid ~= 0 then
   403         -					var sess, usr = co.srv:actor_session_fetch(co.aid, peer)
   404         -					if sess.ok == false then co.aid = 0 else
          426  +					var sess, usr = co.srv:actor_session_fetch(co.aid, peer, co.aid_issue)
          427  +					if sess.ok == false then co.aid = 0 co.aid_issue = 0 else
   405    428   						co.who = usr.ptr
   406    429   						co.who.rights.powers = server:actor_powers_fetch(co.who.id)
   407    430   					end
   408    431   				end
   409    432   
   410    433   				var uridec = lib.mem.heapa(int8, msg.uri.len) defer uridec:free()
   411    434   				var urideclen = lib.net.mg_url_decode(msg.uri.ptr, msg.uri.len, uridec.ptr, uridec.ct, 1)
................................................................................
   640    663   	self.sources:free()
   641    664   end
   642    665   
   643    666   terra cfgcache:load()
   644    667   	self.instance = self.overlord:conf_get('instance-name')
   645    668   	self.secret = self.overlord:conf_get('server-secret')
   646    669   
   647         -	self.pol_reg = false
          670  +	do self.pol_reg = false
   648    671   	var sreg = self.overlord:conf_get('policy-self-register')
   649         -	if sreg.ptr ~= nil then
          672  +	if sreg:ref() then
   650    673   		if lib.str.cmp(sreg.ptr, 'on') == 0
   651    674   			then self.pol_reg = true
   652    675   			else self.pol_reg = false
   653    676   		end
   654    677   	end
   655         -	sreg:free()
          678  +	sreg:free() end
          679  +
          680  +	do self.credmgd = false
          681  +	var sreg = self.overlord:conf_get('credential-store')
          682  +	if sreg:ref() then
          683  +		if lib.str.cmp(sreg.ptr, 'managed') == 0
          684  +			then self.credmgd = true
          685  +			else self.credmgd = false
          686  +		end
          687  +	end
          688  +	sreg:free() end
          689  +
          690  +	do self.maxupsz = [1024 * 100] -- 100 kilobyte default
          691  +	var sreg = self.overlord:conf_get('maximum-artifact-size')
          692  +	if sreg:ref() then
          693  +		var sz, ok = lib.math.fsz_parse(sreg)
          694  +		if ok then self.maxupsz = sz else
          695  +			lib.warn('invalid configuration value for maximum-artifact-size; keeping default 100K upload limit')
          696  +		end
          697  +	end
          698  +	sreg:free() end
   656    699   	
   657    700   	self.pol_sec = secmode.lockdown
   658    701   	var smode = self.overlord:conf_get('policy-security')
   659    702   	if smode.ptr ~= nil then
   660    703   		if lib.str.cmp(smode.ptr, 'public') == 0 then
   661    704   			self.pol_sec = secmode.public
   662    705   		elseif lib.str.cmp(smode.ptr, 'private') == 0 then