From 83e1102a9639ec70b55c6d0339587d3266af0e8b Mon Sep 17 00:00:00 2001 From: sageweil Date: Thu, 1 Feb 2007 23:36:57 +0000 Subject: [PATCH] client blocking to get a user ticket git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1072 29311d96-e01e-0410-9327-a35deaab8ce9 --- .../aleung/security1/ceph/client/Client.cc | 235 +++++++++++++++++- .../aleung/security1/ceph/client/Client.h | 12 + .../aleung/security1/ceph/crypto/Ticket.h | 2 +- .../security1/ceph/messages/MClientAuthUser.h | 34 ++- .../ceph/messages/MClientAuthUserAck.h | 3 +- .../security1/ceph/messages/MClientUserAuth.h | 54 ---- 6 files changed, 270 insertions(+), 70 deletions(-) delete mode 100644 branches/aleung/security1/ceph/messages/MClientUserAuth.h diff --git a/branches/aleung/security1/ceph/client/Client.cc b/branches/aleung/security1/ceph/client/Client.cc index 5f230e23e40b2..9a8374b41ecbb 100644 --- a/branches/aleung/security1/ceph/client/Client.cc +++ b/branches/aleung/security1/ceph/client/Client.cc @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef DARWIN #include @@ -39,6 +40,9 @@ using namespace std; #include "messages/MClientMountAck.h" #include "messages/MClientFileCaps.h" +#include "messages/MClientAuthUser.h" +#include "messages/MClientAuthUserAck.h" + #include "messages/MGenericMessage.h" #include "messages/MMDSGetMap.h" @@ -52,6 +56,7 @@ using namespace std; #include "common/Mutex.h" #include "common/Logger.h" +#include "crypto/Ticket.h" #include "config.h" #undef dout @@ -455,11 +460,7 @@ Dentry *Client::lookup(filepath& path) // ------- -UserCert *Client::get_user_cert(int uid) -{ - -} MClientReply *Client::make_request(MClientRequest *req, bool auth_best, @@ -632,6 +633,65 @@ void Client::handle_client_reply(MClientReply *reply) } +void Client::handle_auth_user_ack(MClientAuthUserAck *m) +{ + uid_t uid = m->get_uid(); + dout(10) << "handle_auth_user_ack for " << uid << endl; + + // put the ticket in the ticket map + // ** + + // wait up the waiter(s) + for (list::iterator p = ticket_waiter_cond[uid].begin(); + p != ticket_waiter_cond[uid].end(); + ++p) + (*p)->Signal(); + ticket_waiter_cond.erase(uid); +} + +Ticket *Client::get_user_ticket(uid_t uid, gid_t gid) +{ + // do we already have it? + if (user_ticket.count(uid) == 0) { + Cond cond; + string username; // i don't know! + string key; // ... + + if (ticket_waiter_cond.count(uid) == 0) { + // request from monitor + int mon = monmap->pick_mon(); + dout(10) << "get_user_ticket requesting ticket for uid " << uid + << " from mon" << mon << endl; + messenger->send_message(new MClientAuthUser(username, uid, gid, key), + MSG_ADDR_MON(mon), monmap->get_inst(mon)); + } else { + // don't request, someone else already did. just wait! + dout(10) << "get_user_ticket waiting for ticket for uid " << uid << endl; + } + + // wait for reply + ticket_waiter_cond[uid].push_back( &cond ); + + // naively assume we'll get a ticket FIXME + while (user_ticket.count(uid) == 0) + cond.Wait(client_lock); + } + + // inc ref count + user_ticket_ref[uid]++; + return user_ticket[uid]; +} + +void Client::put_user_ticket(Ticket *tk) +{ + // dec ref count + uid_t uid = tk->get_uid(); + user_ticket_ref[uid]--; + if (user_ticket_ref[uid] == 0) + user_ticket_ref.erase(uid); +} + + // ------------------------ // incoming messages @@ -653,6 +713,10 @@ void Client::dispatch(Message *m) case MSG_MDS_MAP: handle_mds_map((MMDSMap*)m); break; + + case MSG_CLIENT_AUTH_USER_ACK: + handle_auth_user_ack((MClientAuthUserAck*)m); + break; case MSG_CLIENT_REPLY: handle_client_reply((MClientReply*)m); @@ -1154,6 +1218,12 @@ int Client::link(const char *existing, const char *newname) tout << existing << endl; tout << newname << endl; + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + // main path arg is new link name // sarg is target (existing file) @@ -1174,6 +1244,7 @@ int Client::link(const char *existing, const char *newname) delete reply; dout(10) << "link result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1184,6 +1255,12 @@ int Client::unlink(const char *relpath) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1217,6 +1294,7 @@ int Client::unlink(const char *relpath) delete reply; dout(10) << "unlink result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1226,6 +1304,12 @@ int Client::rename(const char *relfrom, const char *relto) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string absfrom; mkabspath(relfrom, absfrom); const char *from = absfrom.c_str(); @@ -1255,6 +1339,7 @@ int Client::rename(const char *relfrom, const char *relto) delete reply; dout(10) << "rename result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1266,6 +1351,12 @@ int Client::mkdir(const char *relpath, mode_t mode) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1292,6 +1383,7 @@ int Client::mkdir(const char *relpath, mode_t mode) delete reply; dout(10) << "mkdir result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1300,6 +1392,12 @@ int Client::mkdir(const char *relpath, mode_t mode) int Client::rmdir(const char *relpath) { client_lock.Lock(); + + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } string abspath; mkabspath(relpath, abspath); @@ -1335,6 +1433,7 @@ int Client::rmdir(const char *relpath) delete reply; dout(10) << "rmdir result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1346,6 +1445,12 @@ int Client::symlink(const char *reltarget, const char *rellink) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abstarget; mkabspath(reltarget, abstarget); const char *target = abstarget.c_str(); @@ -1375,6 +1480,7 @@ int Client::symlink(const char *reltarget, const char *rellink) delete reply; dout(10) << "symlink result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1384,6 +1490,12 @@ int Client::readlink(const char *relpath, char *buf, off_t size) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1409,6 +1521,7 @@ int Client::readlink(const char *relpath, char *buf, off_t size) if (res > size) res = size; memcpy(buf, in->symlink->c_str(), res); + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; // return length in bytes (to mimic the system call) @@ -1521,6 +1634,12 @@ int Client::lstat(const char *relpath, struct stat *stbuf) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1538,6 +1657,7 @@ int Client::lstat(const char *relpath, struct stat *stbuf) dout(10) << "stat sez size = " << in->inode.size << " ino = " << stbuf->st_ino << endl; } + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1548,6 +1668,12 @@ int Client::lstatlite(const char *relpath, struct statlite *stl) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1571,6 +1697,7 @@ int Client::lstatlite(const char *relpath, struct statlite *stl) dout(10) << "stat sez size = " << in->inode.size << " ino = " << in->inode.ino << endl; } + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1582,6 +1709,12 @@ int Client::chmod(const char *relpath, mode_t mode) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1606,6 +1739,7 @@ int Client::chmod(const char *relpath, mode_t mode) delete reply; dout(10) << "chmod result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1615,6 +1749,12 @@ int Client::chown(const char *relpath, uid_t uid, gid_t gid) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1643,6 +1783,7 @@ int Client::chown(const char *relpath, uid_t uid, gid_t gid) delete reply; dout(10) << "chown result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1652,6 +1793,12 @@ int Client::utime(const char *relpath, struct utimbuf *buf) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1681,6 +1828,7 @@ int Client::utime(const char *relpath, struct utimbuf *buf) delete reply; dout(10) << "utime result is " << res << endl; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1693,14 +1841,16 @@ int Client::mknod(const char *relpath, mode_t mode) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); - UserCert *uc = get_user_cert(getuid(), getgid()); - // do work - put_user_cert(uc); - dout(3) << "op: client->mknod(\"" << path << "\", " << mode << ");" << endl; tout << "mknod" << endl; tout << path << endl; @@ -1725,6 +1875,7 @@ int Client::mknod(const char *relpath, mode_t mode) delete reply; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); return res; @@ -1744,6 +1895,12 @@ int Client::getdir(const char *relpath, map& contents) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -1812,6 +1969,7 @@ int Client::getdir(const char *relpath, map& contents) delete reply; //fix thing above first + put_user_ticket(tk); client_lock.Unlock(); return res; } @@ -2011,6 +2169,12 @@ int Client::open(const char *relpath, int flags) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + string abspath; mkabspath(relpath, abspath); const char *path = abspath.c_str(); @@ -2118,6 +2282,7 @@ int Client::open(const char *relpath, int flags) delete reply; + put_user_ticket(tk); trim_cache(); client_lock.Unlock(); @@ -2153,6 +2318,13 @@ void Client::close_safe(Inode *in) int Client::close(fh_t fh) { client_lock.Lock(); + + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + dout(3) << "op: client->close(open_files[ " << fh << " ]);" << endl; dout(3) << "op: open_files.erase( " << fh << " );" << endl; tout << "close" << endl; @@ -2212,6 +2384,7 @@ int Client::close(fh_t fh) put_inode( in ); int result = 0; + put_user_ticket(tk); client_lock.Unlock(); return result; } @@ -2227,6 +2400,12 @@ int Client::read(fh_t fh, char *buf, off_t size, off_t offset) { client_lock.Lock(); + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + dout(3) << "op: client->read(" << fh << ", buf, " << size << ", " << offset << "); // that's " << offset << "~" << size << endl; tout << "read" << endl; tout << fh << endl; @@ -2313,6 +2492,7 @@ int Client::read(fh_t fh, char *buf, off_t size, off_t offset) dout(10) << "read rvalue " << rvalue << ", r " << r << endl; // done! + put_user_ticket(tk); client_lock.Unlock(); return rvalue; } @@ -2349,6 +2529,12 @@ 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()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + //dout(7) << "write fh " << fh << " size " << size << " offset " << offset << endl; dout(3) << "op: client->write(" << fh << ", buf, " << size << ", " << offset << ");" << endl; tout << "write" << endl; @@ -2459,6 +2645,7 @@ int Client::write(fh_t fh, const char *buf, off_t size, off_t offset) in->file_wr_mtime = in->inode.mtime = g_clock.gettime(); // ok! + put_user_ticket(tk); client_lock.Unlock(); return totalwritten; } @@ -2467,6 +2654,13 @@ int Client::write(fh_t fh, const char *buf, off_t size, off_t offset) int Client::truncate(const char *file, off_t size) { client_lock.Lock(); + + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + dout(3) << "op: client->truncate(\"" << file << "\", " << size << ");" << endl; tout << "truncate" << endl; tout << file << endl; @@ -2488,6 +2682,7 @@ int Client::truncate(const char *file, off_t size) dout(10) << " truncate result is " << res << endl; + put_user_ticket(tk); client_lock.Unlock(); return res; } @@ -2496,6 +2691,13 @@ int Client::truncate(const char *file, off_t size) int Client::fsync(fh_t fh, bool syncdataonly) { client_lock.Lock(); + + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + dout(3) << "op: client->fsync(open_files[ " << fh << " ], " << syncdataonly << ");" << endl; tout << "fsync" << endl; tout << fh << endl; @@ -2523,6 +2725,7 @@ int Client::fsync(fh_t fh, bool syncdataonly) while (!done) cond.Wait(client_lock); } + put_user_ticket(tk); client_lock.Unlock(); return r; } @@ -2569,6 +2772,13 @@ int Client::statfs(const char *path, struct statfs *stbuf) int Client::lazyio_propogate(int fd, off_t offset, size_t count) { client_lock.Lock(); + + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + dout(3) << "op: client->lazyio_propogate(" << fd << ", " << offset << ", " << count << ")" << endl; @@ -2598,6 +2808,7 @@ int Client::lazyio_propogate(int fd, off_t offset, size_t count) } } + put_user_ticket(tk); client_lock.Unlock(); return 0; } @@ -2605,6 +2816,13 @@ int Client::lazyio_propogate(int fd, off_t offset, size_t count) int Client::lazyio_synchronize(int fd, off_t offset, size_t count) { client_lock.Lock(); + + Ticket *tk = get_user_ticket(getuid(), getgid()); + if (!tk) { + client_lock.Unlock(); + return -EPERM; + } + dout(3) << "op: client->lazyio_synchronize(" << fd << ", " << offset << ", " << count << ")" << endl; @@ -2629,6 +2847,7 @@ int Client::lazyio_synchronize(int fd, off_t offset, size_t count) } } + put_user_ticket(tk); client_lock.Unlock(); return 0; } diff --git a/branches/aleung/security1/ceph/client/Client.h b/branches/aleung/security1/ceph/client/Client.h index f1d90232acc18..59ac39366a1c4 100644 --- a/branches/aleung/security1/ceph/client/Client.h +++ b/branches/aleung/security1/ceph/client/Client.h @@ -53,6 +53,7 @@ using namespace __gnu_cxx; class Filer; class Objecter; class ObjectCacher; +class Ticket; extern class LogType client_logtype; extern class Logger *client_logger; @@ -482,6 +483,14 @@ protected: void fill_stat(inode_t& inode, struct stat *st); void fill_statlite(inode_t& inode, struct statlite *st); + // security + map user_ticket; + map user_ticket_ref; + map > ticket_waiter_cond; + + Ticket *get_user_ticket(uid_t uid, gid_t gid); + void put_user_ticket(Ticket *tk); + // friends friend class SyntheticClient; @@ -503,6 +512,9 @@ protected: void handle_unmount_ack(Message*); void handle_mds_map(class MMDSMap *m); + // user tickets + void handle_auth_user_ack(class MClientAuthUserAck *m); + // file caps void handle_file_caps(class MClientFileCaps *m); void implemented_caps(class MClientFileCaps *m, Inode *in); diff --git a/branches/aleung/security1/ceph/crypto/Ticket.h b/branches/aleung/security1/ceph/crypto/Ticket.h index 891e95b871c2e..e1fb14793a049 100644 --- a/branches/aleung/security1/ceph/crypto/Ticket.h +++ b/branches/aleung/security1/ceph/crypto/Ticket.h @@ -93,6 +93,6 @@ public: //bl.append((char*)&uid,sizeof(uid)); //bl.copy(off,sizeof(uid),(char*)&uid); //off += sizeof(uid); -} +}; #endif diff --git a/branches/aleung/security1/ceph/messages/MClientAuthUser.h b/branches/aleung/security1/ceph/messages/MClientAuthUser.h index cd1d3fbde82ae..8fc74d8bd3ea0 100644 --- a/branches/aleung/security1/ceph/messages/MClientAuthUser.h +++ b/branches/aleung/security1/ceph/messages/MClientAuthUser.h @@ -18,17 +18,39 @@ #include "msg/Message.h" class MClientAuthUser : public Message { - + string username; + uid_t uid; + gid_t gid; + string pubKey; + public: - MClientAuthUser() : Message(MSG_CLIENT_AUTH_USER) { - } + MClientAuthUser() : Message(MSG_CLIENT_AUTH_USER) {} + MClientAuthUser(string un, uid_t u, gid_t g, string k) : + Message(MSG_CLIENT_AUTH_USER), username(un), uid(u), gid(g), pubKey(k) { } char *get_type_name() { return "client_auth_user"; } - - void decode_payload() { + const string& get_str_key() { return pubKey; } + //esignPub get_key() { return _fromString_esignPubKey(pubKey); } + string get_username() { return username; } + uid_t get_uid() { return uid; } + gid_t get_gid() { return gid; } + + virtual void decode_payload() { + int off = 0; + payload.copy(off, sizeof(uid), (char*)&uid); + off += sizeof(uid); + payload.copy(off, sizeof(gid), (char*)&gid); + off += sizeof(gid); + _decode(username, payload, off); + _decode(pubKey, payload, off); } - void encode_payload() { + virtual void encode_payload() { + payload.append((char*)&uid, sizeof(uid)); + payload.append((char*)&gid, sizeof(gid)); + _encode(username, payload); + _encode(pubKey, payload); } + }; #endif diff --git a/branches/aleung/security1/ceph/messages/MClientAuthUserAck.h b/branches/aleung/security1/ceph/messages/MClientAuthUserAck.h index c6c47cd75eeef..af16d1e6ee296 100644 --- a/branches/aleung/security1/ceph/messages/MClientAuthUserAck.h +++ b/branches/aleung/security1/ceph/messages/MClientAuthUserAck.h @@ -18,13 +18,14 @@ #include "msg/Message.h" class MClientAuthUserAck : public Message { - public: MClientAuthUserAck() : Message(MSG_CLIENT_AUTH_USER_ACK) { } char *get_type_name() { return "client_auth_user_ack"; } + uid_t get_uid() { return 0; } // fixme + void decode_payload() { } void encode_payload() { diff --git a/branches/aleung/security1/ceph/messages/MClientUserAuth.h b/branches/aleung/security1/ceph/messages/MClientUserAuth.h deleted file mode 100644 index 945eeee78b8e2..0000000000000 --- a/branches/aleung/security1/ceph/messages/MClientUserAuth.h +++ /dev/null @@ -1,54 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2004-2006 Sage Weil - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - - -#ifndef __MCLIENTUSERAUTH_H -#define __MCLIENTUSERAUTH_H - -#include "msg/Message.h" -#include "crypto/CryptoLib.h" -using namespace CryptoLib; - -class MClientUserAuth : public Message { - string username; - uid_t uid; - gid_t gid; - string pubKey; - - public: - MClientBoot(string u, uid_t u, gid_t g, string k) : - Message(MSG_CLIENT_AUTH_USER), username(u), uid(u), gid(g), pubKey(k) { } - - char *get_type_name() { return "Cuserauth"; } - string get_str_key() { return pubKey; } - esignPub get_key() { return _fromString_esignPubKey(pubKey); } - string get_username() { return username; } - uid_t get_uid() { return uid; } - gid_t get_gid() { return gid; } - - virtual void decode_payload() { - int off = 0; - payload.copy(off, sizeof(uid,)(char*)&uid); - payload.copy(off, sizeof(gid,)(char*)&gid); - _decode(username, payload, off); - _decode(pubKey, payload, off); - } - virtual void encode_payload() { - payload.append((char*)&uid, sizeof(uid)); - payload.append((char*)&gid, sizeof(gid)); - _encode(username, payload); - _encode(pubKey, payload); - } -}; - -#endif -- 2.39.5