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
|