1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 /*
21  * XSEC
22  *
23  * XSECEnv := Configuration class - used by the other classes to retrieve
24  *            information on the environment they are working under
25  *
26  * $Id: XSECEnv.hpp 1809031 2017-09-20 13:38:03Z scantor $
27  *
28  */
29 
30 #ifndef XSECENV_INCLUDE
31 #define XSECENV_INCLUDE
32 
33 // XSEC Includes
34 #include <xsec/framework/XSECDefs.hpp>
35 #include <xsec/utils/XSECSafeBufferFormatter.hpp>
36 
37 #include <vector>
38 
39 // Xerces Includes
40 
41 #include <xercesc/dom/DOM.hpp>
42 
43 class XSECURIResolver;
44 
45 /**
46  * @ingroup internal
47  */
48 /*\@{*/
49 
50 /**
51  * @brief Holds environmental information
52  *
53  * The various XSEC classes need to be able to retrieve information
54  * about the environment they are operating in (namespace prefixes,
55  * owning document etc.) - this class is used to provide and hold
56  * this info.
57  *
58  */
59 
60 class XSEC_EXPORT XSECEnv {
61 
62 public:
63 
64 	/** @name Constructors and Destructors */
65     //@{
66 
67     /**
68 	 * \brief Contructor.
69 	 *
70 	 */
71 
72 	XSECEnv(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc);
73 	XSECEnv(const XSECEnv & theOther);
74 	virtual ~XSECEnv();
75 
76     //@}
77 
78 	/** @name Prefix handling. */
79 	//@{
80 
81 	/**
82 	  * \brief Set the prefix be used for the DSIG namespace.
83 	  *
84 	  * <p>When the XSEC library creates XML Element nodes, it uses the prefix here
85 	  * for all nodes created.  By default, the library assumes that the default
86 	  * namespace is used.</p>
87 	  *
88 	  * <p>The #createBlankSignature function will use this prefix to setup the
89 	  * dsig namespace.  E.g. (assuming a call has been made to set the prefix to "ds")
90 	  * the \<Signature\> element will have a namespace attribute added of</p>
91 	  *
92 	  * <p>xmlns:ds="http://www.w3.org/2000/09/xmldsig#"</p>
93 	  *
94 	  * <p>If no prefix has been set, this attribute will be set as the default namespace</p>
95 	  *
96 	  * @see #createBlankSignature
97 	  * @param prefix The UTF-16 encoded NS prefix to use for the XML
98 	  * Digital Signature nodes
99 	  */
100 
101 	void setDSIGNSPrefix(const XMLCh * prefix);
102 
103     /**
104 	  * \brief Set the prefix be used for the DSIG 1.1 namespace.
105 	  *
106 	  * <p>When the XSEC library creates XML Element nodes, it uses the prefix here
107 	  * for all nodes created.  By default, the library assumes that the default
108 	  * namespace is used.</p>
109 	  *
110 	  * @param prefix The UTF-16 encoded NS prefix to use for the XML
111 	  * Digital Signature 1.1 nodes
112 	  */
113 
114 	void setDSIG11NSPrefix(const XMLCh * prefix);
115 
116 	/**
117 	  * \brief Set the prefix be used for the Exclusive Canonicalisation namespace.
118 	  *
119 	  * The Exclusive Canonicalisation specification defines a new namespace for the
120 	  * InclusiveNamespaces node.  This function can be used to set the prefix
121 	  * that the library will use when creating nodes within this namespace.
122 	  *
123 	  * <p>xmlns:ds="http://www.w3.org/2001/10/xml-exc-c14n#"</p>
124 	  *
125 	  * If no prefix is set, the default namespace will be used
126 	  *
127 	  * @see #createBlankSignature
128 	  * @param prefix The UTF-16 encoded NS prefix to use for the XML
129 	  * Exclusive Canonicalisation nodes
130 	  */
131 
132 	void setECNSPrefix(const XMLCh * prefix);
133 
134 	/**
135 	  * \brief Set the prefix be used for the XPath-Filter2 namespace.
136 	  *
137 	  * The XPathFilter definition uses its own namespace.  This
138 	  * method can be used to set the prefix that the library will use
139 	  * when creating elements in this namespace
140 	  *
141 	  * <p>xmlns:ds="http://www.w3.org/2002/06/xmldsig-filter2"</p>
142 	  *
143 	  * If no prefix is set, the default namespace will be used
144 	  *
145 	  * @see #createBlankSignature
146 	  * @param prefix The UTF-16 encoded NS prefix to use for the XPath
147 	  * filter nodes
148 	  */
149 
150 	void setXPFNSPrefix(const XMLCh * prefix);
151 
152 	/**
153 	 * \brief Set prefix for XENC nodes
154 	 *
155 	 * Set the namespace prefix the library will use when creating
156 	 * nodes in the XENC namespace
157 	 */
158 
159 	void setXENCNSPrefix(const XMLCh * prefix);
160 
161 	/**
162 	 * \brief Set prefix for XENC 1.1 nodes
163 	 *
164 	 * Set the namespace prefix the library will use when creating
165 	 * nodes in the XENC 1.1 namespace
166 	 */
167 
168 	void setXENC11NSPrefix(const XMLCh * prefix);
169 
170 #ifdef XSEC_XKMS_ENABLED
171 	/**
172 	 * \brief Set prefix for XKMS nodes
173 	 *
174 	 * Set the namespace prefix the library will use when creating
175 	 * nodes in the XKMS namespace
176 	 */
177 
178 	void setXKMSNSPrefix(const XMLCh * prefix);
179 #endif
180 
181 	/**
182 	 * \brief Get the NS Prefix being used for DSIG elements.
183 	 *
184 	 * @returns A pointer to the buffer holding the prefix
185 	 * @see #setDSIGNSPrefix
186 	 *
187 	 */
188 
getDSIGNSPrefix() const189 	const XMLCh * getDSIGNSPrefix() const {return mp_prefixNS;}
190 
191 	/**
192 	 * \brief Get the NS Prefix being used for DSIG 1.1 elements.
193 	 *
194 	 * @returns A pointer to the buffer holding the prefix
195 	 * @see #setDSIG11NSPrefix
196 	 *
197 	 */
198 
getDSIG11NSPrefix() const199 	const XMLCh * getDSIG11NSPrefix() const {return mp_11PrefixNS;}
200 
201     /**
202 	 * \brief Get the NS being used for EC nodes
203 	 *
204 	 * @returns A pointer to the buffer holding the prefix
205 	 * @see #setECNSPrefix
206 	 */
207 
getECNSPrefix() const208 	const XMLCh * getECNSPrefix() const {return mp_ecPrefixNS;}
209 
210 	/**
211 	 * \brief Get the NS being used for XPath Filter2 nodes
212 	 *
213 	 * @returns A pointer to the buffer holding the prefix
214 	 * @see #setXPFNSPrefix
215 	 */
216 
getXPFNSPrefix() const217 	const XMLCh * getXPFNSPrefix() const {return mp_xpfPrefixNS;}
218 
219 	/**
220 	 * \brief Get namespace prefix for XENC nodes
221 	 *
222 	 * Find the string being used by the library to prefix nodes in the
223 	 * xenc: namespace.
224 	 *
225 	 * @returns XENC namespace prefix
226 	 */
227 
getXENCNSPrefix(void) const228 	const XMLCh * getXENCNSPrefix(void) const {return mp_xencPrefixNS;}
229 
230 	/**
231 	 * \brief Get the NS Prefix being used for XENC 1.1 elements.
232 	 *
233 	 * @returns A pointer to the buffer holding the prefix
234 	 * @see #setXENC11NSPrefix
235 	 *
236 	 */
237 
getXENC11NSPrefix() const238 	const XMLCh * getXENC11NSPrefix() const {return mp_xenc11PrefixNS;}
239 
240 #ifdef XSEC_XKMS_ENABLED
241 	/**
242 	 * \brief Get namespace prefix for XKMS nodes
243 	 *
244 	 * Find the string being used by the library to prefix nodes in the
245 	 * xkms: namespace.
246 	 *
247 	 * @returns XKMS namespace prefix
248 	 */
249 
getXKMSNSPrefix(void) const250 	const XMLCh * getXKMSNSPrefix(void) const {return mp_xkmsPrefixNS;}
251 #endif
252 
253 	//@}
254 
255 	/** @name Pretty Printing Functions */
256 	//@{
257 
258 	/**
259 	 * \brief Set Pretty Print flag
260 	 *
261 	 * The pretty print flag controls whether the library will output
262 	 * CR/LF after the elements it adds to a document
263 	 *
264 	 * By default the library will do pretty printing (flag is true)
265 	 *
266 	 * @param flag Value to set the flag (true = do pretty printing)
267 	 */
268 
setPrettyPrintFlag(bool flag)269 	void setPrettyPrintFlag(bool flag) {m_prettyPrintFlag = flag;}
270 
271 	/**
272 	 * \brief Return the current value of the PrettyPrint flag
273 	 *
274 	 * @returns The value of the pretty print flag
275 	 */
276 
getPrettyPrintFlag(void) const277 	bool getPrettyPrintFlag(void) const {return m_prettyPrintFlag;}
278 
279 	/**
280 	 * \brief Do a pretty print output
281 	 *
282 	 * The library calls this function to perform CR/LF outputting
283 	 *
284 	 * At the moment htis is really redundant, but it is more a holder
285 	 * so that we can set up something in the library to allow users
286 	 * to install a pretty print function.
287 	 *
288 	 * @param node Node to append pretty print content to
289 	 */
290 
291 	void doPrettyPrint(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * node) const;
292 
293 	//@}
294 
295 	/** @name General information functions */
296 	//@{
297 
298 	/**
299 	 * \brief
300 	 *
301 	 * Get the DOMDocument that the super class is operating within.
302 	 *
303 	 * Mainly used by the library itself.
304 	 *
305 	 * @returns The DOM_Document node.
306 	 */
307 
getParentDocument() const308 	XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getParentDocument() const
309 		{return mp_doc;}
310 
311 	/**
312 	 * \brief
313 	 *
314 	 * Set the DOMDocument that the super class is operating within.
315 	 *
316 	 * Mainly used by the library itself.
317 	 *
318 	 * @param doc The Document node.
319 	 */
320 
setParentDocument(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * doc)321 	void setParentDocument(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * doc)
322 		{mp_doc = doc;}
323 
324 	//@}
325 
326 	/** @name Resolver manipulation */
327 	//@{
328 
329 	/**
330 	 * \brief Register a URIResolver
331 	 *
332 	 * Registers a URIResolver to be used by the Signature when dereferencing
333 	 * a URI in a Reference element
334 	 *
335 	 */
336 
337 	void setURIResolver(XSECURIResolver * resolver);
338 
339 	/**
340 	 * \brief Return a pointer to the resolver being used
341 	 *
342 	 * @returns A pointer to the URIResolver registered in this signature
343 	 */
344 
345 	XSECURIResolver * getURIResolver(void) const;
346 
347 
348 	//@}
349 
350 	/** @name ID handling */
351 
352 	//@{
353 
354 	/**
355 	 * \brief Set Id finding behaviour
356 	 *
357 	 * The library de-references "#obj" URI references to ID attributes within
358 	 * a DOM document.  Currently, the library first uses DOM calls to find if
359 	 * the Id has been properly set within the document via the parser or one
360 	 * of the DOM Level 3 calls to set an Id.
361 	 *
362 	 * If no Id is found of the correct name, the library then starts searching
363 	 * for attributes of a given name with the required value.  This list defaults
364 	 * to "id" and "Id", but can be modified via a call to addIdAttributeName()
365 	 *
366 	 * The setIdByAttributeName call enables or disables the second part of the Id
367 	 * search.  I.e. when the Id doesn't exist as an attribute of Type=ID, whether or
368 	 * not to search for an attribute of a name in the list of names.  By default
369 	 * this behaviour is disabled.
370 	 *
371 	 * @warning The default has been changed from earlier versions of the library
372 	 * to address the security risk of assuming IDness based on name.
373 	 *
374 	 * @param flag Enable (true) or Disable (false) searching for Id attributes by name
375 	 */
376 
377 	void setIdByAttributeName(bool flag);
378 
379 	/**
380 	 * \brief Determine Id finding behaviour
381 	 *
382 	 * Allows a caller to determine whether the library is currently searching for
383 	 * Id attributes by name
384 	 *
385 	 * @returns The value of the IdByAttributeName flag
386 	 */
387 
388 	bool getIdByAttributeName(void) const;
389 
390 	/**
391 	 * \brief Add an attribute name to be searched for when looking for Id attributes
392 	 *
393 	 * This allows a user to add an attribute name to be used to identify Id attributes
394 	 * when they are not set to be of Type=ID in the DOM
395 	 *
396 	 * @note Two names are registered by default - "Id" and "id".  These can be
397 	 * removed by calling deregisterIdAttributeName
398 	 *
399 	 * @param name Name to append to the list of those used to find Id attributes
400 	 */
401 
402 	void registerIdAttributeName(const XMLCh * name);
403 
404 	/**
405 	 * \brief Remove an attribute name to be searched for when looking for Id attributes
406 	 *
407 	 * This allows a user to de-register a particular name to be used to identify Id
408 	 * attributes.
409 	 *
410 	 * @param name Name to remove from the list of those used to find Id attributes
411 	 * @returns true if found and removed, false if was not in the list
412 	 */
413 
414 	bool deregisterIdAttributeName(const XMLCh * name);
415 
416 	/**
417 	 * \brief Determine if an attribute name is registered as an Id name
418 	 *
419 	 * @param name String to check in the idAttributeName list
420 	 * @returns true if the passed in name is registered as an Attribute name
421 	 */
422 
423 	bool isRegisteredIdAttributeName(const XMLCh * name) const;
424 
425 	/**
426 	 * \brief Add an attribute name and namespace to be searched for when looking for
427 	 * Id attributes
428 	 *
429 	 * This allows a user to add an attribute name in a parcicular namespace to
430 	 * be used to identify Id attributes
431 	 * when they are not set to be of Type=ID in the DOM
432 	 *
433 	 * @note Two names are registered by default - "Id" and "id".  These can be
434 	 * removed by calling deregisterIdAttributeName
435 	 *
436 	 * @param ns Namespace URI in which attribute appears
437 	 * @param name Name to append to the list of those used to find Id attributes
438 	 */
439 
440 	void registerIdAttributeNameNS(const XMLCh * ns, const XMLCh * name);
441 
442 	/**
443 	 * \brief Remove an attribute name and namespace to be searched for when
444 	 * looking for Id attributes
445 	 *
446 	 * This allows a user to de-register a particular name to be used to identify Id
447 	 * attributes.
448 	 *
449 	 * @param ns Namespace in which attribute resides
450 	 * @param name Name to remove from the list of those used to find Id attributes
451 	 * @returns true if found and removed, false if was not in the list
452 	 */
453 
454 	bool deregisterIdAttributeNameNS(const XMLCh *ns, const XMLCh * name);
455 
456 	/**
457 	 * \brief Determine if an attribute name and namespace is registered
458 	 * as an Id name
459 	 *
460 	 * @param ns Namespace in which attribute resides
461 	 * @param name String to check in the idAttributeName list
462 	 * @returns true if the passed in name is registered as an Attribute name
463 	 */
464 
465 	bool isRegisteredIdAttributeNameNS(const XMLCh * ns, const XMLCh * name) const;
466 
467 	/**
468 	 * \brief Get number of Attribute Names registered as Id attributes
469 	 *
470 	 * @returns the number of elements in the list
471 	 */
472 
473 	int getIdAttributeNameListSize() const;
474 
475 	/*
476 	 * \brief Get an indexed attribute name to use as an Id
477 	 *
478 	 * Returns the item at index point in the list
479 	 *
480 	 * @note This is an internal function and should not be called directly
481 	 *
482 	 * @param index Pointer into the list
483 	 * @returns The indicated element or NULL if it does not exist.
484 	 */
485 
486 	const XMLCh * getIdAttributeNameListItem(int index) const;
487 
488 	/*
489 	 * \brief Get an indexed attribute Namespace to use as an Id
490 	 *
491 	 * Returns the item at index point in the list
492 	 *
493 	 * @note This is an internal function and should not be called directly
494 	 *
495 	 * @param index Pointer into the list
496 	 * @returns The indicated element or NULL if it does not exist.
497 	 */
498 
499 	const XMLCh * getIdAttributeNameListItemNS(int index) const;
500 
501 	/*
502 	 * \brief Determine whether the indexed item is namespace aware
503 	 *
504 	 * Returns the item at index point in the list
505 	 *
506 	 * @note This is an internal function and should not be called directly
507 	 *
508 	 * @param index Pointer into the list
509 	 * @returns The indicated element or NULL if it does not exist.
510 	 */
511 
512 	bool getIdAttributeNameListItemIsNS(int index) const;
513 
514 	//@}
515 
516 	/** @name Formatters */
517 	//@{
518 
519 	/**
520 	 * \brief Get a safeBufferFormatter
521 	 *
522 	 * Return a UTF-8 safeBuffer formatter
523 	 *
524 	 * @returns A pointer to a safeBuffer formatter
525 	 */
526 
getSBFormatter(void) const527 	XSECSafeBufferFormatter * getSBFormatter(void) const {return mp_formatter;}
528 
529 	//@}
530 
531 private:
532 
533 	struct IdAttributeStruct;
534 	typedef struct IdAttributeStruct IdAttributeType;
535 
536 
537 #if defined(XSEC_NO_NAMESPACES)
538 	typedef vector<IdAttributeType *>		IdNameVectorType;
539 #else
540 	typedef std::vector<IdAttributeType *>	IdNameVectorType;
541 #endif
542 
543 	// Internal functions
544 
545 	XSECSafeBufferFormatter		* mp_formatter;
546 	XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument
547 								* mp_doc;
548 	// For creating functions
549 	XMLCh						* mp_prefixNS;
550 	XMLCh						* mp_11PrefixNS;
551 	XMLCh						* mp_ecPrefixNS;
552 	XMLCh						* mp_xpfPrefixNS;
553 	XMLCh						* mp_xencPrefixNS;
554 	XMLCh						* mp_xenc11PrefixNS;
555 #ifdef XSEC_XKMS_ENABLED
556 	XMLCh						* mp_xkmsPrefixNS;
557 #endif
558 	// Resolvers
559 	XSECURIResolver				* mp_URIResolver;
560 
561 	// Flags
562 	bool						m_prettyPrintFlag;
563 	bool						m_idByAttributeNameFlag;
564 
565 	// Id handling
566 	IdNameVectorType			m_idAttributeNameList;
567 
568 	XSECEnv();
569 
570 	/*\@}*/
571 };
572 
573 #endif /* XSECENV_INCLUDE */
574