parsav  Diff

Differences From Artifact [cd7a14ae6e]:

To Artifact [57b2f599e2]:


354
355
356
357
358
359
360
361

362
363
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
...
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
...
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
	::badop :: do co:complain(405, 'invalid operation', 'the operation you have attempted on this post is not meaningful') return end
	::noauth:: do co:complain(401, 'unauthorized', 'you have not supplied the necessary credentials to perform this operation') return end
end

local terra 
credsec_for_uid(co: &lib.srv.convo, uid: uint64)
	var act = co:ppostv('act')
	lib.dbg('showing credentials')

	if act:cmp( 'invalidate') then
		lib.dbg('setting user\'s cookie validation time to now')
		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
................................................................................
				co.srv:auth_privs_set(aid, privs)
			end

			lib.dbg('setting netmask restrictions')
			var nm = co:pgetv('netmask')
		end
		co:reroute('?')
		return
	end
	co:complain(400,'bad request','the operation you have requested is not meaningful in this context')

end

terra http.configure(co: &lib.srv.convo, path: hpath, meth: method.t)
	var msg = pstring.null()
	-- first things first, do priv checks
	if path.ct >= 2 then
		if not co.who.rights.powers.config() and (
................................................................................
				co.ui_hue = co.srv.cfg.ui_hue
			end

			msg = 'profile changes saved'
			--user_refresh = true -- not really necessary here, actually

		elseif path(1):cmp('sec') then
			credsec_for_uid(co, co.who.id)
		elseif path(1):cmp('avi') then
			var act = co:ppostv('act')
			if act:ref() and act:cmp('clear') then
				co.who.avatarid = 0
				co.who.source:actor_save(co.who)
				msg = 'avatar reset to default'
			else goto badop end
................................................................................
							goto nopriv
						end
					else goto badop end
					defer usr:free()

					if path.ct == 4 then
						if path(3):cmp(lib.str.lit 'cred') then
							credsec_for_uid(co, userid)
						end
					elseif path.ct == 3 then
						var purgestr = co:ppostv("purgestr")
						var purgekey = co:ppostv("purgekey")
						if purgestr:ref() and purgekey:ref() and purgestr(0) ~= 0 then
							if purgestr:cmp(purgekey) then -- destroying account! :O
								co.srv:actor_purge_uid(userid)







|
>





>
>
>
>
>
>
>
>
>
|
|








|









|






|





|








|





|







 







|


>







 







|







 







|







354
355
356
357
358
359
360
361
362
363
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
429
430
431
432
...
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
...
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
...
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
	::badop :: do co:complain(405, 'invalid operation', 'the operation you have attempted on this post is not meaningful') return end
	::noauth:: do co:complain(401, 'unauthorized', 'you have not supplied the necessary credentials to perform this operation') return end
end

local terra 
credsec_for_uid(co: &lib.srv.convo, uid: uint64)
	var act = co:ppostv('act')
	if not act then return true end
	lib.dbg('handling credential action')
	if act:cmp( 'invalidate') then
		lib.dbg('setting user\'s cookie validation time to now')
		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 false
	elseif act:cmp('revoke') then
		var s_cred = co:ppostv('cred')
		if s_cred:ref() then
			var cred, ok = lib.math.shorthand.parse(s_cred.ptr, s_cred.ct)
			if ok then
				co.srv:auth_destroy_aid_uid(cred,co.who.id)
			end
		end
		return true
	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 false
			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 false
			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 false
			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 false
			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 false
			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 false
			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
................................................................................
				co.srv:auth_privs_set(aid, privs)
			end

			lib.dbg('setting netmask restrictions')
			var nm = co:pgetv('netmask')
		end
		co:reroute('?')
		return false
	end
	co:complain(400,'bad request','the operation you have requested is not meaningful in this context')
	return false
end

terra http.configure(co: &lib.srv.convo, path: hpath, meth: method.t)
	var msg = pstring.null()
	-- first things first, do priv checks
	if path.ct >= 2 then
		if not co.who.rights.powers.config() and (
................................................................................
				co.ui_hue = co.srv.cfg.ui_hue
			end

			msg = 'profile changes saved'
			--user_refresh = true -- not really necessary here, actually

		elseif path(1):cmp('sec') then
			if not credsec_for_uid(co, co.who.id) then return end
		elseif path(1):cmp('avi') then
			var act = co:ppostv('act')
			if act:ref() and act:cmp('clear') then
				co.who.avatarid = 0
				co.who.source:actor_save(co.who)
				msg = 'avatar reset to default'
			else goto badop end
................................................................................
							goto nopriv
						end
					else goto badop end
					defer usr:free()

					if path.ct == 4 then
						if path(3):cmp(lib.str.lit 'cred') then
							if not credsec_for_uid(co, userid) then return end 
						end
					elseif path.ct == 3 then
						var purgestr = co:ppostv("purgestr")
						var purgekey = co:ppostv("purgekey")
						if purgestr:ref() and purgekey:ref() and purgestr(0) ~= 0 then
							if purgestr:cmp(purgekey) then -- destroying account! :O
								co.srv:actor_purge_uid(userid)