31 OM_uint32 minor_stat = 0;
32 OM_uint32 msg_ctx = 0;
33 OM_uint32 major_stat = gss_display_status(&minor_stat, major,
34 GSS_C_GSS_CODE, GSS_C_NULL_OID,
35 &msg_ctx, msg_major.
getPtr());
36 if (major_stat != GSS_S_COMPLETE) {
41 cerr <<
"gss_display_status(major=" << major <<
") failed with "
42 << major_stat << endl;
44 msg <<
"GSSAPI error: Major = '";
45 if (!msg_major.
empty()) {
46 msg << static_cast<char*>(msg_major.
getValue());
51 minor_stat = msg_ctx = 0;
52 major_stat = gss_display_status(&minor_stat, minor,
53 GSS_C_MECH_CODE, GSS_C_NULL_OID,
54 &msg_ctx, msg_minor.
getPtr());
55 if (major_stat != GSS_S_COMPLETE) {
60 cerr <<
"gss_display_status(minor=" << minor <<
") failed with "
61 << major_stat << endl;
63 msg <<
"' (" << major <<
"), Minor = '";
64 if (!msg_minor.
empty()) {
65 msg << static_cast<char*>(msg_minor.
getValue());
67 msg <<
"' (" << minor <<
").";
69 msg <<
"' (" << major <<
").";
75 memset(&buffer_, 0,
sizeof(gss_buffer_desc));
79 memset(&buffer_, 0,
sizeof(gss_buffer_desc));
80 if (length > numeric_limits<uint32_t>::max()) {
84 buffer_.length = length;
85 if (buffer_.length > 0) {
88 buffer_.value = malloc(buffer_.length);
92 <<
"'Cannot allocate memory'");
94 memmove(buffer_.value, value, buffer_.length);
99 memset(&buffer_, 0,
sizeof(gss_buffer_desc));
100 if (content.size() > numeric_limits<uint32_t>::max()) {
102 content.size() <<
" is too large");
104 buffer_.length = content.size();
105 if (buffer_.length > 0) {
108 buffer_.value = malloc(buffer_.length);
109 if (!buffer_.value) {
112 <<
"'Cannot allocate memory'");
114 memmove(buffer_.value, &content[0], buffer_.length);
119 memset(&buffer_, 0,
sizeof(gss_buffer_desc));
120 if (content.empty()) {
123 if (content.size() >= numeric_limits<uint32_t>::max()) {
125 << content.size() <<
" is too large");
129 buffer_.length = content.size();
130 buffer_.value = malloc(buffer_.length + 1);
131 if (!buffer_.value) {
134 <<
"'Cannot allocate memory'");
136 memset(buffer_.value, 0, buffer_.length + 1);
137 memmove(buffer_.value, content.c_str(), buffer_.length);
144 OM_uint32 major = gss_release_buffer(&minor, &buffer_);
145 if (major != GSS_S_COMPLETE) {
146 cerr <<
"gss_release_buffer failed with " << major << endl;
153 vector<uint8_t> content;
154 content.resize(buffer_.length);
155 if (buffer_.length > 0) {
156 memmove(&content[0], buffer_.value, buffer_.length);
158 return (vector<uint8_t>(content));
163 if (buffer_.length == 0) {
166 return (
string(
static_cast<char*
>(buffer_.value)));
168 return (
string(
static_cast<char*
>(buffer_.value), buffer_.length));
177 if (gname.size() >= numeric_limits<uint32_t>::max()) {
178 isc_throw(OutOfRange,
"GssApiName constructor: string size "
179 << gname.size() <<
" is too large");
183 OM_uint32 major = gss_import_name(&minor, buf.getPtr(),
184 GSS_C_NO_OID, &name_);
185 if (major != GSS_S_COMPLETE) {
194 OM_uint32 major = gss_release_name(&minor, &name_);
195 if (major != GSS_S_COMPLETE) {
196 cerr <<
"gss_release_name failed with " << major << endl;
205 OM_uint32 major = gss_compare_name(&minor, name_, other.name_, &ret);
206 if (major != GSS_S_COMPLETE) {
218 OM_uint32 major = gss_display_name(&minor, name_, buf.
getPtr(), 0);
219 if (major != GSS_S_COMPLETE) {
233 cred_ = GSS_C_NO_CREDENTIAL;
237 OM_uint32 major = gss_acquire_cred(&minor, gname.
get(), GSS_C_INDEFINITE,
238 mech_oid_set.
get(), cred_usage,
239 &cred_, 0, &lifetime);
240 if (major != GSS_S_COMPLETE) {
249 OM_uint32 major = gss_release_cred(&minor, &cred_);
250 if (major != GSS_S_COMPLETE) {
251 cerr <<
"gss_release_cred failed with " << major << endl;
258 OM_uint32& lifetime) {
262 OM_uint32 major = gss_inquire_cred(&minor, cred_,
name.getPtr(),
263 &lifetime, &cred_usage, 0);
264 if (major != GSS_S_COMPLETE) {
281 OM_uint32 major = gss_import_sec_context(&minor, buf.
getPtr(), &sec_ctx_);
282 if (major != GSS_S_COMPLETE) {
291 OM_uint32 major = gss_delete_sec_context(&minor, &sec_ctx_, 0);
292 if (major != GSS_S_COMPLETE) {
293 cerr <<
"gss_delete_sec_context failed with " << major << endl;
302 OM_uint32 major = gss_export_sec_context(&minor, &sec_ctx_, buf.
getPtr());
303 if (major != GSS_S_COMPLETE) {
313 OM_uint32 lifetime = 0;
315 OM_uint32 major = gss_context_time(&minor, sec_ctx_, &lifetime);
316 if (major != GSS_S_COMPLETE) {
326 OM_uint32& lifetime, OM_uint32& flags,
327 bool& local,
bool& established) {
328 lifetime = flags = 0;
329 local = established =
false;
330 int locally_initiated = 0;
333 OM_uint32 major = gss_inquire_context(&minor, sec_ctx_,
335 &lifetime, 0, &flags,
336 &locally_initiated, &open);
337 if (major != GSS_S_COMPLETE) {
342 local = (locally_initiated != 0);
343 established = (open != 0);
349 OM_uint32 major = gss_get_mic(&minor, sec_ctx_, GSS_C_QOP_DEFAULT,
351 if (major != GSS_S_COMPLETE) {
361 OM_uint32 major = gss_verify_mic(&minor, sec_ctx_, gmessage.
getPtr(),
363 if (major != GSS_S_COMPLETE) {
368#ifdef G_BAD_DIRECTION
369 (minor == G_BAD_DIRECTION)
371 (err_msg.find(
"wrong direction") != string::npos)
385 OM_uint32& lifetime) {
386 gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
391 OM_uint32 ret_flags = 0;
393 OM_uint32 major = gss_init_sec_context(&minor, cred,
394 &sec_ctx_, target.
get(),
396 flags, GSS_C_INDEFINITE,
397 GSS_C_NO_CHANNEL_BINDINGS,
399 outtoken.
getPtr(), &ret_flags,
403 if ((flags & GSS_C_REPLAY_FLAG) &&
404 ((ret_flags & GSS_C_REPLAY_FLAG) == 0)) {
406 "requested anti-replay");
408 if ((flags & GSS_C_SEQUENCE_FLAG) &&
409 ((ret_flags & GSS_C_SEQUENCE_FLAG) == 0)) {
411 "requested sequence");
413 if ((flags & GSS_C_MUTUAL_FLAG) &&
414 ((ret_flags & GSS_C_MUTUAL_FLAG) == 0)) {
416 "requested mutual authentication");
419 case GSS_S_CONTINUE_NEEDED:
432 OM_uint32 major = gss_accept_sec_context(&minor, &sec_ctx_, cred.
get(),
434 GSS_C_NO_CHANNEL_BINDINGS,
436 outtoken.
getPtr(), 0, 0, 0);
440 case GSS_S_CONTINUE_NEEDED:
452 oid_ =
static_cast<gss_OID
>(malloc(
sizeof(gss_OID_desc)));
455 <<
"'Cannot allocate memory' (desc)");
457 memset(oid_, 0,
sizeof(gss_OID_desc));
461 if (elements.size() > 1024) {
462 isc_throw(OutOfRange,
"Too large argument to GssApiOid ("
463 << elements.size() <<
" > 1024)");
467 oid_ =
static_cast<gss_OID
>(malloc(
sizeof(gss_OID_desc)));
470 <<
"'Cannot allocate memory' (desc)");
472 memset(oid_, 0,
sizeof(gss_OID_desc));
473 oid_->length = elements.size();
474 if (oid_->length > 0) {
477 oid_->elements = malloc(oid_->length);
478 if (!oid_->elements) {
481 <<
"'Cannot allocate memory' (elements)");
483 memmove(oid_->elements, &elements[0], oid_->length);
488#ifdef HAVE_GSS_STR_TO_OID
491 OM_uint32 major = gss_str_to_oid(&minor, buf.
getPtr(), &oid_);
492 if (major != GSS_S_COMPLETE) {
504 OM_uint32 major = gss_release_oid(&minor, &oid_);
505 if (major != GSS_S_COMPLETE) {
506 cerr <<
"gss_release_oid failed with " << major << endl;
515 OM_uint32 major = gss_oid_to_str(&minor, oid_, buf.
getPtr());
516 if (major != GSS_S_COMPLETE) {
525vector<uint8_t> ISC_GSS_KRB5_MECHANISM_vect =
526 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 };
533vector<uint8_t> ISC_GSS_SPNEGO_MECHANISM_vect =
534 { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 };
540 oid_set_ = GSS_C_NO_OID_SET;
545 OM_uint32 major = gss_create_empty_oid_set(&minor, &oid_set_);
546 if (major != GSS_S_COMPLETE) {
553 if (major != GSS_S_COMPLETE) {
560 if (major != GSS_S_COMPLETE) {
569 OM_uint32 major = gss_release_oid_set(&minor, &oid_set_);
570 if (major != GSS_S_COMPLETE) {
571 cerr <<
"gss_release_oid_set failed with " << major << endl;
A generic exception that is thrown when a function is not implemented.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
std::vector< uint8_t > getContent() const
Get the content as a vector.
bool empty() const
Empty predicate.
gss_buffer_t getPtr()
Get pointer.
void * getValue()
Get the value.
std::string getString(bool trim=false) const
Get the content as a string.
~GssApiBuffer()
Destructor.
GssApiBuffer()
Constructor.
void inquire(GssApiName &name, gss_cred_usage_t &cred_usage, OM_uint32 &lifetime)
Inquire.
gss_cred_id_t get()
Get the value.
void setLastError(int error)
Set the last error.
GssApiLastError()
Constructor.
virtual ~GssApiLastError()
Destructor.
gss_name_t * getPtr()
Get pointer.
std::string toString()
textual representation.
gss_name_t get()
Get the value.
bool compare(GssApiName &other)
Compare.
gss_OID_set get()
Get the value.
~GssApiOidSet()
Destructor.
GssApiOidSet(bool fill=true)
Constructor.
std::string toString()
Get textual representation.
void sign(GssApiBuffer &gmessage, GssApiBuffer &gsig)
Sign.
static bool ignore_bad_direction_
Ignore bad direction flag.
bool init(GssApiCredPtr credp, GssApiName &target, OM_uint32 flags, GssApiBuffer &intoken, GssApiBuffer &outtoken, OM_uint32 &lifetime)
Init.
void verify(GssApiBuffer &gmessage, GssApiBuffer &gsig)
Verify.
~GssApiSecCtx()
Destructor.
std::vector< uint8_t > serialize()
Export.
OM_uint32 getLifetime()
Get the lifetime (validity in seconds).
GssApiSecCtx(gss_ctx_id_t sec_ctx)
Constructor.
void inquire(GssApiName &source, GssApiName &target, OM_uint32 &lifetime, OM_uint32 &flags, bool &local, bool &established)
Inquire.
bool accept(GssApiCred &cred, GssApiBuffer &intoken, GssApiName &source, GssApiBuffer &outtoken)
Accept.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
C++ binding for the GSS-API.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
GssApiOid ISC_GSS_SPNEGO_MECHANISM(ISC_GSS_SPNEGO_MECHANISM_vect)
The SPNEGO OID.
string gssApiErrMsg(OM_uint32 major, OM_uint32 minor)
An the error message.
GssApiOid ISC_GSS_KRB5_MECHANISM(ISC_GSS_KRB5_MECHANISM_vect)
The Kerberos 5 OID.
isc::log::Logger gss_tsig_logger("gss-tsig-hooks")
const isc::log::MessageID GSS_TSIG_IGNORED_BAD_DIRECTION
boost::shared_ptr< GssApiCred > GssApiCredPtr
Shared pointer to GSS-API credential.
Defines the logger used by the top-level component of kea-lfc.