aboutsummaryrefslogtreecommitdiff
path: root/src/libauth/auth_challenge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libauth/auth_challenge.c')
-rw-r--r--src/libauth/auth_challenge.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/libauth/auth_challenge.c b/src/libauth/auth_challenge.c
new file mode 100644
index 00000000..298f5f1b
--- /dev/null
+++ b/src/libauth/auth_challenge.c
@@ -0,0 +1,117 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+#include <authsrv.h>
+#include "authlocal.h"
+
+Chalstate*
+auth_challenge(char *fmt, ...)
+{
+ char *p;
+ va_list arg;
+ Chalstate *c;
+
+ quotefmtinstall(); /* just in case */
+ va_start(arg, fmt);
+ p = vsmprint(fmt, arg);
+ va_end(arg);
+ if(p == nil)
+ return nil;
+
+ c = mallocz(sizeof(*c), 1);
+ if(c == nil){
+ free(p);
+ return nil;
+ }
+
+ if((c->afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
+ Error:
+ auth_freechal(c);
+ free(p);
+ return nil;
+ }
+
+ if((c->rpc=auth_allocrpc(c->afd)) == nil
+ || auth_rpc(c->rpc, "start", p, strlen(p)) != ARok
+ || auth_rpc(c->rpc, "read", nil, 0) != ARok)
+ goto Error;
+
+ if(c->rpc->narg > sizeof(c->chal)-1){
+ werrstr("buffer too small for challenge");
+ goto Error;
+ }
+ memmove(c->chal, c->rpc->arg, c->rpc->narg);
+ c->nchal = c->rpc->narg;
+ free(p);
+ return c;
+}
+
+AuthInfo*
+auth_response(Chalstate *c)
+{
+ int ret;
+ AuthInfo *ai;
+
+ ai = nil;
+ if(c->afd < 0){
+ werrstr("auth_response: connection not open");
+ return nil;
+ }
+ if(c->resp == nil){
+ werrstr("auth_response: nil response");
+ return nil;
+ }
+ if(c->nresp == 0){
+ werrstr("auth_response: unspecified response length");
+ return nil;
+ }
+
+ if(c->user){
+ if(auth_rpc(c->rpc, "write", c->user, strlen(c->user)) != ARok){
+ /*
+ * if this fails we're out of phase with factotum.
+ * give up.
+ */
+ goto Out;
+ }
+ }
+
+ if(auth_rpc(c->rpc, "write", c->resp, c->nresp) != ARok){
+ /*
+ * don't close the connection -- maybe we'll try again.
+ */
+ return nil;
+ }
+
+ switch(ret = auth_rpc(c->rpc, "read", nil, 0)){
+ case ARok:
+ default:
+ werrstr("factotum protocol botch %d %s", ret, c->rpc->ibuf);
+ break;
+ case ARdone:
+ ai = auth_getinfo(c->rpc);
+ break;
+ }
+
+Out:
+ close(c->afd);
+ auth_freerpc(c->rpc);
+ c->afd = -1;
+ c->rpc = nil;
+ return ai;
+}
+
+void
+auth_freechal(Chalstate *c)
+{
+ if(c == nil)
+ return;
+
+ if(c->afd >= 0)
+ close(c->afd);
+ if(c->rpc != nil)
+ auth_freerpc(c->rpc);
+
+ memset(c, 0xBB, sizeof(*c));
+ free(c);
+}