#include <stdlib.h>
+#include <linux/fscrypt.h>
+
#include "include/cephfs/libcephfs.h"
#include "proxy_log.h"
return ans.res;
}
+
+__public int32_t ceph_add_fscrypt_key(struct ceph_mount_info *cmount,
+ const char *key_data, int32_t key_len,
+ char *kid, int32_t user)
+{
+ CEPH_REQ(ceph_add_fscrypt_key, req, 1, ans, 1);
+
+ req.user = user;
+ req.kid = FSCRYPT_KEY_IDENTIFIER_SIZE;
+
+ CEPH_BUFF_ADD(req, key_data, key_len);
+
+ CEPH_BUFF_ADD(ans, kid, FSCRYPT_KEY_IDENTIFIER_SIZE);
+
+ return CEPH_PROCESS(cmount, LIBCEPHFSD_OP_ADD_FSCRYPT_KEY, req, ans);
+}
+
+__public int32_t ceph_remove_fscrypt_key(struct ceph_mount_info *cmount,
+ struct fscrypt_remove_key_arg *arg,
+ int32_t user)
+{
+ CEPH_REQ(ceph_remove_fscrypt_key, req, 1, ans, 1);
+
+ req.user = user;
+ req.arg = sizeof(struct fscrypt_remove_key_arg);
+
+ CEPH_BUFF_ADD(req, arg, sizeof(struct fscrypt_remove_key_arg));
+
+ CEPH_BUFF_ADD(ans, arg, sizeof(struct fscrypt_remove_key_arg));
+
+ return CEPH_PROCESS(cmount, LIBCEPHFSD_OP_REMOVE_FSCRYPT_KEY, req, ans);
+}
+
+__public int32_t ceph_get_fscrypt_key_status(
+ struct ceph_mount_info *cmount, struct fscrypt_get_key_status_arg *arg)
+{
+ CEPH_REQ(ceph_get_fscrypt_key_status, req, 1, ans, 1);
+
+ req.arg = sizeof(struct fscrypt_get_key_status_arg);
+
+ CEPH_BUFF_ADD(req, arg, sizeof(struct fscrypt_get_key_status_arg));
+
+ CEPH_BUFF_ADD(ans, arg, sizeof(struct fscrypt_get_key_status_arg));
+
+ return CEPH_PROCESS(cmount, LIBCEPHFSD_OP_REMOVE_FSCRYPT_KEY, req, ans);
+}
+
+__public int32_t ceph_ll_set_fscrypt_policy_v2(
+ struct ceph_mount_info *cmount, Inode *in,
+ const struct fscrypt_policy_v2 *policy)
+{
+ CEPH_REQ(ceph_ll_set_fscrypt_policy_v2, req, 1, ans, 0);
+
+ req.inode = ptr_value(in);
+ req.policy = sizeof(struct fscrypt_policy_v2);
+
+ CEPH_BUFF_ADD(req, policy, sizeof(struct fscrypt_policy_v2));
+
+ return CEPH_PROCESS(cmount, LIBCEPHFSD_OP_LL_SET_FSCRYPT_POLICY_V2, req,
+ ans);
+}
+
+__public int32_t ceph_ll_get_fscrypt_policy_v2(struct ceph_mount_info *cmount,
+ Inode *in,
+ struct fscrypt_policy_v2 *policy)
+{
+ CEPH_REQ(ceph_ll_get_fscrypt_policy_v2, req, 0, ans, 1);
+
+ req.inode = ptr_value(in);
+ req.policy = sizeof(struct fscrypt_policy_v2);
+
+ CEPH_BUFF_ADD(ans, policy, sizeof(struct fscrypt_policy_v2));
+
+ return CEPH_PROCESS(cmount, LIBCEPHFSD_OP_LL_GET_FSCRYPT_POLICY_V2, req,
+ ans);
+}
+
+__public int32_t ceph_ll_is_encrypted(struct ceph_mount_info *cmount,
+ Inode *in, char *enctag)
+{
+ CEPH_REQ(ceph_ll_is_encrypted, req, 1, ans, 0);
+
+ req.inode = ptr_value(in);
+
+ CEPH_STR_ADD(req, tag, enctag);
+
+ return CEPH_PROCESS(cmount, LIBCEPHFSD_OP_LL_IS_ENCRYPTED, req, ans);
+}
#include <string.h>
#include <stdarg.h>
+#include <linux/fscrypt.h>
+
#include "include/cephfs/libcephfs.h"
#include "proxy_manager.h"
return CEPH_COMPLETE(client, err, ans);
}
+static int32_t libcephfsd_add_fscrypt_key(proxy_client_t *client,
+ proxy_req_t *req, const void *data,
+ int32_t data_size)
+{
+ CEPH_DATA(ceph_add_fscrypt_key, ans, 1);
+ char kid[FSCRYPT_KEY_IDENTIFIER_SIZE];
+ proxy_mount_t *mount;
+ uint32_t user;
+ int32_t err;
+
+ err = ptr_check(&client->random, req->add_fscrypt_key.cmount,
+ (void **)&mount);
+ if ((err >= 0) &&
+ (req->add_fscrypt_key.kid != sizeof(kid))) {
+ err = proxy_log(LOG_ERR, EINVAL, "Invalid size of key id");
+ }
+ if (err >= 0) {
+ user = req->add_fscrypt_key.user;
+
+ CEPH_BUFF_ADD(ans, kid, sizeof(kid));
+
+ err = ceph_add_fscrypt_key(proxy_cmount(mount), data,
+ req->add_fscrypt_key.key, kid,
+ user);
+ TRACE("add_fscrypt_key(%p, %u) -> %d", mount, user, err);
+ }
+
+ return CEPH_COMPLETE(client, err, ans);
+}
+
+static int32_t libcephfsd_remove_fscrypt_key(proxy_client_t *client,
+ proxy_req_t *req, const void *data,
+ int32_t data_size)
+{
+ CEPH_DATA(ceph_remove_fscrypt_key, ans, 1);
+ proxy_mount_t *mount;
+ uint32_t user;
+ int32_t err;
+
+ err = ptr_check(&client->random, req->remove_fscrypt_key.cmount,
+ (void **)&mount);
+ if ((err >= 0) &&
+ (req->remove_fscrypt_key.arg !=
+ sizeof(struct fscrypt_remove_key_arg))) {
+ err = proxy_log(LOG_ERR, EINVAL,
+ "Invalid size of key remove arg");
+ }
+ if (err >= 0) {
+ user = req->remove_fscrypt_key.user;
+
+ CEPH_BUFF_ADD(ans, data, sizeof(struct fscrypt_remove_key_arg));
+
+ err = ceph_remove_fscrypt_key(
+ proxy_cmount(mount),
+ (struct fscrypt_remove_key_arg *)data, user);
+ TRACE("remove_fscrypt_key(%p, %u) -> %d", mount, user, err);
+ }
+
+ return CEPH_COMPLETE(client, err, ans);
+}
+
+static int32_t libcephfsd_get_fscrypt_key_status(proxy_client_t *client,
+ proxy_req_t *req,
+ const void *data,
+ int32_t data_size)
+{
+ CEPH_DATA(ceph_get_fscrypt_key_status, ans, 1);
+ proxy_mount_t *mount;
+ int32_t err;
+
+ err = ptr_check(&client->random, req->get_fscrypt_key_status.cmount,
+ (void **)&mount);
+ if ((err >= 0) &&
+ (req->get_fscrypt_key_status.arg !=
+ sizeof(struct fscrypt_get_key_status_arg))) {
+ err = proxy_log(LOG_ERR, EINVAL,
+ "Invalid size of key status arg");
+ }
+ if (err >= 0) {
+ CEPH_BUFF_ADD(ans, data,
+ sizeof(struct fscrypt_get_key_status_arg));
+
+ err = ceph_get_fscrypt_key_status(
+ proxy_cmount(mount),
+ (struct fscrypt_get_key_status_arg *)data);
+ TRACE("get_fscrypt_key_status(%p) -> %d", mount, err);
+ }
+
+ return CEPH_COMPLETE(client, err, ans);
+}
+
+static int32_t libcephfsd_ll_set_fscrypt_policy_v2(proxy_client_t *client,
+ proxy_req_t *req,
+ const void *data,
+ int32_t data_size)
+{
+ CEPH_DATA(ceph_ll_set_fscrypt_policy_v2, ans, 0);
+ proxy_mount_t *mount;
+ Inode *inode;
+ int32_t err;
+
+ err = ptr_check(&client->random, req->ll_set_fscrypt_policy_v2.cmount,
+ (void **)&mount);
+ if (err >= 0) {
+ err = ptr_check(&client->random,
+ req->ll_set_fscrypt_policy_v2.inode,
+ (void **)&inode);
+ }
+ if ((err >= 0) &&
+ (req->ll_set_fscrypt_policy_v2.policy !=
+ sizeof(struct fscrypt_policy_v2))) {
+ err = proxy_log(LOG_ERR, EINVAL,
+ "Invalid size of fscrypt_policy_v2");
+ }
+ if (err >= 0) {
+ err = ceph_ll_set_fscrypt_policy_v2(proxy_cmount(mount), inode,
+ data);
+ TRACE("ll_set_fscrypt_policy_v2(%p) -> %d", mount, err);
+ }
+
+ return CEPH_COMPLETE(client, err, ans);
+}
+
+static int32_t libcephfsd_ll_get_fscrypt_policy_v2(proxy_client_t *client,
+ proxy_req_t *req,
+ const void *data,
+ int32_t data_size)
+{
+ CEPH_DATA(ceph_ll_get_fscrypt_policy_v2, ans, 1);
+ struct fscrypt_policy_v2 policy;
+ proxy_mount_t *mount;
+ Inode *inode;
+ int32_t err;
+
+ err = ptr_check(&client->random, req->ll_get_fscrypt_policy_v2.cmount,
+ (void **)&mount);
+ if (err >= 0) {
+ err = ptr_check(&client->random,
+ req->ll_get_fscrypt_policy_v2.inode,
+ (void **)&inode);
+ }
+ if ((err >= 0) &&
+ (req->ll_get_fscrypt_policy_v2.policy !=
+ sizeof(struct fscrypt_policy_v2))) {
+ err = proxy_log(LOG_ERR, EINVAL,
+ "Invalid size of fscrypt_policy_v2");
+ }
+ if (err >= 0) {
+ CEPH_BUFF_ADD(ans, &policy, sizeof(policy));
+
+ err = ceph_ll_get_fscrypt_policy_v2(proxy_cmount(mount), inode,
+ &policy);
+ TRACE("ll_get_fscrypt_policy_v2(%p) -> %d", mount, err);
+ }
+
+ return CEPH_COMPLETE(client, err, ans);
+}
+
+static int32_t libcephfsd_ll_is_encrypted(proxy_client_t *client,
+ proxy_req_t *req, const void *data,
+ int32_t data_size)
+{
+ CEPH_DATA(ceph_ll_is_encrypted, ans, 0);
+ proxy_mount_t *mount;
+ Inode *inode;
+ char *tag;
+ int32_t err;
+
+ err = ptr_check(&client->random, req->ll_is_encrypted.cmount,
+ (void **)&mount);
+ if (err >= 0) {
+ err = ptr_check(&client->random, req->ll_is_encrypted.inode,
+ (void **)&inode);
+ }
+ if (err >= 0) {
+ tag = (char *)CEPH_STR_GET(req->ll_is_encrypted, tag, data);
+
+ err = ceph_ll_is_encrypted(proxy_cmount(mount), inode, tag);
+ TRACE("ll_is_encrypted(%p) -> %d", mount, err);
+ }
+
+ return CEPH_COMPLETE(client, err, ans);
+}
+
static proxy_handler_t libcephfsd_handlers[LIBCEPHFSD_OP_TOTAL_OPS] = {
[LIBCEPHFSD_OP_VERSION] = libcephfsd_version,
[LIBCEPHFSD_OP_USERPERM_NEW] = libcephfsd_userperm_new,
[LIBCEPHFSD_OP_LL_RELEASEDIR] = libcephfsd_ll_releasedir,
[LIBCEPHFSD_OP_MOUNT_PERMS] = libcephfsd_mount_perms,
[LIBCEPHFSD_OP_LL_NONBLOCKING_RW] = libcephfsd_ll_nonblocking_rw,
+ [LIBCEPHFSD_OP_ADD_FSCRYPT_KEY] = libcephfsd_add_fscrypt_key,
+ [LIBCEPHFSD_OP_REMOVE_FSCRYPT_KEY] = libcephfsd_remove_fscrypt_key,
+ [LIBCEPHFSD_OP_GET_FSCRYPT_KEY_STATUS] =
+ libcephfsd_get_fscrypt_key_status,
+ [LIBCEPHFSD_OP_LL_SET_FSCRYPT_POLICY_V2] =
+ libcephfsd_ll_set_fscrypt_policy_v2,
+ [LIBCEPHFSD_OP_LL_GET_FSCRYPT_POLICY_V2] =
+ libcephfsd_ll_get_fscrypt_policy_v2,
+ [LIBCEPHFSD_OP_LL_IS_ENCRYPTED] = libcephfsd_ll_is_encrypted,
};
static void serve_binary(proxy_client_t *client)
LIBCEPHFSD_OP_LL_RELEASEDIR,
LIBCEPHFSD_OP_MOUNT_PERMS,
LIBCEPHFSD_OP_LL_NONBLOCKING_RW,
+ LIBCEPHFSD_OP_ADD_FSCRYPT_KEY,
+ LIBCEPHFSD_OP_REMOVE_FSCRYPT_KEY,
+ LIBCEPHFSD_OP_GET_FSCRYPT_KEY_STATUS,
+ LIBCEPHFSD_OP_LL_SET_FSCRYPT_POLICY_V2,
+ LIBCEPHFSD_OP_LL_GET_FSCRYPT_POLICY_V2,
+ LIBCEPHFSD_OP_LL_IS_ENCRYPTED,
/* Add more operations above this comment. */
)
);
+PROTO_CALL(ceph_add_fscrypt_key,
+ PROTO_REQ(
+ PROTO_VER(v0,
+ uint64_t cmount;
+ uint32_t user;
+ uint32_t kid;
+ uint16_t key;
+ )
+ ),
+ PROTO_ANS(
+ PROTO_VER(v0,
+ )
+ )
+);
+
+PROTO_CALL(ceph_remove_fscrypt_key,
+ PROTO_REQ(
+ PROTO_VER(v0,
+ uint64_t cmount;
+ uint32_t user;
+ uint32_t arg;
+ )
+ ),
+ PROTO_ANS(
+ PROTO_VER(v0,
+ )
+ )
+);
+
+PROTO_CALL(ceph_get_fscrypt_key_status,
+ PROTO_REQ(
+ PROTO_VER(v0,
+ uint64_t cmount;
+ uint32_t arg;
+ )
+ ),
+ PROTO_ANS(
+ PROTO_VER(v0,
+ )
+ )
+);
+
+PROTO_CALL(ceph_ll_set_fscrypt_policy_v2,
+ PROTO_REQ(
+ PROTO_VER(v0,
+ uint64_t cmount;
+ uint64_t inode;
+ uint32_t policy;
+ )
+ ),
+ PROTO_ANS(
+ PROTO_VER(v0,
+ )
+ )
+);
+
+PROTO_CALL(ceph_ll_get_fscrypt_policy_v2,
+ PROTO_REQ(
+ PROTO_VER(v0,
+ uint64_t cmount;
+ uint64_t inode;
+ uint32_t policy;
+ )
+ ),
+ PROTO_ANS(
+ PROTO_VER(v0,
+ )
+ )
+);
+
+PROTO_CALL(ceph_ll_is_encrypted,
+ PROTO_REQ(
+ PROTO_VER(v0,
+ uint64_t cmount;
+ uint64_t inode;
+ uint16_t tag;
+ )
+ ),
+ PROTO_ANS(
+ PROTO_VER(v0,
+ uint32_t policy;
+ )
+ )
+);
+
typedef union _proxy_req {
proxy_link_req_t header;
proxy_ceph_ll_releasedir_req_t ll_releasedir;
proxy_ceph_mount_perms_req_t mount_perms;
proxy_ceph_ll_nonblocking_readv_writev_req_t ll_nonblocking_rw;
+ proxy_ceph_add_fscrypt_key_req_t add_fscrypt_key;
+ proxy_ceph_remove_fscrypt_key_req_t remove_fscrypt_key;
+ proxy_ceph_get_fscrypt_key_status_req_t get_fscrypt_key_status;
+ proxy_ceph_ll_set_fscrypt_policy_v2_req_t ll_set_fscrypt_policy_v2;
+ proxy_ceph_ll_get_fscrypt_policy_v2_req_t ll_get_fscrypt_policy_v2;
+ proxy_ceph_ll_is_encrypted_req_t ll_is_encrypted;
} proxy_req_t;
PROTO_NOTIFY(ceph_ll_nonblocking_readv_writev,