32 OM_uint32 minor_stat = 0;
33 OM_uint32 msg_ctx = 0;
34 OM_uint32 major_stat = gss_display_status(&minor_stat, major,
35 GSS_C_GSS_CODE, GSS_C_NULL_OID,
36 &msg_ctx, msg_major.
getPtr());
37 if (major_stat != GSS_S_COMPLETE) {
42 cerr <<
"gss_display_status(major=" << major <<
") failed with "
43 << major_stat << endl;
45 msg <<
"GSSAPI error: Major = '";
46 if (!msg_major.
empty()) {
47 msg << static_cast<char*>(msg_major.
getValue());
52 minor_stat = msg_ctx = 0;
53 major_stat = gss_display_status(&minor_stat, minor,
54 GSS_C_MECH_CODE, GSS_C_NULL_OID,
55 &msg_ctx, msg_minor.
getPtr());
56 if (major_stat != GSS_S_COMPLETE) {
61 cerr <<
"gss_display_status(minor=" << minor <<
") failed with "
62 << major_stat << endl;
64 msg <<
"' (" << major <<
"), Minor = '";
65 if (!msg_minor.
empty()) {
66 msg << static_cast<char*>(msg_minor.
getValue());
68 msg <<
"' (" << minor <<
").";
70 msg <<
"' (" << major <<
").";
76 memset(&buffer_, 0,
sizeof(gss_buffer_desc));
80 memset(&buffer_, 0,
sizeof(gss_buffer_desc));
81 if (length > numeric_limits<uint32_t>::max()) {
85 buffer_.length = length;
86 if (buffer_.length > 0) {
89 buffer_.value = malloc(buffer_.length);
93 <<
"'Cannot allocate memory'");
95 memmove(buffer_.value, value, buffer_.length);
100 memset(&buffer_, 0,
sizeof(gss_buffer_desc));
101 if (content.size() > numeric_limits<uint32_t>::max()) {
103 content.size() <<
" is too large");
105 buffer_.length = content.size();
106 if (buffer_.length > 0) {
109 buffer_.value = malloc(buffer_.length);
110 if (!buffer_.value) {
113 <<
"'Cannot allocate memory'");
115 memmove(buffer_.value, &content[0], buffer_.length);
120 memset(&buffer_, 0,
sizeof(gss_buffer_desc));
121 if (content.empty()) {
124 if (content.size() >= numeric_limits<uint32_t>::max()) {
126 << content.size() <<
" is too large");
130 buffer_.length = content.size();
131 buffer_.value = malloc(buffer_.length + 1);
132 if (!buffer_.value) {
135 <<
"'Cannot allocate memory'");
137 memset(buffer_.value, 0, buffer_.length + 1);
138 memmove(buffer_.value, content.c_str(), buffer_.length);
145 OM_uint32 major = gss_release_buffer(&minor, &buffer_);
146 if (major != GSS_S_COMPLETE) {
147 cerr <<
"gss_release_buffer failed with " << major << endl;
154 vector<uint8_t> content;
155 content.resize(buffer_.length);
156 if (buffer_.length > 0) {
157 memmove(&content[0], buffer_.value, buffer_.length);
159 return (vector<uint8_t>(content));
164 if (buffer_.length == 0) {
167 return (
string(
static_cast<char*
>(buffer_.value)));
169 return (
string(
static_cast<char*
>(buffer_.value), buffer_.length));
178 if (gname.size() >= numeric_limits<uint32_t>::max()) {
179 isc_throw(OutOfRange,
"GssApiName constructor: string size "
180 << gname.size() <<
" is too large");
184 OM_uint32 major = gss_import_name(&minor, buf.getPtr(),
185 GSS_C_NO_OID, &name_);
186 if (major != GSS_S_COMPLETE) {
195 OM_uint32 major = gss_release_name(&minor, &name_);
196 if (major != GSS_S_COMPLETE) {
197 cerr <<
"gss_release_name failed with " << major << endl;
206 OM_uint32 major = gss_compare_name(&minor, name_, other.name_, &ret);
207 if (major != GSS_S_COMPLETE) {
219 OM_uint32 major = gss_display_name(&minor, name_, buf.
getPtr(), 0);
220 if (major != GSS_S_COMPLETE) {
234 cred_ = GSS_C_NO_CREDENTIAL;
238 OM_uint32 major = gss_acquire_cred(&minor, gname.
get(), GSS_C_INDEFINITE,
239 mech_oid_set.
get(), cred_usage,
240 &cred_, 0, &lifetime);
241 if (major != GSS_S_COMPLETE) {
250 OM_uint32 major = gss_release_cred(&minor, &cred_);
251 if (major != GSS_S_COMPLETE) {
252 cerr <<
"gss_release_cred failed with " << major << endl;
259 OM_uint32& lifetime) {
263 OM_uint32 major = gss_inquire_cred(&minor, cred_,
name.getPtr(),
264 &lifetime, &cred_usage, 0);
265 if (major != GSS_S_COMPLETE) {
282 OM_uint32 major = gss_import_sec_context(&minor, buf.
getPtr(), &sec_ctx_);
283 if (major != GSS_S_COMPLETE) {
292 OM_uint32 major = gss_delete_sec_context(&minor, &sec_ctx_, 0);
293 if (major != GSS_S_COMPLETE) {
294 cerr <<
"gss_delete_sec_context failed with " << major << endl;
303 OM_uint32 major = gss_export_sec_context(&minor, &sec_ctx_, buf.
getPtr());
304 if (major != GSS_S_COMPLETE) {
314 OM_uint32 lifetime = 0;
316 OM_uint32 major = gss_context_time(&minor, sec_ctx_, &lifetime);
317 if (major != GSS_S_COMPLETE) {
327 OM_uint32& lifetime, OM_uint32& flags,
328 bool& local,
bool& established) {
329 lifetime = flags = 0;
330 local = established =
false;
331 int locally_initiated = 0;
334 OM_uint32 major = gss_inquire_context(&minor, sec_ctx_,
336 &lifetime, 0, &flags,
337 &locally_initiated, &open);
338 if (major != GSS_S_COMPLETE) {
343 local = (locally_initiated != 0);
344 established = (open != 0);
350 OM_uint32 major = gss_get_mic(&minor, sec_ctx_, GSS_C_QOP_DEFAULT,
352 if (major != GSS_S_COMPLETE) {
362 OM_uint32 major = gss_verify_mic(&minor, sec_ctx_, gmessage.
getPtr(),
364 if (major != GSS_S_COMPLETE) {
369#ifdef G_BAD_DIRECTION
370 (minor == G_BAD_DIRECTION)
372 (err_msg.find(
"wrong direction") != string::npos)
386 OM_uint32& lifetime) {
387 gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
392 OM_uint32 ret_flags = 0;
394 OM_uint32 major = gss_init_sec_context(&minor, cred,
395 &sec_ctx_, target.
get(),
397 flags, GSS_C_INDEFINITE,
398 GSS_C_NO_CHANNEL_BINDINGS,
400 outtoken.
getPtr(), &ret_flags,
404 if ((flags & GSS_C_REPLAY_FLAG) &&
405 ((ret_flags & GSS_C_REPLAY_FLAG) == 0)) {
407 "requested anti-replay");
409 if ((flags & GSS_C_SEQUENCE_FLAG) &&
410 ((ret_flags & GSS_C_SEQUENCE_FLAG) == 0)) {
412 "requested sequence");
414 if ((flags & GSS_C_MUTUAL_FLAG) &&
415 ((ret_flags & GSS_C_MUTUAL_FLAG) == 0)) {
417 "requested mutual authentication");
420 case GSS_S_CONTINUE_NEEDED:
433 OM_uint32 major = gss_accept_sec_context(&minor, &sec_ctx_, cred.
get(),
435 GSS_C_NO_CHANNEL_BINDINGS,
437 outtoken.
getPtr(), 0, 0, 0);
441 case GSS_S_CONTINUE_NEEDED:
453 oid_ =
static_cast<gss_OID
>(malloc(
sizeof(gss_OID_desc)));
456 <<
"'Cannot allocate memory' (desc)");
458 memset(oid_, 0,
sizeof(gss_OID_desc));
462 if (elements.size() > 1024) {
463 isc_throw(OutOfRange,
"Too large argument to GssApiOid ("
464 << elements.size() <<
" > 1024)");
468 oid_ =
static_cast<gss_OID
>(malloc(
sizeof(gss_OID_desc)));
471 <<
"'Cannot allocate memory' (desc)");
473 memset(oid_, 0,
sizeof(gss_OID_desc));
474 oid_->length = elements.size();
475 if (oid_->length > 0) {
478 oid_->elements = malloc(oid_->length);
479 if (!oid_->elements) {
482 <<
"'Cannot allocate memory' (elements)");
484 memmove(oid_->elements, &elements[0], oid_->length);
489#ifdef HAVE_GSS_STR_TO_OID
492 OM_uint32 major = gss_str_to_oid(&minor, buf.
getPtr(), &oid_);
493 if (major != GSS_S_COMPLETE) {
505 OM_uint32 major = gss_release_oid(&minor, &oid_);
506 if (major != GSS_S_COMPLETE) {
507 cerr <<
"gss_release_oid failed with " << major << endl;
516 OM_uint32 major = gss_oid_to_str(&minor, oid_, buf.
getPtr());
517 if (major != GSS_S_COMPLETE) {
526vector<uint8_t> ISC_GSS_KRB5_MECHANISM_vect =
527 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 };
534vector<uint8_t> ISC_GSS_SPNEGO_MECHANISM_vect =
535 { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 };
541 oid_set_ = GSS_C_NO_OID_SET;
546 OM_uint32 major = gss_create_empty_oid_set(&minor, &oid_set_);
547 if (major != GSS_S_COMPLETE) {
554 if (major != GSS_S_COMPLETE) {
561 if (major != GSS_S_COMPLETE) {
570 OM_uint32 major = gss_release_oid_set(&minor, &oid_set_);
571 if (major != GSS_S_COMPLETE) {
572 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.