• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 18679017918

21 Oct 2025 09:15AM UTC coverage: 69.743% (+2.0%) from 67.713%
18679017918

Pull #16307

github

web-flow
Merge ba88af487 into da98764c6
Pull Request #16307: rec: explicit disabling/enabling of tls-gnutls for full and least configs and packages

26192 of 45526 branches covered (57.53%)

Branch coverage included in aggregate %.

6 of 6 new or added lines in 1 file covered. (100.0%)

2282 existing lines in 57 files now uncovered.

86265 of 115719 relevant lines covered (74.55%)

4323875.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pdns/gss_context.hh
1
/*
2
 * This file is part of PowerDNS or dnsdist.
3
 * Copyright -- PowerDNS.COM B.V. and its contributors
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of version 2 of the GNU General Public License as
7
 * published by the Free Software Foundation.
8
 *
9
 * In addition, for the avoidance of any doubt, permission is granted to
10
 * link this program with OpenSSL and to (re)distribute the binaries
11
 * produced as the result of such linking.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22
#pragma once
23

24
#ifdef HAVE_CONFIG_H
25
#include "config.h"
26
#endif
27

28
#include "namespaces.hh"
29
#include "pdnsexception.hh"
30
#include "dns.hh"
31

32
#ifdef ENABLE_GSS_TSIG
33
#include <gssapi/gssapi.h>
34
#include <gssapi/gssapi_krb5.h>
35
extern bool g_doGssTSIG;
36
#endif
37

38
//! Generic errors
39
enum GssContextError
40
{
41
  GSS_CONTEXT_NO_ERROR,
42
  GSS_CONTEXT_UNSUPPORTED,
43
  GSS_CONTEXT_NOT_FOUND,
44
  GSS_CONTEXT_NOT_INITIALIZED,
45
  GSS_CONTEXT_INVALID,
46
  GSS_CONTEXT_EXPIRED,
47
  GSS_CONTEXT_ALREADY_INITIALIZED
48
};
49

50
//! GSS context types
51
enum GssContextType
52
{
53
  GSS_CONTEXT_NONE,
54
  GSS_CONTEXT_INIT,
55
  GSS_CONTEXT_ACCEPT
56
};
57

58
class GssSecContext;
59

60
/*! Class for representing GSS names, such as host/host.domain.com@REALM.
61
 */
62
class GssName
63
{
64
public:
65
  //! Initialize to empty name
66
  GssName()
67
  {
×
68
    setName("");
×
69
  };
×
70

71
  //! Initialize using specific name
72
  GssName(const std::string& name)
73
  {
×
74
    setName(name);
×
75
  };
×
76

77
#ifdef ENABLE_GSS_TSIG
78
  //! Parse name into native representation
79
  bool setName(const std::string& name)
UNCOV
80
  {
×
UNCOV
81
    gss_buffer_desc buffer;
×
UNCOV
82
    d_name = GSS_C_NO_NAME;
×
83

UNCOV
84
    if (!name.empty()) {
×
UNCOV
85
      buffer.length = name.size();
×
UNCOV
86
      buffer.value = (void*)name.c_str();
×
UNCOV
87
      d_maj = gss_import_name(&d_min, &buffer, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &d_name);
×
UNCOV
88
      return d_maj == GSS_S_COMPLETE;
×
UNCOV
89
    }
×
90

UNCOV
91
    return true;
×
UNCOV
92
  }
×
93
#else
94
  bool setName(const std::string& /* name */)
95
  {
96
    return false;
97
  }
98
#endif
99

100
  ~GssName()
101
  {
×
102
#ifdef ENABLE_GSS_TSIG
×
103
    if (d_name != GSS_C_NO_NAME)
×
104
      gss_release_name(&d_min, &d_name);
×
105
#endif
×
106
  };
×
107

108
#ifdef ENABLE_GSS_TSIG
109
  //! Compare two Gss Names, if no gss support is compiled in, returns false always
110
  //! This is not necessarily same as string comparison between two non-parsed names
111
  bool operator==(const GssName& rhs)
UNCOV
112
  {
×
UNCOV
113
    OM_uint32 maj, min;
×
UNCOV
114
    int result;
×
UNCOV
115
    maj = gss_compare_name(&min, d_name, rhs.d_name, &result);
×
UNCOV
116
    return (maj == GSS_S_COMPLETE && result != 0);
×
UNCOV
117
  }
×
118
#else
119
  bool operator==(const GssName& /* rhs */)
120
  {
121
    return false;
122
  }
123
#endif
124

125
#ifdef ENABLE_GSS_TSIG
126
  //! Compare two Gss Names, if no gss support is compiled in, returns false always
127
  //! This is not necessarily same as string comparison between two non-parsed names
128
  bool match(const std::string& name)
UNCOV
129
  {
×
UNCOV
130
    OM_uint32 maj, min;
×
UNCOV
131
    int result;
×
UNCOV
132
    gss_name_t comp;
×
UNCOV
133
    gss_buffer_desc buffer;
×
UNCOV
134
    buffer.length = name.size();
×
UNCOV
135
    buffer.value = (void*)name.c_str();
×
UNCOV
136
    maj = gss_import_name(&min, &buffer, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &comp);
×
UNCOV
137
    if (maj != GSS_S_COMPLETE)
×
UNCOV
138
      throw PDNSException("Could not import " + name + ": " + std::to_string(maj) + string(",") + std::to_string(min));
×
139
    // do comparison
UNCOV
140
    maj = gss_compare_name(&min, d_name, comp, &result);
×
UNCOV
141
    gss_release_name(&min, &comp);
×
UNCOV
142
    return (maj == GSS_S_COMPLETE && result != 0);
×
UNCOV
143
  }
×
144
#else
145
  bool match(const std::string& /* name */)
146
  {
147
    return false;
148
  }
149
#endif
150

151
  //! Check if GSS name was parsed successfully.
152
  bool valid()
153
  {
×
154
#ifdef ENABLE_GSS_TSIG
×
155
    return d_maj == GSS_S_COMPLETE;
×
156
#else
×
157
    return false;
×
158
#endif
×
159
  }
×
160

161
private:
162
#ifdef ENABLE_GSS_TSIG
163
  OM_uint32 d_maj{0}, d_min{0};
164
  gss_name_t d_name;
165
#endif
166
}; // GssName
167

168
class GssContext
169
{
170
public:
171
  static std::tuple<size_t, size_t, size_t> getCounts();
172
  static bool supported(); //<! Returns true if GSS is supported in the first place
173
  GssContext(); //<! Construct new GSS context with random name
174
  GssContext(const DNSName& label); //<! Create or open existing named context
175

176
  void setLocalPrincipal(const std::string& name); //<! Set our gss name
177
  bool getLocalPrincipal(std::string& name); //<! Get our name
178
  void setPeerPrincipal(const std::string& name); //<! Set remote name (do not use after negotiation)
179
  bool getPeerPrincipal(std::string& name); //<! Return remote name, returns actual name after negotiation
180

181
  void generateLabel(const std::string& suffix); //<! Generate random context name using suffix (such as mydomain.com)
182
  void setLabel(const DNSName& label); //<! Set context name to this label
183
  const DNSName& getLabel() { return d_label; } //<! Return context name
×
184

185
  bool init(const std::string& input, std::string& output); //<! Perform GSS Initiate Security Context handshake
186
  bool accept(const std::string& input, std::string& output); //<! Perform GSS Accept Security Context handshake
187
  bool destroy(); //<! Release the cached context
188
  bool expired(); //<! Check if context is expired
189
  bool valid(); //<! Check if context is valid
190

191
  bool sign(const std::string& input, std::string& output); //<! Sign something using gss
192
  bool verify(const std::string& input, const std::string& signature); //<! Validate gss signature with something
193

194
  GssContextError getError(); //<! Get error
195
  const std::vector<std::string> getErrorStrings() { return d_gss_errors; } //<! Get native error texts
×
196
private:
197
  void release(); //<! Release context
198
  void initialize(); //<! Initialize context
199
#ifdef ENABLE_GSS_TSIG
200
  void processError(const string& method, OM_uint32 maj, OM_uint32 min); //<! Process and fill error text vector
201
#endif
202
  DNSName d_label; //<! Context name
203
  std::string d_peerPrincipal; //<! Remote name
204
  std::string d_localPrincipal; //<! Our name
205
  GssContextError d_error; //<! Context error
206
  GssContextType d_type; //<! Context type
207
  std::vector<std::string> d_gss_errors; //<! Native error string(s)
208
  std::shared_ptr<GssSecContext> d_secctx; //<! Attached security context
209
}; // GssContext
210

211
bool gss_add_signature(const DNSName& context, const std::string& message, std::string& mac); //<! Create signature
212
bool gss_verify_signature(const DNSName& context, const std::string& message, const std::string& mac); //<! Validate signature
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc