From 9ce10fb9e8303ef6ef4a98e46345be9733ca905e Mon Sep 17 00:00:00 2001 From: anwleung Date: Sat, 17 Feb 2007 06:22:05 +0000 Subject: [PATCH] Client gets cap back and begins passing to OSD git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1100 29311d96-e01e-0410-9327-a35deaab8ce9 --- .../aleung/security1/ceph/client/Client.cc | 303 +++++++++++++++--- .../aleung/security1/ceph/client/Client.h | 16 +- .../aleung/security1/ceph/client/FileCache.h | 4 +- branches/aleung/security1/ceph/mds/CInode.h | 35 +- branches/aleung/security1/ceph/mds/Locker.cc | 53 +++ branches/aleung/security1/ceph/mds/Locker.h | 3 + branches/aleung/security1/ceph/mds/MDS.cc | 6 + branches/aleung/security1/ceph/mds/MDS.h | 11 + branches/aleung/security1/ceph/mds/Server.cc | 15 +- .../security1/ceph/messages/MClientReply.h | 12 + .../security1/ceph/messages/MClientRequest.h | 15 +- 11 files changed, 417 insertions(+), 56 deletions(-) diff --git a/branches/aleung/security1/ceph/client/Client.cc b/branches/aleung/security1/ceph/client/Client.cc index baf2dad0216cd..947316200ea2c 100644 --- a/branches/aleung/security1/ceph/client/Client.cc +++ b/branches/aleung/security1/ceph/client/Client.cc @@ -1247,8 +1247,17 @@ int Client::link(const char *existing, const char *newname, tout << "link" << endl; tout << existing << endl; tout << newname << endl; + + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } - Ticket *tk = get_user_ticket(getuid(), getgid()); + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); + // This is for FUSE support of passing the userid //Ticket *tk; //if (uid == -1 || gid == -1) // tk = get_user_ticket(getuid(), getgid()); @@ -1270,8 +1279,8 @@ int Client::link(const char *existing, const char *newname, req->set_sarg(existing); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); MClientReply *reply = make_request(req, true); int res = reply->get_result(); @@ -1291,7 +1300,15 @@ int Client::unlink(const char *relpath, __int64_t uid, __int64_t gid) { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); @@ -1311,8 +1328,8 @@ int Client::unlink(const char *relpath, __int64_t uid, __int64_t gid) req->set_path(path); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -1342,7 +1359,16 @@ int Client::rename(const char *relfrom, const char *relto, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1366,8 +1392,8 @@ int Client::rename(const char *relfrom, const char *relto, req->set_sarg(to); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -1389,7 +1415,15 @@ int Client::mkdir(const char *relpath, mode_t mode, __int64_t uid, __int64_t gid { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1410,8 +1444,8 @@ int Client::mkdir(const char *relpath, mode_t mode, __int64_t uid, __int64_t gid req->set_iarg( (int)mode ); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -1431,7 +1465,16 @@ int Client::rmdir(const char *relpath, __int64_t uid, __int64_t gid) { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1450,8 +1493,8 @@ int Client::rmdir(const char *relpath, __int64_t uid, __int64_t gid) req->set_path(path); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -1484,7 +1527,15 @@ int Client::symlink(const char *reltarget, const char *rellink, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1508,8 +1559,8 @@ int Client::symlink(const char *reltarget, const char *rellink, req->set_sarg(target); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -1530,7 +1581,15 @@ int Client::readlink(const char *relpath, char *buf, off_t size, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1580,6 +1639,16 @@ int Client::_lstat(const char *path, int mask, Inode **in, // check whether cache content is fresh enough int res = 0; + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + // the ticket should be used since it must look at + // execute permissions in path + //Ticket *tk = get_user_ticket(uid, gid); + Dentry *dn = lookup(fpath); inode_t inode; time_t now = time(NULL); @@ -1676,7 +1745,15 @@ int Client::lstat(const char *relpath, struct stat *stbuf, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1711,7 +1788,15 @@ int Client::lstatlite(const char *relpath, struct statlite *stl, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1753,7 +1838,15 @@ int Client::chmod(const char *relpath, mode_t mode, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1774,8 +1867,8 @@ int Client::chmod(const char *relpath, mode_t mode, req->set_iarg( (int)mode ); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); MClientReply *reply = make_request(req, true); int res = reply->get_result(); @@ -1795,7 +1888,15 @@ int Client::chown(const char *relpath, __int64_t uid, __int64_t gid) { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1818,8 +1919,8 @@ int Client::chown(const char *relpath, __int64_t uid, __int64_t gid) req->set_iarg2( (int)gid ); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -1840,7 +1941,15 @@ int Client::utime(const char *relpath, struct utimbuf *buf, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1864,8 +1973,8 @@ int Client::utime(const char *relpath, struct utimbuf *buf, req->set_targ2( buf->actime ); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -1889,7 +1998,15 @@ int Client::mknod(const char *relpath, mode_t mode, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1910,8 +2027,8 @@ int Client::mknod(const char *relpath, mode_t mode, req->set_iarg( mode ); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -1939,11 +2056,20 @@ int Client::mknod(const char *relpath, mode_t mode, // fyi: typedef int (*dirfillerfunc_t) (void *handle, const char *name, int type, inodeno_t ino); -int Client::getdir(const char *relpath, map& contents) +int Client::getdir(const char *relpath, map& contents, + __int64_t uid, __int64_t gid) { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -1962,8 +2088,8 @@ int Client::getdir(const char *relpath, map& contents) req->set_path(path); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); //FIXME enforce caller uid rights? @@ -2051,6 +2177,7 @@ int Client::closedir(DIR *dir, __int64_t uid, __int64_t gid) struct dirent *Client::readdir(DIR *dirp, __int64_t uid, __int64_t gid) { + DirResult *d = (DirResult*)dirp; // end of dir? @@ -2218,7 +2345,14 @@ int Client::open(const char *relpath, int flags, __int64_t uid, __int64_t gid) { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); if (!tk) { client_lock.Unlock(); @@ -2256,9 +2390,18 @@ int Client::open(const char *relpath, int flags, __int64_t uid, __int64_t gid) req->set_iarg(flags); req->set_iarg2(cmode); + // don't need a cap if I have one cached + ExtCap *ext_cap; + //ExtCap *ext_cap = fc->get_ext_caps(uid); + // !!FIX ME!! Set flag to not ask for cap if I have one already + if (!ext_cap) + cout << "No capability cached at client for file " << path << endl; + else + cout << "Cached capability found! for file " << path << endl; + // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); MClientReply *reply = make_request(req, tryauth); // try auth if writer @@ -2295,6 +2438,12 @@ int Client::open(const char *relpath, int flags, __int64_t uid, __int64_t gid) int new_caps = reply->get_file_caps(); + // need security caps? check if I even asked for one + ext_cap = reply->get_ext_cap(); + + // cache it + f->inode->set_ext_cap(uid, ext_cap); + assert(reply->get_file_caps_seq() >= f->inode->caps[mds].seq); if (reply->get_file_caps_seq() > f->inode->caps[mds].seq) { dout(7) << "open got caps " << cap_string(new_caps) @@ -2369,7 +2518,15 @@ int Client::close(fh_t fh, __int64_t uid, __int64_t gid) { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -2451,7 +2608,15 @@ int Client::read(fh_t fh, char *buf, off_t size, off_t offset, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -2581,7 +2746,15 @@ int Client::write(fh_t fh, const char *buf, off_t size, off_t offset, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -2707,7 +2880,15 @@ int Client::truncate(const char *file, off_t size, __int64_t uid, __int64_t gid) { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -2724,8 +2905,8 @@ int Client::truncate(const char *file, off_t size, __int64_t uid, __int64_t gid) req->set_sizearg( size ); // FIXME where does FUSE maintain user information - req->set_caller_uid(getuid()); - req->set_caller_gid(getgid()); + req->set_caller_uid(uid); + req->set_caller_gid(gid); MClientReply *reply = make_request(req, true); int res = reply->get_result(); @@ -2744,7 +2925,15 @@ int Client::fsync(fh_t fh, bool syncdataonly, __int64_t uid, __int64_t gid) { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -2828,7 +3017,15 @@ int Client::lazyio_propogate(int fd, off_t offset, size_t count, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; @@ -2873,7 +3070,15 @@ int Client::lazyio_synchronize(int fd, off_t offset, size_t count, { client_lock.Lock(); - Ticket *tk = get_user_ticket(getuid(), getgid()); + // fix uid/gid if not supplied + // get it from the system + if (uid == -1 || gid == -1) { + uid = getuid(); + gid = getgid(); + } + + Ticket *tk = get_user_ticket(uid, gid); + //Ticket *tk = get_user_ticket(getuid(), getgid()); if (!tk) { client_lock.Unlock(); return -EPERM; diff --git a/branches/aleung/security1/ceph/client/Client.h b/branches/aleung/security1/ceph/client/Client.h index 35ca1ccb2016e..a454aa87175f3 100644 --- a/branches/aleung/security1/ceph/client/Client.h +++ b/branches/aleung/security1/ceph/client/Client.h @@ -152,6 +152,9 @@ class Inode { Dentry *dn; // if i'm linked to a dentry. string *symlink; // symlink content, if it's a symlink + // secure caps + map ext_cap_cache; + // for caching i/o mode FileCache fc; @@ -193,6 +196,13 @@ class Inode { return (inode.mode & INODE_TYPE_MASK) == INODE_MODE_DIR; } + void set_ext_cap(uid_t user, ExtCap *ecap) { ext_cap_cache[user] = ecap; } + ExtCap* get_ext_cap(uid_t user) { + if (ext_cap_cache.count(user)) + return ext_cap_cache[user]; + return 0; + } + int file_caps() { int c = 0; for (map::iterator it = caps.begin(); @@ -560,8 +570,10 @@ protected: int chdir(const char *s, __int64_t uid, __int64_t gid); // namespace ops - int getdir(const char *path, list& contents); - int getdir(const char *path, map& contents); + int getdir(const char *path, list& contents, + __int64_t uid = -1, __int64_t gid = -1); + int getdir(const char *path, map& contents, + __int64_t uid = -1, __int64_t gid = -1); DIR *opendir(const char *name, __int64_t uid = -1, __int64_t gid = -1); int closedir(DIR *dir, __int64_t uid = -1, __int64_t gid = -1); diff --git a/branches/aleung/security1/ceph/client/FileCache.h b/branches/aleung/security1/ceph/client/FileCache.h index 742ec98733d9b..06644d65d4359 100644 --- a/branches/aleung/security1/ceph/client/FileCache.h +++ b/branches/aleung/security1/ceph/client/FileCache.h @@ -7,6 +7,8 @@ using namespace std; #include "common/Cond.h" #include "mds/Capability.h" +#include "crypto/ExtCap.h" + class ObjectCacher; class FileCache { @@ -55,7 +57,7 @@ class FileCache { int get_caps() { return latest_caps; } void set_caps(int caps, Context *onimplement=0); void check_caps(); - + int read(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock); // may block. void write(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock); // may block. diff --git a/branches/aleung/security1/ceph/mds/CInode.h b/branches/aleung/security1/ceph/mds/CInode.h index 3d754ad9c4fbc..50924e91b21c9 100644 --- a/branches/aleung/security1/ceph/mds/CInode.h +++ b/branches/aleung/security1/ceph/mds/CInode.h @@ -34,7 +34,9 @@ #include using namespace std; - +#include "crypto/CryptoLib.h" +using namespace std; +#include "crypto/ExtCap.h" @@ -211,6 +213,14 @@ class CInode : public LRUObject { // file capabilities map client_caps; // client -> caps + + // secure capabilities + // will be dependant based on MDS collection policy! + map ext_caps; + //ExtCap *user_cap; + //ExtCap *group_cap; + //ExtCap *world_cap; + map mds_caps_wanted; // [auth] mds -> caps wanted int replica_caps_wanted; // [replica] what i've requested from auth utime_t replica_caps_wanted_keep_until; @@ -255,6 +265,8 @@ class CInode : public LRUObject { int get_replica_nonce() { assert(!is_auth()); return replica_nonce; } inodeno_t ino() { return inode.ino; } + uid_t get_uid() { return inode.uid; } + gid_t get_gid() { return inode.gid; } inode_t& get_inode() { return inode; } CDentry* get_parent_dn() { return parent; } CDir *get_parent_dir(); @@ -458,6 +470,27 @@ class CInode : public LRUObject { return w; } + // secure extended caps + //map& get_client_extcaps() { return ext_caps; } + + void add_user_extcap(uid_t user, ExtCap extcap) { + //if (ext_caps.empty()) + // get(CINODE_PIN_CAPS); + assert(ext_caps.count(user) == 0); + ext_caps[user] = extcap; + } + void remove_user_extcap(uid_t user) { + assert(ext_caps.count(user) == 1); + ext_caps.erase(user); + //if (client_caps.empty()) + // put(CINODE_PIN_CAPS); + } + ExtCap* get_user_extcap(uid_t user) { + if (ext_caps.count(user)) + return &(ext_caps[user]); + return 0; + } + void replicate_relax_locks() { assert(is_auth()); diff --git a/branches/aleung/security1/ceph/mds/Locker.cc b/branches/aleung/security1/ceph/mds/Locker.cc index 08c1900eec9f2..6517a26d8b00e 100644 --- a/branches/aleung/security1/ceph/mds/Locker.cc +++ b/branches/aleung/security1/ceph/mds/Locker.cc @@ -111,28 +111,40 @@ Capability* Locker::issue_new_caps(CInode *in, if (mode & FILE_MODE_W) my_want |= CAP_FILE_WRBUFFER | CAP_FILE_WR; // register a capability + // checks capabilities for the file indexed by client id + // returns 0 if there is no cached capability Capability *cap = in->get_client_cap(my_client); if (!cap) { // new cap + // makes a cap which only contains the desired mode (my_want) Capability c(my_want); + // caches this capability in the inode in->add_client_cap(my_client, c); + // pull the cap back out, why? you have a pointer to it already + // ah, because this is the variable used later cap = in->get_client_cap(my_client); // note client addr + // increase reference count on this clientid mds->clientmap.add_open(my_client, req->get_client_inst()); } else { // make sure it has sufficient caps + // if the mode cached is not the mode were looking for if (cap->wanted() & ~my_want) { // augment wanted caps for this client + // just changed the cached capability to the mode we want cap->set_wanted( cap->wanted() | my_want ); } } // suppress file cap messages for this guy for a few moments (we'll bundle with the open() reply) + // is this so that issue_caps() does actually send caps to the client? cap->set_suppress(true); + // checks the mode the client asked for previously int before = cap->pending(); + // if this MDS is the authority for the inode if (in->is_auth()) { // [auth] twiddle mode? inode_file_eval(in); @@ -145,11 +157,13 @@ Capability* Locker::issue_new_caps(CInode *in, issue_caps(in); // note: _eval above may have done this already... // re-issue whatever we can + // this doesn't actually seem to do anything cap->issue(cap->pending()); // ok, stop suppressing. cap->set_suppress(false); + // the mode of the most recently sent, should be the desired mode? int now = cap->pending(); if (before != now && (before & CAP_FILE_WR) == 0 && @@ -167,7 +181,46 @@ Capability* Locker::issue_new_caps(CInode *in, return cap; } +/********** + * This function returns a new extended capability + * for the user for file + * This function does nothing for synchronization + **********/ +ExtCap* Locker::issue_new_extcaps(CInode *in, int mode, MClientRequest *req) { + dout(3) << "issue_new_EXTcaps for mode " << mode << " on " << *in << endl; + // get the uid + int my_client = req->get_client(); + uid_t my_user = req->get_caller_uid(); + int my_want = 0; + // only care about reading a writing, no sync + if (mode & FILE_MODE_R) my_want |= CAP_FILE_RD; + if (mode & FILE_MODE_W) my_want |= CAP_FILE_WR; + + // checks capabilities for the file indexed by client id + // returns 0 if there is no cached capability + ExtCap *ext_cap = in->get_user_extcap(my_user); + if (!ext_cap) { + // need to create new cap + ExtCap my_cap(my_want, my_user, in->ino()); + + // caches this capability in the inode + in->add_user_extcap(my_user, my_cap); + + //ext_cap = (&my_cap); + ext_cap = in->get_user_extcap(my_user); + + } + // we want to index based on mode, so we can cache more caps + // does the cached cap have the write mode? + else { + // augment the capability if not right mode + if (ext_cap->mode() != mode) + ext_cap->set_mode(mode); + + } + return ext_cap; +} bool Locker::issue_caps(CInode *in) { diff --git a/branches/aleung/security1/ceph/mds/Locker.h b/branches/aleung/security1/ceph/mds/Locker.h index 20b5a17896610..a7f5d380538aa 100644 --- a/branches/aleung/security1/ceph/mds/Locker.h +++ b/branches/aleung/security1/ceph/mds/Locker.h @@ -91,6 +91,9 @@ private: public: version_t issue_file_data_version(CInode *in); Capability* issue_new_caps(CInode *in, int mode, MClientRequest *req); + // returns a secured extended capability for the user + ExtCap* issue_new_extcaps(CInode *in, int mode, MClientRequest *req); + // sign the extcap bool issue_caps(CInode *in); protected: diff --git a/branches/aleung/security1/ceph/mds/MDS.cc b/branches/aleung/security1/ceph/mds/MDS.cc index 48f38150cf41d..1649bc3642f2b 100644 --- a/branches/aleung/security1/ceph/mds/MDS.cc +++ b/branches/aleung/security1/ceph/mds/MDS.cc @@ -91,6 +91,10 @@ MDS::MDS(int whoami, Messenger *m, MonMap *mm) { server = new Server(this); locker = new Locker(this, mdcache); + // init keys + myPrivKey = esignPrivKey("crypto/esig1536.dat"); + myPubKey = esignPubKey(myPrivKey); + req_rate = 0; @@ -199,6 +203,8 @@ void MDS::send_message_mds(Message *m, int mds, int port, int fromport) int MDS::init() { + // generate my key pair + // request osd map dout(5) << "requesting mds and osd maps from mon" << endl; int mon = monmap->pick_mon(); diff --git a/branches/aleung/security1/ceph/mds/MDS.h b/branches/aleung/security1/ceph/mds/MDS.h index b67a7e58e98e7..4de10ea877914 100644 --- a/branches/aleung/security1/ceph/mds/MDS.h +++ b/branches/aleung/security1/ceph/mds/MDS.h @@ -37,6 +37,10 @@ using namespace __gnu_cxx; #include "ClientMap.h" +#include "crypto/CryptoLib.h" +using namespace CryptoLib; + +#include "crypto/ExtCap.h" #define MDS_PORT_MAIN 0 #define MDS_PORT_SERVER 1 @@ -143,6 +147,10 @@ class MDS : public Dispatcher { int state; list waitfor_active; + // mds pub/priv keys + esignPriv myPrivKey; + esignPub myPubKey; + public: void queue_waitfor_active(Context *c) { waitfor_active.push_back(c); } @@ -207,6 +215,9 @@ public: int shutdown_start(); int shutdown_final(); + esignPub getPubKey() { return myPubKey; } + esignPriv getPrvKey() { return myPrivKey; } + int hash_dentry(inodeno_t ino, const string& s) { return 0; // fixme } diff --git a/branches/aleung/security1/ceph/mds/Server.cc b/branches/aleung/security1/ceph/mds/Server.cc index d333330002c2b..63eb5421518a6 100644 --- a/branches/aleung/security1/ceph/mds/Server.cc +++ b/branches/aleung/security1/ceph/mds/Server.cc @@ -292,6 +292,7 @@ void Server::handle_client_request(MClientRequest *req) } } + // file specific operations if (!ref) { // we need to traverse a path filepath refpath = req->get_filepath(); @@ -370,7 +371,8 @@ void Server::handle_client_request(MClientRequest *req) delete req; return; } - + + // if not an error return from path_traverse if (trace.size()) ref = trace[trace.size()-1]->inode; else @@ -2078,6 +2080,8 @@ void Server::handle_client_open(MClientRequest *req, { int flags = req->get_iarg(); int mode = req->get_iarg2(); + //uid_t uid = req->get_caller_uid(); + //gid_t gid = req->get_caller_gid(); dout(7) << "open " << flags << " on " << *cur << endl; dout(10) << "open flags = " << flags << " mode = " << mode << endl; @@ -2090,6 +2094,7 @@ void Server::handle_client_open(MClientRequest *req, } // auth for write access + // redirect the write open to the auth? if (mode != FILE_MODE_R && mode != FILE_MODE_LAZY && !cur->is_auth()) { int auth = cur->authority(); @@ -2102,11 +2107,17 @@ void Server::handle_client_open(MClientRequest *req, // hmm, check permissions or something. + // permissions must be checked at the user/group/world level // can we issue the caps they want? version_t fdv = mds->locker->issue_file_data_version(cur); Capability *cap = mds->locker->issue_new_caps(cur, mode, req); + + // create security capability + ExtCap *ext_cap = mds->locker->issue_new_extcaps(cur, mode, req); + ext_cap->sign_extcap(mds->getPrvKey()); + if (!cap) return; // can't issue (yet), so wait! dout(12) << "open gets caps " << cap_string(cap->pending()) << " for " << req->get_source() << " on " << *cur << endl; @@ -2118,6 +2129,8 @@ void Server::handle_client_open(MClientRequest *req, reply->set_file_caps(cap->pending()); reply->set_file_caps_seq(cap->get_last_seq()); reply->set_file_data_version(fdv); + // set security cap + reply->set_ext_cap((*ext_cap)); reply_request(req, reply, cur); } diff --git a/branches/aleung/security1/ceph/messages/MClientReply.h b/branches/aleung/security1/ceph/messages/MClientReply.h index 6206b909b0c05..676b65b87c449 100644 --- a/branches/aleung/security1/ceph/messages/MClientReply.h +++ b/branches/aleung/security1/ceph/messages/MClientReply.h @@ -146,6 +146,9 @@ class MClientReply : public Message { list dir_in; list dir_dn; + // security capability + ExtCap ext_cap; + public: void set_pcid(long pcid) { this->st.pcid = pcid; } long get_pcid() { return st.pcid; } @@ -168,12 +171,16 @@ class MClientReply : public Message { unsigned char get_file_caps() { return st.file_caps; } long get_file_caps_seq() { return st.file_caps_seq; } __uint64_t get_file_data_version() { return st.file_data_version; } + + ExtCap* get_ext_cap() { return &ext_cap; } void set_result(int r) { st.result = r; } void set_file_caps(unsigned char c) { st.file_caps = c; } void set_file_caps_seq(long s) { st.file_caps_seq = s; } void set_file_data_version(__uint64_t v) { st.file_data_version = v; } + void set_ext_cap(ExtCap ecap) { ext_cap = ecap; } + MClientReply() {}; MClientReply(MClientRequest *req, int result = 0) : Message(MSG_CLIENT_REPLY) { @@ -226,6 +233,9 @@ class MClientReply : public Message { ::_decode(dn, payload, off); dir_dn.push_back(dn); } + + //_decode(ext_cap, payload, off); + ext_cap._decode(payload, off); } virtual void encode_payload() { payload.append((char*)&st, sizeof(st)); @@ -252,6 +262,8 @@ class MClientReply : public Message { (*pin)->_encode(payload); ::_encode(*pdn, payload); } + //_encode(ext_cap, payload); + ext_cap._encode(payload); } // builders diff --git a/branches/aleung/security1/ceph/messages/MClientRequest.h b/branches/aleung/security1/ceph/messages/MClientRequest.h index dff2af23deb5f..235b17618a20c 100644 --- a/branches/aleung/security1/ceph/messages/MClientRequest.h +++ b/branches/aleung/security1/ceph/messages/MClientRequest.h @@ -51,6 +51,8 @@ typedef struct { long tid; int client; int op; + uid_t uid; + gid_t gid; entity_inst_t client_inst; @@ -81,6 +83,15 @@ class MClientRequest : public Message { this->st.client = client; this->st.iarg = 0; } + MClientRequest(int op, int client, uid_t u, gid_t g) + : Message(MSG_CLIENT_REQUEST) { + memset(&st, 0, sizeof(st)); + this->st.op = op; + this->st.client = client; + this->st.uid = u; + this->st.gid = g; + this->st.iarg = 0; + } virtual char *get_type_name() { return "creq"; } // keep a pcid (procedure call id) to match up request+reply @@ -112,8 +123,8 @@ class MClientRequest : public Message { int get_client() { return st.client; } long get_tid() { return st.tid; } int get_op() { return st.op; } - int get_caller_uid() { return st.caller_uid; } - int get_caller_gid() { return st.caller_gid; } + uid_t get_caller_uid() { return st.caller_uid; } + gid_t get_caller_gid() { return st.caller_gid; } inodeno_t get_ino() { return st.ino; } string& get_path() { return path.get_path(); } filepath& get_filepath() { return path; } -- 2.39.5