#define dout_prefix *_dout << "cephx keyserverdata: "
bool KeyServerData::get_service_secret(CephContext *cct, uint32_t service_id,
- CryptoKey& secret, uint64_t& secret_id) const
+ CryptoKey& secret, uint64_t& secret_id,
+ double& ttl) const
{
map<uint32_t, RotatingSecrets>::const_iterator iter =
rotating_secrets.find(service_id);
if (secrets.secrets.size() > 1)
++riter;
- if (riter->second.expiration < ceph_clock_now())
+ utime_t now = ceph_clock_now();
+ if (riter->second.expiration < now)
++riter; // "current" key has expired, use "next" key instead
secret_id = riter->first;
secret = riter->second.key;
+ // ttl may have just been increased by the user
+ // cap it by expiration of "next" key to prevent handing out a ticket
+ // with a bogus, possibly way into the future, validity
+ ttl = service_id == CEPH_ENTITY_TYPE_AUTH ?
+ cct->_conf->auth_mon_ticket_ttl : cct->_conf->auth_service_ticket_ttl;
+ ttl = min(ttl, static_cast<double>(
+ secrets.secrets.rbegin()->second.expiration - now));
+
ldout(cct, 30) << __func__ << " service "
<< ceph_entity_type_name(service_id) << " secret_id "
- << secret_id << " " << riter->second << dendl;
+ << secret_id << " " << riter->second << " ttl " << ttl
+ << dendl;
return true;
}
return data.get_caps(cct, name, type, caps_info);
}
-bool KeyServer::get_service_secret(uint32_t service_id,
- CryptoKey& secret, uint64_t& secret_id) const
+bool KeyServer::get_service_secret(uint32_t service_id, CryptoKey& secret,
+ uint64_t& secret_id, double& ttl) const
{
std::scoped_lock l{lock};
- return data.get_service_secret(cct, service_id, secret, secret_id);
+ return data.get_service_secret(cct, service_id, secret, secret_id, ttl);
}
bool KeyServer::get_service_secret(uint32_t service_id,
int KeyServer::_build_session_auth_info(uint32_t service_id,
const AuthTicket& parent_ticket,
- CephXSessionAuthInfo& info)
+ CephXSessionAuthInfo& info,
+ double ttl)
{
info.service_id = service_id;
info.ticket = parent_ticket;
- info.ticket.init_timestamps(ceph_clock_now(),
- cct->_conf->auth_service_ticket_ttl);
+ info.ticket.init_timestamps(ceph_clock_now(), ttl);
+ info.validity.set_from_double(ttl);
generate_secret(info.session_key);
const AuthTicket& parent_ticket,
CephXSessionAuthInfo& info)
{
- if (!get_service_secret(service_id, info.service_secret, info.secret_id)) {
+ double ttl;
+ if (!get_service_secret(service_id, info.service_secret, info.secret_id,
+ ttl)) {
return -EPERM;
}
std::scoped_lock l{lock};
-
- return _build_session_auth_info(service_id, parent_ticket, info);
+ return _build_session_auth_info(service_id, parent_ticket, info, ttl);
}
int KeyServer::build_session_auth_info(uint32_t service_id,
info.secret_id = secret_id;
std::scoped_lock l{lock};
- return _build_session_auth_info(service_id, parent_ticket, info);
+ return _build_session_auth_info(service_id, parent_ticket, info,
+ cct->_conf->auth_service_ticket_ttl);
}
}
bool get_service_secret(CephContext *cct, uint32_t service_id,
- CryptoKey& secret, uint64_t& secret_id) const;
+ CryptoKey& secret, uint64_t& secret_id,
+ double& ttl) const;
bool get_service_secret(CephContext *cct, uint32_t service_id,
uint64_t secret_id, CryptoKey& secret) const;
bool get_auth(const EntityName& name, EntityAuth& auth) const;
void _dump_rotating_secrets();
int _build_session_auth_info(uint32_t service_id,
const AuthTicket& parent_ticket,
- CephXSessionAuthInfo& info);
+ CephXSessionAuthInfo& info,
+ double ttl);
bool _get_service_caps(const EntityName& name, uint32_t service_id,
AuthCapsInfo& caps) const;
public:
uint64_t secret_id);
/* get current secret for specific service type */
- bool get_service_secret(uint32_t service_id, CryptoKey& service_key,
- uint64_t& secret_id) const;
+ bool get_service_secret(uint32_t service_id, CryptoKey& secret,
+ uint64_t& secret_id, double& ttl) const;
bool get_service_secret(uint32_t service_id, uint64_t secret_id,
CryptoKey& secret) const override;
break;
}
- info.ticket.init_timestamps(ceph_clock_now(),
- cct->_conf->auth_mon_ticket_ttl);
+ double ttl;
+ if (!key_server->get_service_secret(CEPH_ENTITY_TYPE_AUTH,
+ info.service_secret, info.secret_id,
+ ttl)) {
+ ldout(cct, 0) << " could not get service secret for auth subsystem" << dendl;
+ ret = -EIO;
+ break;
+ }
+
+ info.service_id = CEPH_ENTITY_TYPE_AUTH;
info.ticket.name = entity_name;
info.ticket.global_id = global_id;
- info.validity += cct->_conf->auth_mon_ticket_ttl;
+ info.ticket.init_timestamps(ceph_clock_now(), ttl);
+ info.validity.set_from_double(ttl);
key_server->generate_secret(session_key);
if (psession_key) {
*psession_key = session_key;
}
- info.service_id = CEPH_ENTITY_TYPE_AUTH;
- if (!key_server->get_service_secret(CEPH_ENTITY_TYPE_AUTH, info.service_secret, info.secret_id)) {
- ldout(cct, 0) << " could not get service secret for auth subsystem" << dendl;
- ret = -EIO;
- break;
- }
vector<CephXSessionAuthInfo> info_vec;
info_vec.push_back(info);
service_id,
info.ticket,
svc_info);
- svc_info.validity += cct->_conf->auth_service_ticket_ttl;
info_vec.push_back(svc_info);
}
}
service_err = r;
continue;
}
- info.validity += cct->_conf->auth_service_ticket_ttl;
info_vec.push_back(info);
++found_services;
}