summaryrefslogtreecommitdiff
path: root/lib9p/srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r--lib9p/srv.c76
1 files changed, 74 insertions, 2 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c
index f25fe09..1510a4a 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -14,6 +14,12 @@
/* structs ********************************************************************/
+#define NAME fidmap
+#define KEY_T uint32_t
+#define VAL_T struct lib9p_srv_file
+#define CAP CONFIG_9P_MAX_FIDS
+#include "map.h"
+
/* The hierarchy of concepts is:
*
* server -> connection -> session -> request
@@ -40,6 +46,7 @@ struct lib9p_sess {
/* mutable */
bool initialized;
unsigned int refcount;
+ struct fidmap fids;
};
struct lib9p_req {
@@ -48,7 +55,7 @@ struct lib9p_req {
uint16_t tag;
/* mutable */
uint8_t *net_bytes; /* CONFIG_9P_MAX_MSG_SIZE-sized */
- struct lib9p_ctx ctx;
+ struct lib9p_reqctx ctx;
};
/* base utilities *************************************************************/
@@ -195,6 +202,8 @@ COROUTINE lib9p_srv_read_cr(void *_srv) {
/* write coroutine ************************************************************/
static void handle_Tversion(struct lib9p_req *ctx, struct lib9p_msg_Tversion *req, struct lib9p_msg_Rversion *resp);
+static void handle_Tauth(struct lib9p_req *ctx, struct lib9p_msg_Tauth *req, struct lib9p_msg_Rauth *resp);
+static void handle_Tattach(struct lib9p_req *ctx, struct lib9p_msg_Tattach *req, struct lib9p_msg_Rattach *resp);
COROUTINE lib9p_srv_write_cr(void *_srv) {
uint8_t net[CONFIG_9P_MAX_MSG_SIZE];
@@ -287,7 +296,7 @@ COROUTINE lib9p_srv_write_cr(void *_srv) {
}
write:
- if (req.ctx.err_num || req.ctx.err_msg[0])
+ if (lib9p_ctx_has_error(&req.ctx))
respond_error(&req);
else {
if (lib9p_marshal(&req.ctx, typ+1, req.tag, host_resp, net))
@@ -335,3 +344,66 @@ static void handle_Tversion(struct lib9p_req *ctx, struct lib9p_msg_Tversion *re
? CONFIG_9P_MAX_MSG_SIZE
: req->max_msg_size;
}
+
+static void handle_Tauth(struct lib9p_req *ctx, struct lib9p_msg_Tauth *UNUSED(req), struct lib9p_msg_Rauth *UNUSED(resp)) {
+ if (!ctx->parent_sess->parent_conn->parent_srv->auth) {
+ lib9p_error(&ctx->ctx, LINUX_EOPNOTSUPP, "authentication not required");
+ return;
+ }
+ ctx->ctx.uid = req->uid;
+ ctx->ctx.uname = req->uname.utf8;
+ lib9p_error(&ctx->ctx, LINUX_EOPNOTSUPP, "TODO: auth not implemented");
+ return;
+}
+
+static void handle_Tattach(struct lib9p_req *ctx, struct lib9p_msg_Tattach *req, struct lib9p_msg_Rattach *resp) {
+ ctx->ctx.uid = req->uid;
+ ctx->ctx.uname = req->uname.utf8;
+ if (ctx->parent_sess->parent_conn->parent_srv->auth) {
+ /*
+ struct lib9p_srv_filehandle *fh = fidmap_get(req->afid);
+ if (!fh)
+ lib9p_error(&ctx->ctx, LINUX_EACCES, "FID provided as auth-file is not a valid FID");
+ else if (fh->type != FH_AUTH)
+ lib9p_error(&ctx->ctx, LINUX_EACCES, "FID provided as auth-file is not an auth-file");
+ else if (strcmp(fh->data.auth.uname, req->uname.utf8) != 0)
+ lib9p_errorf(&ctx->ctx, LINUX_EACCES, "FID provided as auth-file is for user=\"%s\" and cannot be used for user=\"%s\"",
+ fh->data.auth.uname, req->uname.utf8);
+ else if (strcmp(fh->data.auth.aname, req->aname.utf8) != 0)
+ lib9p_errorf(&ctx->ctx, LINUX_EACCES, "FID provided as auth-file is for tree=\"%s\" and cannot be used for tree=\"%s\"",
+ fh->data.auth.aname, req->aname.utf8);
+ else if (!fh->data.auth.authenticated)
+ lib9p_error(&ctx->ctx, LINUX_EACCES, "FID provided as auth-file has not completed authentication");
+ fh->refcount--;
+ if (lib9p_ctx_has_error(&ctx->ctx))
+ return;
+ */
+ lib9p_error(&ctx->ctx, LINUX_EOPNOTSUPP, "TODO: auth not implemented");
+ return;
+ } else {
+ if (req->afid != LIB9P_NOFID) {
+ lib9p_error(&ctx->ctx, LINUX_EACCES, "FID provided as auth-file, but no auth-file is required");
+ return;
+ }
+ }
+
+ if (fidmap_load(&ctx->parent_sess->fids, req->fid)) {
+ lib9p_error(&ctx->ctx, LINUX_EBADF, "FID already in use");
+ return;
+ }
+
+ struct lib9p_srv_file rootdir = ctx->parent_sess->parent_conn->parent_srv->rootdir(&ctx->ctx, req->aname.utf8);
+ if (lib9p_ctx_has_error(&ctx->ctx.ctx))
+ return;
+
+ struct lib9p_srv_file *rootdir_ptr = fidmap_store(&ctx->parent_sess->fids, req->fid, rootdir);
+ if (!rootdir_ptr) {
+ lib9p_error(&ctx->ctx, LINUX_EMFILE, "too many open files");
+ if (rootdir.free)
+ rootdir.free(ctx, rootdir.impldata);
+ return;
+ }
+
+ resp->qid = rootdir.qid;
+ return;
+}