1 // Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #ifndef TSIGERROR_H
8 #define TSIGERROR_H 1
9 
10 #include <ostream>
11 #include <string>
12 
13 #include <dns/rcode.h>
14 
15 namespace isc {
16 namespace dns {
17 /// TSIG errors
18 ///
19 /// The \c TSIGError class objects represent standard errors related to
20 /// TSIG protocol operations as defined in related specifications, mainly
21 /// in RFC2845, RFC2930 and RFC4635.
22 class TSIGError {
23 public:
24     /// Constants for pre-defined TSIG error values.
25     ///
26     /// Code values from 0 through 15 (inclusive) are derived from those of
27     /// RCODE and are not defined here.  See the \c Rcode class.
28     ///
29     /// \note Unfortunately some systems define "BADSIG" as a macro in a public
30     /// header file.  To avoid conflict with it we add an underscore to our
31     /// definitions.
32     enum CodeValue {
33         BAD_SIG_CODE = 16,  ///< 16: TSIG verification failure
34         BAD_KEY_CODE = 17,  ///< 17: TSIG key is not recognized
35         BAD_TIME_CODE = 18, ///< 18: Current time and time signed are too different
36         BAD_MODE_CODE = 19, ///< 19: Bad TKEY mode
37         BAD_NAME_CODE = 20, ///< 20: Duplicate TKEY name
38         BAD_ALG_CODE = 21,  ///< 21: TKEY algorithm not supported
39         BAD_TRUNC_CODE = 22 ///< 22: Bad truncation
40     };
41 
42     /// \name Constructors
43     ///
44     /// We use the default versions of destructor, copy constructor,
45     /// and assignment operator.
46     //@{
47     /// Constructor from the code value.
48     ///
49     /// \exception None
50     ///
51     /// \param error_code The underlying 16-bit error code value of the \c TSIGError.
TSIGError(uint16_t error_code)52     explicit TSIGError(uint16_t error_code) : code_(error_code) {}
53 
54     /// Constructor from \c Rcode.
55     ///
56     /// As defined in RFC2845, error code values from 0 to 15 (inclusive) are
57     /// derived from the DNS RCODEs, which are represented via the \c Rcode
58     /// class in this library.  This constructor works as a converter from
59     /// these RCODEs to corresponding TSIGError objects.
60     ///
61     /// \exception isc::OutOfRange Given rcode is not convertible to
62     /// TSIGErrors.
63     ///
64     /// \param rcode the \c Rcode from which the TSIGError should be derived.
65     explicit TSIGError(Rcode rcode);
66     //@}
67 
68     /// \brief Returns the \c TSIGCode error code value.
69     ///
70     /// \exception None
71     ///
72     /// \return The underlying code value corresponding to the \c TSIGError.
getCode()73     uint16_t getCode() const { return (code_); }
74 
75     /// \brief Return true iff two \c TSIGError objects are equal.
76     ///
77     /// Two TSIGError objects are equal iff their error codes are equal.
78     ///
79     /// \exception None
80     ///
81     /// \param other the \c TSIGError object to compare against.
82     /// \return true if the two TSIGError are equal; otherwise false.
equals(const TSIGError & other)83     bool equals(const TSIGError& other) const
84     { return (code_ == other.code_); }
85 
86     /// \brief Same as \c equals().
87     bool operator==(const TSIGError& other) const { return (equals(other)); }
88 
89     /// \brief Return true iff two \c TSIGError objects are not equal.
90     ///
91     /// \exception None
92     ///
93     /// \param other the \c TSIGError object to compare against.
94     /// \return true if the two TSIGError objects are not equal;
95     /// otherwise false.
nequals(const TSIGError & other)96     bool nequals(const TSIGError& other) const
97     { return (code_ != other.code_); }
98 
99     /// \brief Same as \c nequals().
100     bool operator!=(const TSIGError& other) const { return (nequals(other)); }
101 
102     /// \brief Convert the \c TSIGError to a string.
103     ///
104     /// For codes derived from RCODEs up to 15, this method returns the
105     /// same string as \c Rcode::toText() for the corresponding code.
106     /// For other pre-defined code values (see TSIGError::CodeValue),
107     /// this method returns a string representation of the "mnemonic' used
108     /// for the enum and constant objects as defined in RFC2845.
109     /// For example, the string for code value 16 is "BADSIG", etc.
110     /// For other code values it returns a string representation of the decimal
111     /// number of the value, e.g. "32", "100", etc.
112     ///
113     /// \exception std::bad_alloc Resource allocation for the string fails
114     ///
115     /// \return A string representation of the \c TSIGError.
116     std::string toText() const;
117 
118     /// \brief Convert the \c TSIGError to a \c Rcode
119     ///
120     /// This method returns an \c Rcode object that is corresponding to
121     /// the TSIG error.  The returned \c Rcode is expected to be used
122     /// by a verifying server to specify the RCODE of a response when
123     /// TSIG verification fails.
124     ///
125     /// Specifically, this method returns \c Rcode::NOTAUTH() for the
126     /// TSIG specific errors, BADSIG, BADKEY, BADTIME, as described in
127     /// RFC2845.  For errors derived from the standard Rcode (code 0-15),
128     /// it returns the corresponding \c Rcode.  For others, this method
129     /// returns \c Rcode::SERVFAIL() as a last resort.
130     ///
131     /// \exception None
132     Rcode toRcode() const;
133 
134     /// A constant TSIG error object derived from \c Rcode::NOERROR()
135     static const TSIGError& NOERROR();
136 
137     /// A constant TSIG error object derived from \c Rcode::FORMERR()
138     static const TSIGError& FORMERR();
139 
140     /// A constant TSIG error object derived from \c Rcode::SERVFAIL()
141     static const TSIGError& SERVFAIL();
142 
143     /// A constant TSIG error object derived from \c Rcode::NXDOMAIN()
144     static const TSIGError& NXDOMAIN();
145 
146     /// A constant TSIG error object derived from \c Rcode::NOTIMP()
147     static const TSIGError& NOTIMP();
148 
149     /// A constant TSIG error object derived from \c Rcode::REFUSED()
150     static const TSIGError& REFUSED();
151 
152     /// A constant TSIG error object derived from \c Rcode::YXDOMAIN()
153     static const TSIGError& YXDOMAIN();
154 
155     /// A constant TSIG error object derived from \c Rcode::YXRRSET()
156     static const TSIGError& YXRRSET();
157 
158     /// A constant TSIG error object derived from \c Rcode::NXRRSET()
159     static const TSIGError& NXRRSET();
160 
161     /// A constant TSIG error object derived from \c Rcode::NOTAUTH()
162     static const TSIGError& NOTAUTH();
163 
164     /// A constant TSIG error object derived from \c Rcode::NOTZONE()
165     static const TSIGError& NOTZONE();
166 
167     /// A constant TSIG error object derived from \c Rcode::RESERVED11()
168     static const TSIGError& RESERVED11();
169 
170     /// A constant TSIG error object derived from \c Rcode::RESERVED12()
171     static const TSIGError& RESERVED12();
172 
173     /// A constant TSIG error object derived from \c Rcode::RESERVED13()
174     static const TSIGError& RESERVED13();
175 
176     /// A constant TSIG error object derived from \c Rcode::RESERVED14()
177     static const TSIGError& RESERVED14();
178 
179     /// A constant TSIG error object derived from \c Rcode::RESERVED15()
180     static const TSIGError& RESERVED15();
181 
182     /// A constant TSIG error object for the BADSIG code
183     /// (see \c TSIGError::BAD_SIG_CODE).
184     static const TSIGError& BAD_SIG();
185 
186     /// A constant TSIG error object for the BADKEY code
187     /// (see \c TSIGError::BAD_KEY_CODE).
188     static const TSIGError& BAD_KEY();
189 
190     /// A constant TSIG error object for the BADTIME code
191     /// (see \c TSIGError::BAD_TIME_CODE).
192     static const TSIGError& BAD_TIME();
193 
194     /// A constant TSIG error object for the BADMODE code
195     /// (see \c TSIGError::BAD_MODE_CODE).
196     static const TSIGError& BAD_MODE();
197 
198     /// A constant TSIG error object for the BADNAME code
199     /// (see \c TSIGError::BAD_NAME_CODE).
200     static const TSIGError& BAD_NAME();
201 
202     /// A constant TSIG error object for the BADALG code
203     /// (see \c TSIGError::BAD_ALG_CODE).
204     static const TSIGError& BAD_ALG();
205 
206     /// A constant TSIG error object for the BADTRUNC code
207     /// (see \c TSIGError::BAD_TRUNC_CODE).
208     static const TSIGError& BAD_TRUNC();
209 
210 private:
211     // This is internally used to specify the maximum possible RCODE value
212     // that can be convertible to TSIGErrors.
213     static const int MAX_RCODE_FOR_TSIGERROR = 15;
214 
215     uint16_t code_;
216 };
217 
218 inline const TSIGError&
NOERROR()219 TSIGError::NOERROR() {
220     static TSIGError e(Rcode::NOERROR());
221     return (e);
222 }
223 
224 inline const TSIGError&
FORMERR()225 TSIGError::FORMERR() {
226     static TSIGError e(Rcode::FORMERR());
227     return (e);
228 }
229 
230 inline const TSIGError&
SERVFAIL()231 TSIGError::SERVFAIL() {
232     static TSIGError e(Rcode::SERVFAIL());
233     return (e);
234 }
235 
236 inline const TSIGError&
NXDOMAIN()237 TSIGError::NXDOMAIN() {
238     static TSIGError e(Rcode::NXDOMAIN());
239     return (e);
240 }
241 
242 inline const TSIGError&
NOTIMP()243 TSIGError::NOTIMP() {
244     static TSIGError e(Rcode::NOTIMP());
245     return (e);
246 }
247 
248 inline const TSIGError&
REFUSED()249 TSIGError::REFUSED() {
250     static TSIGError e(Rcode::REFUSED());
251     return (e);
252 }
253 
254 inline const TSIGError&
YXDOMAIN()255 TSIGError::YXDOMAIN() {
256     static TSIGError e(Rcode::YXDOMAIN());
257     return (e);
258 }
259 
260 inline const TSIGError&
YXRRSET()261 TSIGError::YXRRSET() {
262     static TSIGError e(Rcode::YXRRSET());
263     return (e);
264 }
265 
266 inline const TSIGError&
NXRRSET()267 TSIGError::NXRRSET() {
268     static TSIGError e(Rcode::NXRRSET());
269     return (e);
270 }
271 
272 inline const TSIGError&
NOTAUTH()273 TSIGError::NOTAUTH() {
274     static TSIGError e(Rcode::NOTAUTH());
275     return (e);
276 }
277 
278 inline const TSIGError&
NOTZONE()279 TSIGError::NOTZONE() {
280     static TSIGError e(Rcode::NOTZONE());
281     return (e);
282 }
283 
284 inline const TSIGError&
RESERVED11()285 TSIGError::RESERVED11() {
286     static TSIGError e(Rcode::RESERVED11());
287     return (e);
288 }
289 
290 inline const TSIGError&
RESERVED12()291 TSIGError::RESERVED12() {
292     static TSIGError e(Rcode::RESERVED12());
293     return (e);
294 }
295 
296 inline const TSIGError&
RESERVED13()297 TSIGError::RESERVED13() {
298     static TSIGError e(Rcode::RESERVED13());
299     return (e);
300 }
301 
302 inline const TSIGError&
RESERVED14()303 TSIGError::RESERVED14() {
304     static TSIGError e(Rcode::RESERVED14());
305     return (e);
306 }
307 
308 inline const TSIGError&
RESERVED15()309 TSIGError::RESERVED15() {
310     static TSIGError e(Rcode::RESERVED15());
311     return (e);
312 }
313 
314 inline const TSIGError&
BAD_SIG()315 TSIGError::BAD_SIG() {
316     static TSIGError e(BAD_SIG_CODE);
317     return (e);
318 }
319 
320 inline const TSIGError&
BAD_KEY()321 TSIGError::BAD_KEY() {
322     static TSIGError e(BAD_KEY_CODE);
323     return (e);
324 }
325 
326 inline const TSIGError&
BAD_TIME()327 TSIGError::BAD_TIME() {
328     static TSIGError e(BAD_TIME_CODE);
329     return (e);
330 }
331 
332 inline const TSIGError&
BAD_MODE()333 TSIGError::BAD_MODE() {
334     static TSIGError e(BAD_MODE_CODE);
335     return (e);
336 }
337 
338 inline const TSIGError&
BAD_NAME()339 TSIGError::BAD_NAME() {
340     static TSIGError e(BAD_NAME_CODE);
341     return (e);
342 }
343 
344 inline const TSIGError&
BAD_ALG()345 TSIGError::BAD_ALG() {
346     static TSIGError e(BAD_ALG_CODE);
347     return (e);
348 }
349 
350 inline const TSIGError&
BAD_TRUNC()351 TSIGError::BAD_TRUNC() {
352     static TSIGError e(BAD_TRUNC_CODE);
353     return (e);
354 }
355 
356 /// Insert the \c TSIGError as a string into stream.
357 ///
358 /// This method convert \c tsig_error into a string and inserts it into the
359 /// output stream \c os.
360 ///
361 /// \param os A \c std::ostream object on which the insertion operation is
362 /// performed.
363 /// \param tsig_error An \c TSIGError object output by the operation.
364 /// \return A reference to the same \c std::ostream object referenced by
365 /// parameter \c os after the insertion operation.
366 std::ostream& operator<<(std::ostream& os, const TSIGError& tsig_error);
367 }
368 }
369 
370 #endif  // TSIGERROR_H
371 
372 // Local Variables:
373 // mode: c++
374 // End:
375