parsav  Diff

Differences From Artifact [6caa1366ba]:

To Artifact [cd7a14ae6e]:


140
141
142
143
144
145
146
147
148

























149
150
151
152
153
154
155
156
...
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356






357





358


























359
360
361
362
363
364
365
			-- pick an auth method
			lib.render.login(co, act.ptr, &cs, pstring.null())
		else var aid: uint64 = 0
			lib.dbg('authentication attempt beginning')
			-- attempt login with provided method
			if lib.str.ncmp('pw', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then
				aid = co.srv:actor_auth_pw(co.peer,
					[lib.mem.ptr(int8)]{ptr=usn,ct=usnl},
					[lib.mem.ptr(int8)]{ptr=chrs,ct=chrsl})

























			elseif lib.str.ncmp('otp', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then
				lib.dbg('using otp auth')
				-- ··· --
			else lib.dbg('invalid auth method') end

			-- error out
			if aid == 0 then
				lib.render.login(co, nil, nil,  'authentication failure')
................................................................................
		co.who.source:auth_sigtime_user_alter(uid, lib.osclock.time(nil))
		-- the current session has been invalidated as well, so we need to immediately install a new authentication cookie with the same aid so the user doesn't need to log back in all over again
		co:installkey('?',co.aid)
		return
	elseif act:cmp( 'newcred') then
		var cmt = co:ppostv('comment')
		var pw = co:ppostv('newpw')

		var aid: uint64 = 0
		if pw:ref() then
			var cpw = co:ppostv('rptpw')
			if not pw:cmp(cpw) then
				co:complain(400,'enrollment failure','the passwords you supplied do not match')
				return
			end
			aid = co.srv:auth_attach_pw(uid, false, pw, cmt)
		else
			var key = co:ppostv('newkey')
			if key:ref() then












			end


























		end
		if aid ~= 0 then
			lib.dbg('setting credential restrictions')
			var privs = [(function()
				local check = quote end
				local me = symbol(lib.store.privset)
				for i,v in ipairs(lib.store.privset.members) do







|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







>








|
|
|
>
>
>
>
>
>

>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
...
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
			-- pick an auth method
			lib.render.login(co, act.ptr, &cs, pstring.null())
		else var aid: uint64 = 0
			lib.dbg('authentication attempt beginning')
			-- attempt login with provided method
			if lib.str.ncmp('pw', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then
				aid = co.srv:actor_auth_pw(co.peer,
					pstring {ptr=usn,ct=usnl},
					pstring {ptr=chrs,ct=chrsl})
			elseif lib.str.ncmp('challenge', am, lib.math.biggest(9,aml)) == 0 and chrs ~= nil then
				lib.dbg('challenge attempt beginning')
				var s_time = co:ppostv('time')
				var s_vfy = co:ppostv('vfy')
				var token = co:ppostv('token')
				if s_time:ref() and s_vfy:ref() and token:ref() then 
					lib.dbg('checking hmac validity')
					var vftok = co:stra(128) vftok:ppush(token):ppush(s_time)
					var hmac = lib.crypt.hmacp(&co.srv.pool, lib.crypt.alg.sha256, co.srv.cfg.secret:blob(), vftok:finalize())
					var vfy, vfyok = lib.math.shorthand.parse(s_vfy.ptr, s_vfy.ct)
					if vfyok and lib.math.truncate64(hmac.ptr,hmac.ct) == vfy then
						lib.dbg('checking expiration time')
						var time, timeok = lib.math.shorthand.parse(s_time.ptr, s_time.ct)
						if timeok and lib.osclock.time(nil) - time < [2 * 60] then -- two minutes
							lib.dbg('decoding base64')
							var bin = co.srv.pool:alloc(uint8, chrsl)
							var binlen: intptr
							if lib.b64.mbedtls_base64_decode(bin.ptr, bin.ct, &binlen, [&uint8](chrs), chrsl) == 0 then
								lib.dbg('running signature <',{chrs,chrsl},'> against challenge keys for token [', {token.ptr,token.ct}, ']')
								aid = co.srv:actor_auth_challenge(co.peer,
									pstring {usn,usnl}, binblob{bin.ptr,binlen}, token)
							end
						end
					end
				end
			elseif lib.str.ncmp('otp', am, lib.math.biggest(3,aml)) == 0 and chrs ~= nil then
				lib.dbg('using otp auth')
				-- ··· --
			else lib.dbg('invalid auth method') end

			-- error out
			if aid == 0 then
				lib.render.login(co, nil, nil,  'authentication failure')
................................................................................
		co.who.source:auth_sigtime_user_alter(uid, lib.osclock.time(nil))
		-- the current session has been invalidated as well, so we need to immediately install a new authentication cookie with the same aid so the user doesn't need to log back in all over again
		co:installkey('?',co.aid)
		return
	elseif act:cmp( 'newcred') then
		var cmt = co:ppostv('comment')
		var pw = co:ppostv('newpw')
		var rsapub = co:ppostv('newrsa'):blob()
		var aid: uint64 = 0
		if pw:ref() then
			var cpw = co:ppostv('rptpw')
			if not pw:cmp(cpw) then
				co:complain(400,'enrollment failure','the passwords you supplied do not match')
				return
			end
			aid = co.srv:auth_attach_pw(uid, false, pw, cmt)
		elseif rsapub:ref() then
			var sig = co:ppostv('sig')
			var nonce = co:ppostv('nonce')
			var s_noncevld = co:ppostv('noncevld')
			var noncevld, ok = lib.math.shorthand.parse(s_noncevld.ptr, s_noncevld.ct)
			if not ok then
				co:complain(403,'try harder next time','you call that cryptanalysis?')
				return
			end

			var fr = co.srv.pool:frame()
			var hmac = lib.crypt.hmacp(&co.srv.pool, lib.crypt.alg.sha256, co.srv.cfg.secret:blob(), nonce)
			if not lib.math.truncate64(hmac.ptr, hmac.ct) == noncevld then
				co:complain(403,'nice try','what exactly are you trying to accomplish here, buddy')
				return
			end

			var pkres = lib.crypt.loadpub(rsapub.ptr,rsapub.ct+1) -- needs NUL
			if not pkres.ok then
				co:complain(400,'invalid key','the key you have supplied is not a valid PEM or DER file')
				return
			end
			var pk = pkres.val
			defer pk:free()

			var decoded = co.srv.pool:alloc(uint8,sig.ct)
			var decoded_sz: intptr = 0
			if lib.b64.mbedtls_base64_decode(decoded.ptr,sig.ct,&decoded_sz,[&uint8](sig.ptr),sig.ct) ~= 0 then
				co:complain(400,'invalid signature','the signature you supplied is not encoded in valid base64')
				return
			end

			var vfy, secl = lib.crypt.verify(&pk, nonce.ptr, nonce.ct, decoded.ptr, decoded_sz)
			if not vfy then
				co:complain(403,'verification failed','the signature you supplied does not match the required nonce')
				return
			end

			var dbuf: uint8[lib.crypt.const.maxdersz]
			var derkey = lib.crypt.der(true, &pk, &dbuf[0])
			aid = co.srv:auth_attach_rsa(co.who.id, false, derkey, cmt)
			co.srv.pool:reset(fr)
		end
		if aid ~= 0 then
			lib.dbg('setting credential restrictions')
			var privs = [(function()
				local check = quote end
				local me = symbol(lib.store.privset)
				for i,v in ipairs(lib.store.privset.members) do