auth: consolidate messages, rename

This commit is contained in:
Yehuda Sadeh 2009-09-08 11:32:13 -07:00
parent 81a2efa688
commit 9e9526511b
6 changed files with 187 additions and 96 deletions

View File

@ -8,75 +8,108 @@
/*
* Authentication
*/
static void encode_tgt(PrincipalTicket& ticket, CryptoKey& key, bufferlist& bl)
#if 0
static void encode_tgt(AuthTicket& ticket, CryptoKey& key, bufferlist& bl)
{
::encode(ticket, bl);
::encode(key, bl);
}
static void decode_tgt(PrincipalTicket& ticket, CryptoKey& key, bufferlist& bl)
static void decode_tgt(AuthTicket& ticket, CryptoKey& key, bufferlist& bl)
{
bufferlist::iterator iter = bl.begin();
::decode(ticket, iter);
::decode(key, iter);
}
#endif
/*
* PRINCIPAL: request authentication
*
* principal_name, principal_addr. "please authenticate me."
*/
void build_get_tgt_request(EntityName& principal_name, entity_addr_t principal_addr,
void build_authenticate_request(EntityName& principal_name, entity_addr_t& principal_addr,
uint32_t keys,
bool encrypt,
CryptoKey& session_key,
AuthBlob& ticket_info,
bufferlist& request)
{
::encode(principal_name, request);
::encode(principal_addr, request);
AuthServiceTicketRequest ticket_req;
ticket_req.addr = principal_addr;
ticket_req.timestamp = g_clock.now();
ticket_req.keys = keys;
::encode(ticket_req, request);
::encode(ticket_info, request);
}
/*
* AUTH SERVER: authenticate
*
* Authenticate principal, respond with TGT
* Authenticate principal, respond with AuthServiceTicketInfo
*
* {session key, validity, nonce}^principal_secret
* {principal_ticket, session key}^service_secret ... "enc_ticket"
*/
bool build_get_tgt_reply(PrincipalTicket& principal_ticket,
bool build_authenticate_reply(AuthTicket& ticket,
CryptoKey& session_key,
CryptoKey& principal_secret,
CryptoKey& service_secret,
bufferlist& reply)
{
AuthMsg_A msg_a;
AuthServiceTicket msg_a;
msg_a.session_key = session_key;
if (msg_a.encode_encrypt(principal_secret, reply) < 0)
return false;
TGT tgt;
AuthServiceTicketInfo tgt;
tgt.session_key = session_key;
tgt.ticket = principal_ticket;
tgt.ticket = ticket;
if (tgt.encode_encrypt(service_secret, reply) < 0)
return false;
return true;
}
bool verify_service_ticket_request(bool encrypted,
CryptoKey& service_secret,
CryptoKey& session_key,
uint32_t& keys,
bufferlist::iterator& indata)
{
AuthServiceTicketRequest msg;
if (encrypted) {
if (msg.decode_decrypt(session_key, indata) < 0)
return false;
dout(0) << "decoded timestamp=" << msg.timestamp << " addr=" << msg.addr << dendl;
AuthServiceTicketInfo ticket_info;
if (ticket_info.decode_decrypt(service_secret, indata) < 0)
return false;
}
/* FIXME: validate that request makes sense */
return true;
}
/*
* PRINCIPAL: verify our attempt to authenticate succeeded. fill out
* this ServiceTicket with the result.
*/
bool ServiceTicket::verify_service_ticket_reply(CryptoKey& principal_secret,
bool AuthTicketHandler::verify_service_ticket_reply(CryptoKey& secret,
bufferlist::iterator& indata)
{
dout(0) << "1" << dendl;
AuthMsg_A msg_a;
if (msg_a.decode_decrypt(principal_secret, indata) < 0)
AuthServiceTicket msg_a;
if (msg_a.decode_decrypt(secret, indata) < 0)
return false;
::decode(enc_ticket, indata);
::decode(ticket, indata);
if (!indata.end())
return false;
@ -86,12 +119,13 @@ bool ServiceTicket::verify_service_ticket_reply(CryptoKey& principal_secret,
return true;
}
#if 0
/*
* PRINCIPAL: build request to retrieve a service ticket
*
* TGT, D = {principal_addr, timestamp}^principal/auth session key
* AuthServiceTicketInfo, D = {principal_addr, timestamp}^principal/auth session key
*/
bool ServiceTicket::get_session_keys(uint32_t keys, entity_addr_t& principal_addr, bufferlist& bl)
bool AuthTicketHandler::get_session_keys(uint32_t keys, entity_addr_t& principal_addr, bufferlist& bl)
{
AuthMsg_D msg;
msg.timestamp = g_clock.now();
@ -114,7 +148,7 @@ bool verify_get_session_keys_request(CryptoKey& service_secret,
dout(0) << "decoded now=" << msg.timestamp << " addr=" << msg.principal_addr << dendl;
TGT tgt;
AuthServiceTicketInfo tgt;
if (tgt.decode_decrypt(service_secret, indata) < 0)
return false;
@ -122,8 +156,8 @@ bool verify_get_session_keys_request(CryptoKey& service_secret,
return true;
}
#if 0
bool build_get_tgt_reply(PrincipalTicket& principal_ticket, CryptoKey& principal_secret,
bool build_get_tgt_reply(AuthTicket& principal_ticket, CryptoKey& principal_secret,
CryptoKey& session_key, CryptoKey& service_secret,
bufferlist& reply)
{
@ -140,7 +174,7 @@ bool build_get_tgt_reply(PrincipalTicket& principal_ticket, CryptoKey& principal
::encode(enc_info, reply);
/*
Build TGT
Build AuthServiceTicketInfo
*/
bufferlist ticket, tgt;
encode_tgt(principal_ticket, session_key, ticket);
@ -157,6 +191,8 @@ bool build_get_tgt_reply(PrincipalTicket& principal_ticket, CryptoKey& principal
return true;
}
#endif
#if 0
/*
* AUTH SERVER: build ticket for service reply
*
@ -164,7 +200,7 @@ bool build_get_tgt_reply(PrincipalTicket& principal_ticket, CryptoKey& principal
* F= {principal/service session key, validity}^principal/auth session key
*
*/
bool build_ticket_reply(ServiceTicket service_ticket,
bool build_ticket_reply(AuthTicketHandler service_ticket,
CryptoKey session_key,
CryptoKey auth_session_key,
CryptoKey& service_secret,
@ -177,9 +213,8 @@ bool build_ticket_reply(ServiceTicket service_ticket,
return false;
AuthMsg_F f;
AuthServiceTicket f;
f.session_key = session_key;
f.validity = 0; /* FIXME */
if (f.encode_encrypt(auth_session_key, reply) < 0)
return false;
@ -189,7 +224,7 @@ bool build_ticket_reply(ServiceTicket service_ticket,
/*
* AUTH SERVER: verify a request to retrieve a service ticket, build response
*
* TGT, {principal_addr, timestamp}^principal/auth session key
* AuthServiceTicketInfo, {principal_addr, timestamp}^principal/auth session key
*/
bool build_get_session_keys_response(ServiceTicket& ticket, CryptoKey& service_secret,
bufferlist::iterator& indata, bufferlist& out)
@ -198,17 +233,17 @@ bool build_get_session_keys_response(ServiceTicket& ticket, CryptoKey& service_s
return true;
}
#endif
/*
* PRINCIPAL: build authenticator to access the service.
*
* enc_ticket, {timestamp, nonce}^session_key
*/
utime_t ServiceTicket::build_authenticator(bufferlist& bl)
utime_t AuthTicketHandler::build_authenticator(bufferlist& bl)
{
utime_t now = g_clock.now();
::encode(enc_ticket, bl);
::encode(ticket, bl);
bufferlist info, enc_info;
::encode(now, info);
@ -231,7 +266,7 @@ bool verify_authenticator(CryptoKey& service_secret, bufferlist::iterator& indat
::decode(enc_info, indata);
// decrypt ticket
PrincipalTicket ticket;
AuthTicket ticket;
CryptoKey session_key;
{
bufferlist bl;
@ -279,7 +314,7 @@ bool verify_authenticator(CryptoKey& service_secret, bufferlist::iterator& indat
/*
* PRINCIPAL: verify reply is authentic
*/
bool ServiceTicket::verify_reply_authenticator(utime_t then, bufferlist& enc_reply)
bool AuthTicketHandler::verify_reply_authenticator(utime_t then, bufferlist& enc_reply)
{
bufferlist reply;
if (session_key.decrypt(enc_reply, reply) < 0)

View File

@ -35,11 +35,11 @@ WRITE_CLASS_ENCODER(EntityName);
/*
* The principal ticket (if properly validated) authorizes the principal use
* The ticket (if properly validated) authorizes the principal use
* services as described by 'caps' during the specified validity
* period.
*/
struct PrincipalTicket {
struct AuthTicket {
entity_addr_t addr;
utime_t created, renew_after, expires;
string nonce;
@ -67,17 +67,42 @@ struct PrincipalTicket {
::decode(flags, bl);
}
};
WRITE_CLASS_ENCODER(PrincipalTicket)
WRITE_CLASS_ENCODER(AuthTicket)
/*
* Authentication
*/
extern void build_get_tgt_request(EntityName& principal_name, entity_addr_t principal_addr,
extern void build_authenticate_request(EntityName& principal_name, entity_addr_t principal_addr,
bufferlist& request);
extern bool build_get_tgt_reply(PrincipalTicket& principal_ticket, CryptoKey& principal_secret,
extern bool build_authenticate_reply(AuthTicket& principal_ticket, CryptoKey& principal_secret,
CryptoKey& session_key, CryptoKey& service_secret,
bufferlist& reply);
class AuthenticateRequest {
EntityName name;
entity_addr_t addr;
public:
AuthenticateRequest(EntityName& principal_name, entity_addr_t principal_addr) : name(principal_name), addr(principal_addr) {}
void encode(bufferlist& bl) const {
::encode(name, bl);
::encode(addr, bl);
}
void decode(bufferlist::iterator& bl) {
::decode(name, bl);
::decode(addr, bl);
}
};
WRITE_CLASS_ENCODER(AuthenticateRequest)
class AuthenticateReply {
bool verify() {
/* FIXME */
return false;
};
};
struct AuthBlob {
bufferlist blob;
@ -96,14 +121,17 @@ WRITE_CLASS_ENCODER(AuthBlob);
* ServiceTicket gives a principal access to some service
* (monitor, osd, mds).
*/
struct ServiceTicket {
struct AuthTicketHandler {
CryptoKey session_key;
AuthBlob enc_ticket; // opaque to us
AuthBlob ticket; // opaque to us
string nonce;
utime_t renew_after, expires;
bool has_key_flag;
ServiceTicket() : has_key_flag(false) {}
AuthTicketHandler() : has_key_flag(false) {}
bool build_authenticate_request();
bool verify_authenticate_response();
// to build our ServiceTicket
bool verify_service_ticket_reply(CryptoKey& principal_secret,
@ -117,6 +145,7 @@ struct ServiceTicket {
bool verify_reply_authenticator(utime_t then, bufferlist& enc_reply);
bool has_key() { return has_key_flag; }
#if 0
void encode(bufferlist& bl) const {
__u8 v = 1;
::encode(v, bl);
@ -140,8 +169,9 @@ struct ServiceTicket {
::decode(f, bl);
has_key_flag = f;
}
#endif
};
WRITE_CLASS_ENCODER(ServiceTicket)
//WRITE_CLASS_ENCODER(ServiceTicket)
struct AuthEnc {
virtual void encode(bufferlist& bl) const = 0;
@ -173,10 +203,28 @@ struct AuthEnc {
}
};
struct AuthServiceTicketRequest : public AuthEnc {
entity_addr_t addr;
utime_t timestamp;
uint32_t keys;
void encode(bufferlist& bl) const {
::encode(addr, bl);
::encode(timestamp, bl);
::encode(keys, bl);
}
void decode(bufferlist::iterator& bl) {
::decode(addr, bl);
::decode(timestamp, bl);
::decode(keys, bl);
}
};
WRITE_CLASS_ENCODER(AuthServiceTicketRequest);
/* A */
struct AuthMsg_A : public AuthEnc {
utime_t validity;
struct AuthServiceTicket : public AuthEnc {
CryptoKey session_key;
utime_t validity;
void encode(bufferlist& bl) const {
::encode(session_key, bl);
@ -187,10 +235,11 @@ struct AuthMsg_A : public AuthEnc {
::decode(validity, bl);
}
};
WRITE_CLASS_ENCODER(AuthMsg_A);
WRITE_CLASS_ENCODER(AuthServiceTicket);
/* B */
struct TGT : public AuthEnc {
PrincipalTicket ticket;
struct AuthServiceTicketInfo : public AuthEnc {
AuthTicket ticket;
CryptoKey session_key;
void encode(bufferlist& bl) const {
@ -206,8 +255,9 @@ struct TGT : public AuthEnc {
::decode(session_key, bl);
}
};
WRITE_CLASS_ENCODER(TGT);
WRITE_CLASS_ENCODER(AuthServiceTicketInfo);
#if 0
/* D */
struct AuthMsg_D : public AuthEnc {
entity_addr_t principal_addr;
@ -228,7 +278,6 @@ struct AuthMsg_D : public AuthEnc {
WRITE_CLASS_ENCODER(AuthMsg_D);
/* E */
struct AuthMsg_E : public AuthEnc {
ServiceTicket ticket;
@ -241,27 +290,17 @@ struct AuthMsg_E : public AuthEnc {
}
};
WRITE_CLASS_ENCODER(AuthMsg_E);
#endif
/* F */
struct AuthMsg_F : public AuthEnc {
CryptoKey session_key;
utime_t validity;
void encode(bufferlist& bl) const {
::encode(session_key, bl);
::encode(validity, bl);
}
void decode(bufferlist::iterator& bl) {
::decode(session_key, bl);
::decode(validity, bl);
}
};
WRITE_CLASS_ENCODER(AuthMsg_F);
extern void build_authenticate_request(EntityName& principal_name, entity_addr_t& principal_addr,
uint32_t keys,
bool encrypt,
CryptoKey& session_key,
AuthBlob& ticket_info,
bufferlist& request);
extern bool verify_get_session_keys_request(CryptoKey& service_secret,
CryptoKey& session_key, uint32_t& keys, bufferlist::iterator& indata);
extern bool build_ticket_reply(ServiceTicket service_ticket,
extern bool build_authenticate_reply(AuthTicketHandler ticket_handler,
CryptoKey session_key,
CryptoKey auth_session_key,
CryptoKey& service_secret,
@ -269,6 +308,13 @@ extern bool build_ticket_reply(ServiceTicket service_ticket,
/*
* Verify authenticator and generate reply authenticator
*/
extern bool verify_service_ticket_request(bool encrypted,
CryptoKey& service_secret,
CryptoKey& session_key,
uint32_t& keys,
bufferlist::iterator& indata);
extern bool verify_authenticator(CryptoKey& service_secret, bufferlist::iterator& bl,
bufferlist& enc_reply);

View File

@ -65,8 +65,8 @@ int AuthClientHandler::handle_response(int ret, bufferlist& bl)
char buf[1024];
const char *s = bl.c_str();
int pos = 0;
for (int i=0; i<bl.length(); i++) {
pos += snprintf(&buf[pos], 1024-pos, "%0.2x ", (int)(unsigned char)s[i]);
for (unsigned int i=0; i<bl.length(); i++) {
pos += snprintf(&buf[pos], 1024-pos, "%.2x ", (int)(unsigned char)s[i]);
if (i && !(i%8))
pos += snprintf(&buf[pos], 1024-pos, " ");
if (i && !(i%16))
@ -113,14 +113,17 @@ int AuthClientHandler::generate_cephx_protocol_request(bufferlist& bl)
{
CephXRequestHeader header;
if (!auth_ticket.has_key()) {
if (!ticket_handler.has_key()) {
dout(0) << "auth ticket: doesn't have key" << dendl;
/* we first need to get the principle/auth session key */
header.request_type = CEPHX_GET_AUTH_SESSION_KEY;
::encode(header, bl);
build_get_tgt_request(name, addr, bl);
CryptoKey key;
AuthBlob blob;
build_authenticate_request(name, addr, CEPHX_PRINCIPAL_AUTH,
false, key, blob, bl);
cephx_request_state = 1;
return 0;
}
@ -137,7 +140,8 @@ int AuthClientHandler::generate_cephx_protocol_request(bufferlist& bl)
header.request_type = CEPHX_GET_PRINCIPAL_SESSION_KEY;
::encode(header, bl);
auth_ticket.get_session_keys(want_keys, addr, bl);
build_authenticate_request(name, addr, want_keys,
true, ticket_handler.session_key, ticket_handler.ticket, bl);
return 0;
}
@ -161,7 +165,7 @@ int AuthClientHandler::handle_cephx_protocol_response(bufferlist::iterator& inda
bufferptr p(PRINCIPAL_SECRET, sizeof(PRINCIPAL_SECRET) - 1);
secret.set_secret(CEPH_SECRET_AES, p);
if (!auth_ticket.verify_service_ticket_reply(secret, indata)) {
if (!ticket_handler.verify_service_ticket_reply(secret, indata)) {
dout(0) << "could not verify authenticate reply" << dendl;
return -EPERM;
}

View File

@ -38,7 +38,7 @@ class AuthClientHandler {
/* ceph-x protocol */
utime_t auth_ts;
ServiceTicket auth_ticket;
AuthTicketHandler ticket_handler;
CryptoKey secret;

View File

@ -111,6 +111,7 @@ WRITE_CLASS_ENCODER(CephXEnvRequest2);
1. Obtaining principal/auth session key
(Authenticate Request)
p->a : principal, principal_addr. authenticate me!
...authenticator does lookup in database...
@ -118,7 +119,9 @@ WRITE_CLASS_ENCODER(CephXEnvRequest2);
a->p : A= {principal/auth session key, validity}^principal_secret (*)
B= {principal ticket, validity, principal/auth session key}^authsecret
B is also known as TGT
[principal/auth session key, validity] = service ticket
[principal ticket, validity, principal/auth session key] = service ticket info
(*) annotation: ^ signifies 'encrypted by'
@ -133,6 +136,8 @@ WRITE_CLASS_ENCODER(CephXEnvRequest2);
a->p : E= {service ticket}^svcsecret
F= {principal/service session key, validity}^principal/auth session key
principal_addr, timestamp = authenticator
service ticket = principal name, client network address, validity, principal/service session key
Note that steps 1 and 2 are pretty much the same thing; contacting the
@ -146,19 +151,22 @@ WRITE_CLASS_ENCODER(CephXEnvRequest2);
p->s : E + {principal_addr, timestamp}^principal/service session key
s->p : {timestamp+1}^principal/service/session key
timestamp+1 = reply authenticator
Now, the principal is fully authenticated with the service. So, logically we
have 2 main actions here. The first one would be to obtain a session key to
the service (steps 1 and 2), and the second one would be to authenticate with
the service, using that ticket.
*/
#define CEPHX_PRINCIPAL_MON 0x0001
#define CEPHX_PRINCIPAL_OSD 0x0002
#define CEPHX_PRINCIPAL_MDS 0x0004
#define CEPHX_PRINCIPAL_AUTH 0x0001
#define CEPHX_PRINCIPAL_MON 0x0002
#define CEPHX_PRINCIPAL_OSD 0x0004
#define CEPHX_PRINCIPAL_MDS 0x0008
#define CEPHX_PRINCIPAL_TYPE_MASK 0x00FF
#define CEPHX_GET_AUTH_SESSION_KEY 0x0100 /* Get TGT */
#define CEPHX_GET_AUTH_SESSION_KEY 0x0100
#define CEPHX_GET_PRINCIPAL_SESSION_KEY 0x0200
#define CEPHX_OPEN_SESSION 0x0300

View File

@ -32,7 +32,7 @@
class CephAuthServer {
/* FIXME: this is all temporary */
PrincipalTicket principal_ticket;
AuthTicket ticket;
CryptoKey client_secret;
CryptoKey osd_secret;
CryptoKey auth_session_key;
@ -162,34 +162,31 @@ int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, buffe
dout(0) << "CEPHX_GET_AUTH_SESSION_KEY" << dendl;
EntityName name; /* FIXME should take it from the request */
entity_addr_t addr;
PrincipalTicket ticket;
AuthTicket ticket;
CryptoKey principal_secret;
CryptoKey session_key;
CryptoKey service_secret;
ticket.expires = g_clock.now();
uint32_t keys;
if (!verify_service_ticket_request(false, service_secret,
session_key, keys, indata)) {
ret = -EPERM;
break;
}
auth_server.get_client_secret(principal_secret);
auth_server.get_auth_session_key(session_key);
auth_server.get_service_secret(service_secret);
build_cephx_response_header(request_type, 0, result_bl);
if (!build_get_tgt_reply(ticket, session_key, principal_secret, service_secret, result_bl)) {
if (!build_authenticate_reply(ticket, session_key, principal_secret, service_secret, result_bl)) {
ret = -EIO;
break;
}
#if 0
char buf[1024];
const char *s = result_bl.c_str();
int pos = 0;
for (int i=0; i<result_bl.length(); i++) {
pos += snprintf(&buf[pos], 1024-pos, "%0.2x ", (int)(unsigned char)s[i]);
if (i && !(i%8))
pos += snprintf(&buf[pos], 1024-pos, " ");
if (i && !(i%16))
pos += snprintf(&buf[pos], 1024-pos, "\n");
}
dout(0) << "result_buf=" << buf << dendl;
#endif
}
break;
case CEPHX_GET_PRINCIPAL_SESSION_KEY:
@ -206,19 +203,20 @@ int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, buffe
auth_server.get_service_secret(service_secret);
auth_server.get_test_session_key(session_key);
if (!verify_get_session_keys_request(service_secret,
if (!verify_service_ticket_request(true, service_secret,
auth_session_key, keys, indata)) {
ret = -EPERM;
break;
}
ServiceTicket service_ticket;
AuthTicket service_ticket;
CryptoKey osd_secret;
auth_server.get_osd_secret(osd_secret);
auth_server.get_osd_secret(osd_secret);
build_cephx_response_header(request_type, ret, result_bl);
build_ticket_reply(service_ticket, session_key, auth_session_key, osd_secret, result_bl);
build_authenticate_reply(service_ticket, session_key, auth_session_key, osd_secret, result_bl);
}
break;
default: