6 #include <gssapi/gssapi.h>
7 #include <gssapi/gssapi_krb5.h>
8 #include <gssapi/gssapi_ext.h>
12 enum GssContextError {
14 GSS_CONTEXT_UNSUPPORTED,
15 GSS_CONTEXT_NOT_FOUND,
16 GSS_CONTEXT_NOT_INITIALIZED,
19 GSS_CONTEXT_ALREADY_INITIALIZED
31 /*! Class for representing GSS names, such as host/host.domain.com@REALM.
35 //! Initialize to empty name
40 //! Initilize using specific name
41 GssName(const std::string& name) {
45 //! Parse name into native representation
46 bool setName(const std::string& name) {
47 #ifdef ENABLE_GSS_TSIG
48 gss_buffer_desc buffer;
49 d_name = GSS_C_NO_NAME;
52 buffer.length = name.size();
53 buffer.value = (void*)name.c_str();
54 d_maj = gss_import_name(&d_min, &buffer, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &d_name);
55 return d_maj == GSS_S_COMPLETE;
64 #ifdef ENABLE_GSS_TSIG
65 if (d_name != GSS_C_NO_NAME)
66 gss_release_name(&d_min, &d_name);
70 //! Compare two Gss Names, if no gss support is compiled in, returns false always
71 //! This is not necessarely same as string comparison between two non-parsed names
72 bool operator==(const GssName& rhs) {
73 #ifdef ENABLE_GSS_TSIG
76 maj = gss_compare_name(&min, d_name, rhs.d_name, &result);
77 return (maj == GSS_S_COMPLETE && result != 0);
82 //! Compare two Gss Names, if no gss support is compiled in, returns false always
83 //! This is not necessarely same as string comparison between two non-parsed names
84 bool match(const std::string& name) {
85 #ifdef ENABLE_GSS_TSIG
89 gss_buffer_desc buffer;
90 buffer.length = name.size();
91 buffer.value = (void*)name.c_str();
92 maj = gss_import_name(&min, &buffer, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &comp);
93 if (maj != GSS_S_COMPLETE)
94 throw PDNSException("Could not import " + name + ": " + boost::lexical_cast<std::string>(maj) + string(",") + boost::lexical_cast<std::string>(min));
96 maj = gss_compare_name(&min, d_name, comp, &result);
97 gss_release_name(&min, &comp);
98 return (maj == GSS_S_COMPLETE && result != 0);
104 //! Check if GSS name was parsed successfully.
106 #ifdef ENABLE_GSS_TSIG
107 return d_maj == GSS_S_COMPLETE;
113 #ifdef ENABLE_GSS_TSIG
114 OM_uint32 d_maj,d_min;
121 static bool supported(); //<! Returns true if GSS is supported in the first place
122 GssContext(); //<! Construct new GSS context with random name
123 GssContext(const std::string& label); //<! Create or open existing named context
125 void setLocalPrincipal(const std::string& name); //<! Set our gss name
126 bool getLocalPrincipal(std::string& name); //<! Get our name
127 void setPeerPrincipal(const std::string& name); //<! Set remote name (do not use after negotiation)
128 bool getPeerPrincipal(std::string &name); //<! Return remote name, returns actual name after negotatioan
130 void generateLabel(const std::string& suffix); //<! Generate random context name using suffix (such as mydomain.com)
131 void setLabel(const std::string& label); //<! Set context name to this label
132 const std::string& getLabel() { return d_label; } //<! Return context name
134 bool init(const std::string &input, std::string& output); //<! Perform GSS Initiate Security Context handshake
135 bool accept(const std::string &input, std::string& output); //<! Perform GSS Acccept Security Context handshake
136 bool destroy(); //<! Release the cached context
137 bool expired(); //<! Check if context is expired
138 bool valid(); //<! Check if context is valid
140 bool sign(const std::string &input, std::string& output); //<! Sign something using gss
141 bool verify(const std::string &input, const std::string &signature); //<! Validate gss signature with something
143 GssContextError getError(); //<! Get error
144 const std::vector<std::string> getErrorStrings() { return d_gss_errors; } //<! Get native error texts
146 void release(); //<! Release context
147 void initialize(); //<! Initialize context
148 #ifdef ENABLE_GSS_TSIG
149 void processError(const string& method, OM_uint32 maj, OM_uint32 min); //<! Process and fill error text vector
151 std::string d_label; //<! Context name
152 std::string d_peerPrincipal; //<! Remote name
153 std::string d_localPrincipal; //<! Our name
154 GssContextError d_error; //<! Context error
155 GssContextType d_type; //<! Context type
156 std::vector<std::string> d_gss_errors; //<! Native error string(s)
157 boost::shared_ptr<GssSecContext> d_ctx; //<! Attached security context
160 bool gss_add_signature(const DNSName& context, const std::string& message, std::string& mac); //<! Create signature
161 bool gss_verify_signature(const DNSName& context, const std::string& message, const std::string& mac); //<! Validate signature