#4 AsciiDoc version of the Defensive Coding Guide
Closed 6 years ago by bex. Opened 6 years ago by mjahoda.
https://gitlab.com/redhat-sectech/defensive-coding-guide master  into  master

.gitlab-ci.yml: corrected copy of generated files
Nikos Mavrogiannopoulos • 6 years ago  
.gitlab-ci.yml: install python
Nikos Mavrogiannopoulos • 6 years ago  
Syntax highlighting for Example 3 added
Mirek Jahoda • 6 years ago  
Markup issues resolved
Mirek Jahoda • 6 years ago  
Additional markup fixes
Mirek Jahoda • 6 years ago  
Section numbering & source code syntax highlighting added
Mirek Jahoda • 6 years ago  
ToC added, several markup issues fixed
Mirek Jahoda • 6 years ago  
.gitlab-ci.yml: updated for asciidoctor generation
Nikos Mavrogiannopoulos • 6 years ago  
include snippets from main doc
Nikos Mavrogiannopoulos • 6 years ago  
updated makefile for asciidoctor
Nikos Mavrogiannopoulos • 6 years ago  
updated snippets generation for adoc format
Nikos Mavrogiannopoulos • 6 years ago  
Adding adoc files & several conversion errors fixed
Mirek Jahoda • 6 years ago  
Converted to AsciiDoc
Mirek Jahoda • 6 years ago  
Update Tasks-Processes.xml - title case + adj.
Mirek Jahoda • 6 years ago  
Update CXX-Std.xml - title case
Mirek Jahoda • 6 years ago  
Update CXX-Language.xml - title case
Mirek Jahoda • 6 years ago  
Update README.md - internal link removed
Mirek Jahoda • 6 years ago  
Update README.md - the Emender URL added
Mirek Jahoda • 6 years ago  
Update Features-HSM.xml - grammar fixes
Mirek Jahoda • 6 years ago  
Update Features-TLS.xml - a typo fixed
Mirek Jahoda • 6 years ago  
Update Features-Authentication.xml - grammar fixes
Mirek Jahoda • 6 years ago  
Update Tasks-Cryptography.xml - grammar fixes
Mirek Jahoda • 6 years ago  
Update Tasks-Packaging.xml - title case
Mirek Jahoda • 6 years ago  
Update Tasks-Serialization.xml - grammar fixes
Mirek Jahoda • 6 years ago  
Update Tasks-Descriptors.xml - typos fixed
Mirek Jahoda • 6 years ago  
Update Tasks-Library_Design.xml - typos, title case
Mirek Jahoda • 6 years ago  
Update Go.xml - title case
Mirek Jahoda • 6 years ago  
Update Shell.xml - title case
Mirek Jahoda • 6 years ago  
Update Python.xml - title case
Mirek Jahoda • 6 years ago  
Update Java-SecurityManager.xml - title case
Mirek Jahoda • 6 years ago  
Update Java-LowLevel.xml - title case
Mirek Jahoda • 6 years ago  
Update Java-Language.xml - title case
Mirek Jahoda • 6 years ago  
Update C-Other.xml - title case
Mirek Jahoda • 6 years ago  
Update C-Allocators.xml - typos, title case
Mirek Jahoda • 6 years ago  
Update C-Libc.xml - typos, title case
Mirek Jahoda • 6 years ago  
Update C-Language.xml - Title Case
Mirek Jahoda • 6 years ago  
Update Tasks-Packaging.xml - Title Case
Mirek Jahoda • 6 years ago  
Update Tasks-Serialization.xml - Title Case and an adj. fixed
Mirek Jahoda • 6 years ago  
Update Tasks-Processes.xml - Title Case and an adj. fixed
Mirek Jahoda • 6 years ago  
Update Tasks-Temporary_Files.xml - Title Case fixed
Mirek Jahoda • 6 years ago  
Update Tasks-Descriptors.xml - Title case fixed
Mirek Jahoda • 6 years ago  
Update Tasks-File_System.xml - Title Case fixed
Mirek Jahoda • 6 years ago  
Update Java-Language.xml - a typo in a title fixed
Mirek Jahoda • 6 years ago  
Merge branch 'tmp-update-self-signed-section' into 'master'
Nikos Mavrogiannopoulos • 6 years ago  
link to packaging guidelines on generating certificates
Nikos Mavrogiannopoulos • 6 years ago  
added known issues text
Nikos Mavrogiannopoulos • 7 years ago  
serialization: mention protocol buffers
Nikos Mavrogiannopoulos • 7 years ago  
Merge branch 'tmp-remove-snippets' into 'master'
Nikos Mavrogiannopoulos • 7 years ago  
removed auto-generated files
Nikos Mavrogiannopoulos • 7 years ago  
mark it as unofficial
Nikos Mavrogiannopoulos • 7 years ago  
corrected brand
Nikos Mavrogiannopoulos • 7 years ago  
updated copyright date
Nikos Mavrogiannopoulos • 7 years ago  
Makefile: removed legacy upload option
Nikos Mavrogiannopoulos • 7 years ago  
getrandom: documented addition to glibc
Nikos Mavrogiannopoulos • 7 years ago  
crypto: added getentropy syscall
Nikos Mavrogiannopoulos • 7 years ago  
Merge branch '5.3-tinyfix' into 'master'
Nikos Mavrogiannopoulos • 7 years ago  
change "Completely isolation" to "Complete isolation"
Ryan Sawhill Aroha • 7 years ago  
Merge branch 'tmp-jobs' into 'master'
Nikos Mavrogiannopoulos • 7 years ago  
.gitlab-ci.yml: added CI job for testing when not in master
Nikos Mavrogiannopoulos • 7 years ago  
Merge branch 'tmp-use-gnutls_set_default_priority' into 'master'
Nikos Mavrogiannopoulos • 7 years ago  
gnutls: recommend the use of gnutls_set_default_priority()
Nikos Mavrogiannopoulos • 7 years ago  
README.md: added
Nikos Mavrogiannopoulos • 7 years ago  
.gitlab-ci.yml: added auto-generation of code
Nikos Mavrogiannopoulos • 7 years ago  
Added contributing authors
Nikos Mavrogiannopoulos • 7 years ago  
crypto primitives: added text on getrandom
Nikos Mavrogiannopoulos • 7 years ago  
TLS: mention upstream documentation for libraries
Nikos Mavrogiannopoulos • 7 years ago  
TLS-Client-NSS: enable AES-GCM
Nikos Mavrogiannopoulos • 7 years ago  
TLS: document the update-ca-trust
Nikos Mavrogiannopoulos • 7 years ago  
Mention only gnutls_certificate_verify_peers3()
Nikos Mavrogiannopoulos • 7 years ago  
TLS: gnutls: use gnutls_certificate_set_x509_system_trust
Nikos Mavrogiannopoulos • 7 years ago  
mention TLS in Transport Layer Security section title
Nikos Mavrogiannopoulos • 7 years ago  
Removed pitfalls mentioned for old versions of GnuTLS
Nikos Mavrogiannopoulos • 7 years ago  
Added a section on usage of Hardware Security Modules (HSM).
Nikos Mavrogiannopoulos • 7 years ago  
.gitlab-ci.yml
file added
+30
@@ -0,0 +1,30 @@

+ pages:

+   image: fedora:27

+   script:

+   - dnf install -y python asciidoctor gnutls-devel openssl-devel nss-devel gcc-go gcc make java-devel gcc-c++ expat-devel qt-devel

+   - gem install pygments.rb

+   - make

+   - make build-manual

+   - mkdir -p public

+   - cp -ar html/* public

+   - cp -ar html/master.html public/index.html

+   tags:

+   - shared

+   only:

+     - master

+   artifacts:

+     when: on_success

+     paths:

+       - public

+ 

+ test:

+   image: fedora:27

+   script:

+   - dnf install -y python asciidoctor gnutls-devel openssl-devel nss-devel gcc-go gcc make java-devel gcc-c++ expat-devel qt-devel

+   - gem install pygments.rb

+   - make

+   tags:

+   - shared

+   except:

+     - master

+ 

KNOWN-ISSUES.md
file added
+7
@@ -0,0 +1,7 @@

+ # Known issues

+ 

+  * No mention of rust

+  * Enhance sections on serialization with examples of protocol buffers

+  * No mention of process isolation mechanisms/sandboxing (seccomp)

+  * No mention of programming with SELinux for safety

+ 

Makefile
file modified
+9 -13
@@ -2,9 +2,10 @@

  

  include src/src.mk

  

- .PHONY: all build build-manual build-snippets build-manual-html build-manual-epub force clean upload

+ .PHONY: all build build-manual build-snippets build-manual-html build-manual-epub force clean

  

- build: build-src build-manual

+ #build: build-src build-manual

+ build: build-manual

  

  build-snippets:

  	mkdir -p en-US/snippets
@@ -12,23 +13,18 @@

  	  src/*.c src/*.cpp src/*.java src/*.py src/*.go src/*.sh

  

  build-manual: build-snippets

- 	publican build --formats=html,epub,pdf --langs=en-US

+ 	rm -rf html && mkdir html

+ 	cd en-US && asciidoctor -n master.adoc -D ../html && cp -ar Common_Content/ ../html/

  

- build-manual-html: build-snippets

- 	publican build --formats=html --langs=en-US

+ build-manual-html: build-manual

  

  build-manual-epub: build-snippets

- 	publican build --formats=epub --langs=en-US

+ 	false

  

  build-manual-pdf: build-snippets

- 	publican build --formats=pdf --langs=en-US

+ 	false

  

  clean: clean-src

- 	-rm -rf tmp

+ 	-rm -rf html

  	-rm -rf en-US/*/snippets

  

- upload:	clean build

- 	rsync -avP --delete tmp/en-US/html/. file.rdu.redhat.com:public_html/defensive-coding/.

- 	rsync -avP tmp/en-US/Defensive_Coding*.epub file.rdu.redhat.com:public_html/defensive-coding.epub

- 	rsync -avP tmp/en-US/pdf/Defensive_Coding*.pdf file.rdu.redhat.com:public_html/defensive-coding.pdf

- 

README
file removed
-26
@@ -1,26 +0,0 @@

- TODO and bug tracking

- ---------------------

- 

- The secure-coding guide has its own component in Bugzilla:

- 

- https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20Documentation&component=defensive-coding-guide

- 

- Please file bugs and suggestions there.

- 

- Building HTML documentation

- ---------------------------

- 

- Just type "make".  If you do not want to build the example code, run

- "make build-manual".

- 

- When you type "make", the code examples in src/ are compiled (mainly

- to check for obvious syntax errors, but also for manual testing).  If

- you lack the necessary libraries, you can type "make build-manual"

- instead, which will skip this step.  The code examples are still

- included in the manual.

- 

- Dependencies

- ------------

- 

- Building the manual needs the "publican" and the "publican-fedora"

- packages.

README.md
file added
+26
@@ -0,0 +1,26 @@

+ # Security coding guide

+ 

+ This is a fork of the Fedora secure coding guide.

+ 

+ The guide is present in HTML form (auto-generated from this

+ repository) at:

+ 

+  * http://redhat-sectech.gitlab.io/defensive-coding-guide

+ 

+ 

+ # Building HTML documentation

+ 

+ Just type "make".  If you do not want to build the example code, run

+ "make build-manual".

+ 

+ When you type "make", the code examples in src/ are compiled (mainly

+ to check for obvious syntax errors, but also for manual testing).  If

+ you lack the necessary libraries, you can type "make build-manual"

+ instead, which will skip this step.  The code examples are still

+ included in the manual.

+ 

+ 

+ # Dependencies

+ 

+ Building the manual pages needs the "publican" and the "publican-fedora"

+ packages. 

\ No newline at end of file

docbook-schema/README
file removed
-3
@@ -1,3 +0,0 @@

- This directory contains Relax NG Compact schema files, for use with

- Emacs.  These files were download from http://www.docbook.org/rng/4.5/

- on 2012-07-16.

docbook-schema/calstblx.rnc
file removed
-164
@@ -1,164 +0,0 @@

- # ......................................................................

- 

- # DocBook CALS Table Model V4.5 ........................................

- 

- # File calstblx.mod ....................................................

- 

- # Copyright 1992-2002 HaL Computer Systems, Inc.,

- # O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software

- # Corporation, Norman Walsh, Sun Microsystems, Inc., and the

- # Organization for the Advancement of Structured Information

- # Standards (OASIS).

- # 

- # This DTD is based on the CALS Table Model

- # PUBLIC "-//USA-DOD//DTD Table Model 951010//EN"

- # 

- # $Id: calstblx.dtd 6340 2006-10-03 13:23:24Z nwalsh $

- # 

- # Permission to use, copy, modify and distribute the DocBook DTD

- # and its accompanying documentation for any purpose and without fee

- # is hereby granted in perpetuity, provided that the above copyright

- # notice and this paragraph appear in all copies.  The copyright

- # holders make no representation about the suitability of the DTD for

- # any purpose.  It is provided "as is" without expressed or implied

- # warranty.

- # 

- # If you modify the DocBook DTD in any way, except for declaring and

- # referencing additional sets of general entities and declaring

- # additional notations, label your DTD as a variant of DocBook.  See

- # the maintenance documentation for more information.

- # 

- # Please direct all questions, bug reports, or suggestions for

- # changes to the docbook@lists.oasis-open.org mailing list. For more

- # information, see http://www.oasis-open.org/docbook/.

- 

- # ......................................................................

- 

- # This module contains the definitions for the CALS Table Model

- # converted to XML. It has been modified slightly for use in the

- # combined HTML/CALS models supported by DocBook V4.5.

- 

- # These definitions are not directly related to the table model, but are

- # used in the default CALS table model and are usually defined elsewhere

- # (and prior to the inclusion of this table module) in a CALS DTD.

- 

- # no if zero(s),

- # yes if any other digits value

- 

- yesorno = string

- titles = title?

- # default for use in entry content

- 

- # The parameter entities as defined below provide the CALS table model

- # as published (as part of the Example DTD) in MIL-HDBK-28001.

- # 

- # These following declarations provide the CALS-compliant default definitions

- # for these entities.  However, these entities can and should be redefined

- # (by giving the appropriate parameter entity declaration(s) prior to the

- # reference to this Table Model declaration set entity) to fit the needs

- # of the current application.

- tbl.table-titles.mdl = titles

- tbl.table-main.mdl = tgroup+ | graphic+

- tbl.tgroup.mdl = colspec*, spanspec*, thead?, tfoot?, tbody

- tbl.tgroup.att = attribute tgroupstyle { text }?

- tbl.row.mdl = (entry | entrytbl)+

- tbl.entrytbl.mdl = colspec*, spanspec*, thead?, tbody

- # =====  Element and attribute declarations follow. =====

- 

- # doc:A formal table in a document.

- table = element table { table.attlist, tbl.table.mdl }

- table.attlist &=

-   attribute frame { tbl.frame.attval }?,

-   attribute colsep { yesorno }?,

-   attribute rowsep { yesorno }?,

-   tbl.table.att,

-   bodyatt,

-   secur

- # doc:A wrapper for the main content of a table, or part of a table.

- tgroup = element tgroup { tgroup.attlist, tbl.tgroup.mdl }

- tgroup.attlist &=

-   attribute cols { text },

-   tbl.tgroup.att,

-   attribute colsep { yesorno }?,

-   attribute rowsep { yesorno }?,

-   attribute align { "left" | "right" | "center" | "justify" | "char" }?,

-   attribute char { text }?,

-   attribute charoff { text }?,

-   secur

- # doc:Specifications for a column in a table.

- colspec = element colspec { colspec.attlist, empty }

- colspec.attlist &=

-   attribute colnum { text }?,

-   attribute colname { text }?,

-   attribute colwidth { text }?,

-   attribute colsep { yesorno }?,

-   attribute rowsep { yesorno }?,

-   attribute align { "left" | "right" | "center" | "justify" | "char" }?,

-   attribute char { text }?,

-   attribute charoff { text }?

- # doc:Formatting information for a spanned column in a table.

- spanspec = element spanspec { spanspec.attlist, empty }

- spanspec.attlist &=

-   attribute namest { text },

-   attribute nameend { text },

-   attribute spanname { text },

-   attribute colsep { yesorno }?,

-   attribute rowsep { yesorno }?,

-   attribute align { "left" | "right" | "center" | "justify" | "char" }?,

-   attribute char { text }?,

-   attribute charoff { text }?

- # doc:A table header consisting of one or more rows.

- thead = element thead { thead.attlist, tbl.hdft.mdl }

- thead.attlist &=

-   attribute valign { "top" | "middle" | "bottom" }?,

-   secur

- # doc:A table footer consisting of one or more rows.

- tfoot = element tfoot { tfoot.attlist, tbl.hdft.mdl }

- tfoot.attlist &=

-   attribute valign { "top" | "middle" | "bottom" }?,

-   secur

- # doc:A wrapper for the rows of a table or informal table.

- tbody = element tbody { tbody.attlist, tbl.tbody.mdl }

- tbody.attlist &=

-   attribute valign { "top" | "middle" | "bottom" }?,

-   secur

- # doc:A row in a table.

- row = element row { row.attlist, tbl.row.mdl }

- row.attlist &=

-   attribute rowsep { yesorno }?,

-   attribute valign { "top" | "middle" | "bottom" }?,

-   secur

- # doc:A subtable appearing in place of an Entry in a table.

- entrytbl = element entrytbl { entrytbl.attlist, tbl.entrytbl.mdl }

- entrytbl.attlist &=

-   attribute cols { text },

-   tbl.tgroup.att,

-   attribute colname { text }?,

-   attribute spanname { text }?,

-   attribute namest { text }?,

-   attribute nameend { text }?,

-   attribute colsep { yesorno }?,

-   attribute rowsep { yesorno }?,

-   attribute align { "left" | "right" | "center" | "justify" | "char" }?,

-   attribute char { text }?,

-   attribute charoff { text }?,

-   secur

- # doc:A cell in a table.

- entry = element entry { entry.attlist, tbl.entry.mdl* }

- entry.attlist &=

-   attribute colname { text }?,

-   attribute namest { text }?,

-   attribute nameend { text }?,

-   attribute spanname { text }?,

-   attribute morerows { text }?,

-   attribute colsep { yesorno }?,

-   attribute rowsep { yesorno }?,

-   attribute align { "left" | "right" | "center" | "justify" | "char" }?,

-   attribute char { text }?,

-   attribute charoff { text }?,

-   attribute rotate { yesorno }?,

-   attribute valign { "top" | "middle" | "bottom" }?,

-   secur

- # End of DocBook CALS Table Model V4.5 .................................

- 

- # ......................................................................

docbook-schema/dbhierx.rnc
file removed
-1549
@@ -1,1549 +0,0 @@

- # ......................................................................

- 

- # DocBook document hierarchy module V4.5 ...............................

- 

- # File dbhierx.mod .....................................................

- 

- # Copyright 1992-2004 HaL Computer Systems, Inc.,

- # O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software

- # Corporation, Norman Walsh, Sun Microsystems, Inc., and the

- # Organization for the Advancement of Structured Information

- # Standards (OASIS).

- # 

- # $Id: dbhierx.mod 6340 2006-10-03 13:23:24Z nwalsh $

- # 

- # Permission to use, copy, modify and distribute the DocBook DTD

- # and its accompanying documentation for any purpose and without fee

- # is hereby granted in perpetuity, provided that the above copyright

- # notice and this paragraph appear in all copies.  The copyright

- # holders make no representation about the suitability of the DTD for

- # any purpose.  It is provided "as is" without expressed or implied

- # warranty.

- # 

- # If you modify the DocBook DTD in any way, except for declaring and

- # referencing additional sets of general entities and declaring

- # additional notations, label your DTD as a variant of DocBook.  See

- # the maintenance documentation for more information.

- # 

- # Please direct all questions, bug reports, or suggestions for

- # changes to the docbook@lists.oasis-open.org mailing list. For more

- # information, see http://www.oasis-open.org/docbook/.

- 

- # ......................................................................

- 

- # This module contains the definitions for the overall document

- # hierarchies of DocBook documents.  It covers computer documentation

- # manuals and manual fragments, as well as reference entries (such as

- # man pages) and technical journals or anthologies containing

- # articles.

- # 

- # This module depends on the DocBook information pool module.  All

- # elements and entities referenced but not defined here are assumed

- # to be defined in the information pool module.

- # 

- # In DTD driver files referring to this module, please use an entity

- # declaration that uses the public identifier shown below:

- # 

- # <!ENTITY % dbhier PUBLIC

- # "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN"

- # "dbhierx.mod">

- # %dbhier;

- # 

- # See the documentation for detailed information on the parameter

- # entity and module scheme used in DocBook, customizing DocBook and

- # planning for interchange, and changes made since the last release

- # of DocBook.

- 

- # ......................................................................

- 

- # Entities for module inclusions .......................................

- 

- # ......................................................................

- 

- # Entities for element classes .........................................

- 

- local.appendix.class = notAllowed

- appendix.class = appendix | local.appendix.class

- local.article.class = notAllowed

- article.class = article | local.article.class

- local.book.class = notAllowed

- book.class = book | local.book.class

- local.chapter.class = notAllowed

- chapter.class = chapter | local.chapter.class

- local.index.class = notAllowed

- index.class = index | setindex | local.index.class

- local.refentry.class = notAllowed

- refentry.class = refentry | local.refentry.class

- local.section.class = notAllowed

- section.class = section | local.section.class

- local.nav.class = notAllowed

- nav.class =

-   toc | lot | index | glossary | bibliography | local.nav.class

- # Redeclaration placeholder ............................................

- 

- # For redeclaring entities that are declared after this point while

- # retaining their references to the entities that are declared before

- # this point

- 

- # ......................................................................

- 

- # Entities for element mixtures ........................................

- local.divcomponent.mix = notAllowed

- divcomponent.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | formal.class

-   | compound.class

-   | genobj.class

-   | descobj.class

-   | ndxterm.class

-   | beginpage

-   | forms.hook

-   | local.divcomponent.mix

- local.refcomponent.mix = notAllowed

- refcomponent.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | formal.class

-   | compound.class

-   | genobj.class

-   | descobj.class

-   | ndxterm.class

-   | beginpage

-   | forms.hook

-   | local.refcomponent.mix

- local.indexdivcomponent.mix = notAllowed

- indexdivcomponent.mix =

-   itemizedlist

-   | orderedlist

-   | variablelist

-   | simplelist

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | anchor

-   | remark

-   | link.char.class

-   | beginpage

-   | local.indexdivcomponent.mix

- local.refname.char.mix = notAllowed

- refname.char.mix = text | tech.char.class | local.refname.char.mix

- local.partcontent.mix = notAllowed

- partcontent.mix =

-   appendix.class

-   | chapter.class

-   | nav.class

-   | article.class

-   | preface

-   | refentry.class

-   | reference

-   | local.partcontent.mix

- local.refinline.char.mix = notAllowed

- refinline.char.mix =

-   text

-   | xref.char.class

-   | gen.char.class

-   | link.char.class

-   | tech.char.class

-   | base.char.class

-   | docinfo.char.class

-   | other.char.class

-   | ndxterm.class

-   | beginpage

-   | local.refinline.char.mix

- local.refclass.char.mix = notAllowed

- refclass.char.mix = text | application | local.refclass.char.mix

- # Redeclaration placeholder 2 ..........................................

- 

- # For redeclaring entities that are declared after this point while

- # retaining their references to the entities that are declared before

- # this point

- 

- # ......................................................................

- 

- # Entities for content models ..........................................

- div.title.content = title, subtitle?, titleabbrev?

- bookcomponent.title.content = title, subtitle?, titleabbrev?

- sect.title.content = title, subtitle?, titleabbrev?

- refsect.title.content = title, subtitle?, titleabbrev?

- bookcomponent.content =

-   (divcomponent.mix+,

-    (sect1* | refentry.class* | simplesect* | section.class*))

-   | (sect1+ | refentry.class+ | simplesect+ | section.class+)

- # ......................................................................

- 

- # Set and SetInfo ......................................................

- local.set.attrib = empty

- set.role.attrib = role.attrib

- # doc:A collection of books.

- set =

-   element set {

-     set.attlist,

-     div.title.content?,

-     setinfo?,

-     toc?,

-     (set | book.class)+,

-     setindex?

-   }

- # end of set.element

- 

- # FPI: SGML formal public identifier

- set.attlist &=

-   attribute fpi { text }?,

-   status.attrib,

-   common.attrib,

-   set.role.attrib,

-   local.set.attrib

- # end of set.attlist

- 

- # end of set.module

- local.setinfo.attrib = empty

- setinfo.role.attrib = role.attrib

- # doc:Meta-information for a Set.

- setinfo = element setinfo { setinfo.attlist, info.class+ }

- # end of setinfo.element

- 

- # Contents: IDs of the ToC, Books, and SetIndex that comprise

- # the set, in the order of their appearance

- setinfo.attlist &=

-   attribute contents { xsd:IDREFS }?,

-   common.attrib,

-   setinfo.role.attrib,

-   local.setinfo.attrib

- # end of setinfo.attlist

- 

- # end of setinfo.module

- 

- # end of set.content.module

- 

- # ......................................................................

- 

- # Book and BookInfo ....................................................

- local.book.attrib = empty

- book.role.attrib = role.attrib

- # doc:A book.

- book =

-   element book {

-     book.attlist,

-     div.title.content?,

-     bookinfo?,

-     (dedication

-      | toc

-      | lot

-      | glossary

-      | bibliography

-      | preface

-      | chapter.class

-      | reference

-      | part

-      | article.class

-      | appendix.class

-      | index.class

-      | colophon)*

-   }

- # end of book.element

- 

- # FPI: SGML formal public identifier

- book.attlist &=

-   attribute fpi { text }?,

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   book.role.attrib,

-   local.book.attrib

- # end of book.attlist

- 

- # end of book.module

- local.bookinfo.attrib = empty

- bookinfo.role.attrib = role.attrib

- # doc:Meta-information for a Book.

- bookinfo = element bookinfo { bookinfo.attlist, info.class+ }

- # end of bookinfo.element

- 

- # Contents: IDs of the ToC, LoTs, Prefaces, Parts, Chapters,

- # Appendixes, References, GLossary, Bibliography, and indexes

- # comprising the Book, in the order of their appearance

- bookinfo.attlist &=

-   attribute contents { xsd:IDREFS }?,

-   common.attrib,

-   bookinfo.role.attrib,

-   local.bookinfo.attrib

- # end of bookinfo.attlist

- 

- # end of bookinfo.module

- 

- # end of book.content.module

- 

- # ......................................................................

- 

- # Dedication, ToC, and LoT .............................................

- local.dedication.attrib = empty

- dedication.role.attrib = role.attrib

- # doc:A wrapper for the dedication section of a book.

- dedication =

-   element dedication {

-     dedication.attlist, sect.title.content?, legalnotice.mix+

-   }

- # end of dedication.element

- dedication.attlist &=

-   status.attrib,

-   common.attrib,

-   dedication.role.attrib,

-   local.dedication.attrib

- # end of dedication.attlist

- 

- # end of dedication.module

- local.colophon.attrib = empty

- colophon.role.attrib = role.attrib

- # doc:Text at the back of a book describing facts about its production.

- colophon =

-   element colophon {

-     colophon.attlist, sect.title.content?, textobject.mix+

-   }

- # end of colophon.element

- colophon.attlist &=

-   status.attrib,

-   common.attrib,

-   colophon.role.attrib,

-   local.colophon.attrib

- # end of colophon.attlist

- 

- # end of colophon.module

- local.toc.attrib = empty

- toc.role.attrib = role.attrib

- # doc:A table of contents.

- toc =

-   element toc {

-     toc.attlist,

-     beginpage?,

-     bookcomponent.title.content?,

-     tocfront*,

-     (tocpart | tocchap)*,

-     tocback*

-   }

- # end of toc.element

- toc.attlist &=

-   pagenum.attrib, common.attrib, toc.role.attrib, local.toc.attrib

- # end of toc.attlist

- 

- # end of toc.module

- local.tocfront.attrib = empty

- tocfront.role.attrib = role.attrib

- # doc:An entry in a table of contents for a front matter component.

- tocfront = element tocfront { tocfront.attlist, para.char.mix* }

- # end of tocfront.element

- 

- # to element that this entry represents

- tocfront.attlist &=

-   label.attrib,

-   linkend.attrib,

-   pagenum.attrib,

-   common.attrib,

-   tocfront.role.attrib,

-   local.tocfront.attrib

- # end of tocfront.attlist

- 

- # end of tocfront.module

- local.tocentry.attrib = empty

- tocentry.role.attrib = role.attrib

- # doc:A component title in a table of contents.

- tocentry = element tocentry { tocentry.attlist, para.char.mix* }

- # end of tocentry.element

- 

- # to element that this entry represents

- tocentry.attlist &=

-   linkend.attrib,

-   pagenum.attrib,

-   common.attrib,

-   tocentry.role.attrib,

-   local.tocentry.attrib

- # end of tocentry.attlist

- 

- # end of tocentry.module

- local.tocpart.attrib = empty

- tocpart.role.attrib = role.attrib

- # doc:An entry in a table of contents for a part of a book.

- tocpart = element tocpart { tocpart.attlist, tocentry+, tocchap* }

- # end of tocpart.element

- tocpart.attlist &=

-   common.attrib, tocpart.role.attrib, local.tocpart.attrib

- # end of tocpart.attlist

- 

- # end of tocpart.module

- local.tocchap.attrib = empty

- tocchap.role.attrib = role.attrib

- # doc:An entry in a table of contents for a component in the body of a document.

- tocchap = element tocchap { tocchap.attlist, tocentry+, toclevel1* }

- # end of tocchap.element

- tocchap.attlist &=

-   label.attrib, common.attrib, tocchap.role.attrib, local.tocchap.attrib

- # end of tocchap.attlist

- 

- # end of tocchap.module

- local.toclevel1.attrib = empty

- toclevel1.role.attrib = role.attrib

- # doc:A top-level entry within a table of contents entry for a chapter-like component.

- toclevel1 =

-   element toclevel1 { toclevel1.attlist, tocentry+, toclevel2* }

- # end of toclevel1.element

- toclevel1.attlist &=

-   common.attrib, toclevel1.role.attrib, local.toclevel1.attrib

- # end of toclevel1.attlist

- 

- # end of toclevel1.module

- local.toclevel2.attrib = empty

- toclevel2.role.attrib = role.attrib

- # doc:A second-level entry within a table of contents entry for a chapter-like component.

- toclevel2 =

-   element toclevel2 { toclevel2.attlist, tocentry+, toclevel3* }

- # end of toclevel2.element

- toclevel2.attlist &=

-   common.attrib, toclevel2.role.attrib, local.toclevel2.attrib

- # end of toclevel2.attlist

- 

- # end of toclevel2.module

- local.toclevel3.attrib = empty

- toclevel3.role.attrib = role.attrib

- # doc:A third-level entry within a table of contents entry for a chapter-like component.

- toclevel3 =

-   element toclevel3 { toclevel3.attlist, tocentry+, toclevel4* }

- # end of toclevel3.element

- toclevel3.attlist &=

-   common.attrib, toclevel3.role.attrib, local.toclevel3.attrib

- # end of toclevel3.attlist

- 

- # end of toclevel3.module

- local.toclevel4.attrib = empty

- toclevel4.role.attrib = role.attrib

- # doc:A fourth-level entry within a table of contents entry for a chapter-like component.

- toclevel4 =

-   element toclevel4 { toclevel4.attlist, tocentry+, toclevel5* }

- # end of toclevel4.element

- toclevel4.attlist &=

-   common.attrib, toclevel4.role.attrib, local.toclevel4.attrib

- # end of toclevel4.attlist

- 

- # end of toclevel4.module

- local.toclevel5.attrib = empty

- toclevel5.role.attrib = role.attrib

- # doc:A fifth-level entry within a table of contents entry for a chapter-like component.

- toclevel5 = element toclevel5 { toclevel5.attlist, tocentry+ }

- # end of toclevel5.element

- toclevel5.attlist &=

-   common.attrib, toclevel5.role.attrib, local.toclevel5.attrib

- # end of toclevel5.attlist

- 

- # end of toclevel5.module

- local.tocback.attrib = empty

- tocback.role.attrib = role.attrib

- # doc:An entry in a table of contents for a back matter component.

- tocback = element tocback { tocback.attlist, para.char.mix* }

- # end of tocback.element

- 

- # to element that this entry represents

- tocback.attlist &=

-   label.attrib,

-   linkend.attrib,

-   pagenum.attrib,

-   common.attrib,

-   tocback.role.attrib,

-   local.tocback.attrib

- # end of tocback.attlist

- 

- # end of tocback.module

- 

- # end of toc.content.module

- local.lot.attrib = empty

- lot.role.attrib = role.attrib

- # doc:A list of the titles of formal objects (as tables or figures) in a document.

- lot =

-   element lot {

-     lot.attlist, beginpage?, bookcomponent.title.content?, lotentry*

-   }

- # end of lot.element

- lot.attlist &=

-   label.attrib, common.attrib, lot.role.attrib, local.lot.attrib

- # end of lot.attlist

- 

- # end of lot.module

- local.lotentry.attrib = empty

- lotentry.role.attrib = role.attrib

- # doc:An entry in a list of titles.

- lotentry = element lotentry { lotentry.attlist, para.char.mix* }

- # end of lotentry.element

- 

- # SrcCredit: Information about the source of the entry,

- # as for a list of illustrations

- 

- # linkend: to element that this entry represents

- lotentry.attlist &=

-   linkend.attrib,

-   pagenum.attrib,

-   attribute srccredit { text }?,

-   common.attrib,

-   lotentry.role.attrib,

-   local.lotentry.attrib

- # end of lotentry.attlist

- 

- # end of lotentry.module

- 

- # end of lot.content.module

- 

- # ......................................................................

- 

- # Appendix, Chapter, Part, Preface, Reference, PartIntro ...............

- local.appendix.attrib = empty

- appendix.role.attrib = role.attrib

- # doc:An appendix in a Book or Article.

- appendix =

-   element appendix {

-     appendix.attlist,

-     beginpage?,

-     appendixinfo?,

-     bookcomponent.title.content,

-     nav.class*,

-     tocchap?,

-     bookcomponent.content,

-     nav.class*

-   }

- # end of appendix.element

- appendix.attlist &=

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   appendix.role.attrib,

-   local.appendix.attrib

- # end of appendix.attlist

- 

- # end of appendix.module

- local.chapter.attrib = empty

- chapter.role.attrib = role.attrib

- # doc:A chapter, as of a book.

- chapter =

-   element chapter {

-     chapter.attlist,

-     beginpage?,

-     chapterinfo?,

-     bookcomponent.title.content,

-     nav.class*,

-     tocchap?,

-     bookcomponent.content,

-     nav.class*

-   }

- # end of chapter.element

- chapter.attlist &=

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   chapter.role.attrib,

-   local.chapter.attrib

- # end of chapter.attlist

- 

- # end of chapter.module

- 

- # Note that Part was to have its content model reduced in V4.5.  This

- # change will not be made after all.

- local.part.attrib = empty

- part.role.attrib = role.attrib

- # doc:A division in a book.

- part =

-   element part {

-     part.attlist,

-     beginpage?,

-     partinfo?,

-     bookcomponent.title.content,

-     partintro?,

-     partcontent.mix+

-   }

- # end of part.element

- part.attlist &=

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   part.role.attrib,

-   local.part.attrib

- # end of part.attlist

- 

- # ELEMENT PartIntro (defined below)

- 

- # end of part.module

- local.preface.attrib = empty

- preface.role.attrib = role.attrib

- # doc:Introductory matter preceding the first chapter of a book.

- preface =

-   element preface {

-     preface.attlist,

-     beginpage?,

-     prefaceinfo?,

-     bookcomponent.title.content,

-     nav.class*,

-     tocchap?,

-     bookcomponent.content,

-     nav.class*

-   }

- # end of preface.element

- preface.attlist &=

-   status.attrib,

-   common.attrib,

-   preface.role.attrib,

-   local.preface.attrib

- # end of preface.attlist

- 

- # end of preface.module

- local.reference.attrib = empty

- reference.role.attrib = role.attrib

- # doc:A collection of reference entries.

- reference =

-   element reference {

-     reference.attlist,

-     beginpage?,

-     referenceinfo?,

-     bookcomponent.title.content,

-     partintro?,

-     refentry.class+

-   }

- # end of reference.element

- reference.attlist &=

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   reference.role.attrib,

-   local.reference.attrib

- # end of reference.attlist

- 

- # ELEMENT PartIntro (defined below)

- 

- # end of reference.module

- local.partintro.attrib = empty

- partintro.role.attrib = role.attrib

- # doc:An introduction to the contents of a part.

- partintro =

-   element partintro {

-     partintro.attlist, div.title.content?, bookcomponent.content

-   }

- # end of partintro.element

- partintro.attlist &=

-   label.attrib,

-   common.attrib,

-   partintro.role.attrib,

-   local.partintro.attrib

- # end of partintro.attlist

- 

- # end of partintro.module

- 

- # ......................................................................

- 

- # Other Info elements ..................................................

- local.appendixinfo.attrib = empty

- appendixinfo.role.attrib = role.attrib

- # doc:Meta-information for an Appendix.

- appendixinfo =

-   element appendixinfo { appendixinfo.attlist, info.class+ }

- # end of appendixinfo.element

- appendixinfo.attlist &=

-   common.attrib, appendixinfo.role.attrib, local.appendixinfo.attrib

- # end of appendixinfo.attlist

- 

- # end of appendixinfo.module

- local.bibliographyinfo.attrib = empty

- bibliographyinfo.role.attrib = role.attrib

- # doc:Meta-information for a Bibliography.

- bibliographyinfo =

-   element bibliographyinfo { bibliographyinfo.attlist, info.class+ }

- # end of bibliographyinfo.element

- bibliographyinfo.attlist &=

-   common.attrib,

-   bibliographyinfo.role.attrib,

-   local.bibliographyinfo.attrib

- # end of bibliographyinfo.attlist

- 

- # end of bibliographyinfo.module

- local.chapterinfo.attrib = empty

- chapterinfo.role.attrib = role.attrib

- # doc:Meta-information for a Chapter.

- chapterinfo = element chapterinfo { chapterinfo.attlist, info.class+ }

- # end of chapterinfo.element

- chapterinfo.attlist &=

-   common.attrib, chapterinfo.role.attrib, local.chapterinfo.attrib

- # end of chapterinfo.attlist

- 

- # end of chapterinfo.module

- local.glossaryinfo.attrib = empty

- glossaryinfo.role.attrib = role.attrib

- # doc:Meta-information for a Glossary.

- glossaryinfo =

-   element glossaryinfo { glossaryinfo.attlist, info.class+ }

- # end of glossaryinfo.element

- glossaryinfo.attlist &=

-   common.attrib, glossaryinfo.role.attrib, local.glossaryinfo.attrib

- # end of glossaryinfo.attlist

- 

- # end of glossaryinfo.module

- local.indexinfo.attrib = empty

- indexinfo.role.attrib = role.attrib

- # doc:Meta-information for an Index.

- indexinfo = element indexinfo { indexinfo.attlist, info.class+ }

- # end of indexinfo.element

- indexinfo.attlist &=

-   common.attrib, indexinfo.role.attrib, local.indexinfo.attrib

- # end of indexinfo.attlist

- 

- # end of indexinfo.module

- local.setindexinfo.attrib = empty

- setindexinfo.role.attrib = role.attrib

- # doc:Meta-information for a SetIndex.

- setindexinfo =

-   element setindexinfo { setindexinfo.attlist, info.class+ }

- # end of setindexinfo.element

- setindexinfo.attlist &=

-   common.attrib, setindexinfo.role.attrib, local.setindexinfo.attrib

- # end of setindexinfo.attlist

- 

- # end of setindexinfo.module

- local.partinfo.attrib = empty

- partinfo.role.attrib = role.attrib

- # doc:Meta-information for a Part.

- partinfo = element partinfo { partinfo.attlist, info.class+ }

- # end of partinfo.element

- partinfo.attlist &=

-   common.attrib, partinfo.role.attrib, local.partinfo.attrib

- # end of partinfo.attlist

- 

- # end of partinfo.module

- local.prefaceinfo.attrib = empty

- prefaceinfo.role.attrib = role.attrib

- # doc:Meta-information for a Preface.

- prefaceinfo = element prefaceinfo { prefaceinfo.attlist, info.class+ }

- # end of prefaceinfo.element

- prefaceinfo.attlist &=

-   common.attrib, prefaceinfo.role.attrib, local.prefaceinfo.attrib

- # end of prefaceinfo.attlist

- 

- # end of prefaceinfo.module

- local.refentryinfo.attrib = empty

- refentryinfo.role.attrib = role.attrib

- # doc:Meta-information for a Refentry.

- refentryinfo =

-   element refentryinfo { refentryinfo.attlist, info.class+ }

- # end of refentryinfo.element

- refentryinfo.attlist &=

-   common.attrib, refentryinfo.role.attrib, local.refentryinfo.attrib

- # end of refentryinfo.attlist

- 

- # end of refentryinfo.module

- local.refsectioninfo.attrib = empty

- refsectioninfo.role.attrib = role.attrib

- # doc:Meta-information for a refsection.

- refsectioninfo =

-   element refsectioninfo { refsectioninfo.attlist, info.class+ }

- # end of refsectioninfo.element

- refsectioninfo.attlist &=

-   common.attrib, refsectioninfo.role.attrib, local.refsectioninfo.attrib

- # end of refsectioninfo.attlist

- 

- # end of refsectioninfo.module

- local.refsect1info.attrib = empty

- refsect1info.role.attrib = role.attrib

- # doc:Meta-information for a RefSect1.

- refsect1info =

-   element refsect1info { refsect1info.attlist, info.class+ }

- # end of refsect1info.element

- refsect1info.attlist &=

-   common.attrib, refsect1info.role.attrib, local.refsect1info.attrib

- # end of refsect1info.attlist

- 

- # end of refsect1info.module

- local.refsect2info.attrib = empty

- refsect2info.role.attrib = role.attrib

- # doc:Meta-information for a RefSect2.

- refsect2info =

-   element refsect2info { refsect2info.attlist, info.class+ }

- # end of refsect2info.element

- refsect2info.attlist &=

-   common.attrib, refsect2info.role.attrib, local.refsect2info.attrib

- # end of refsect2info.attlist

- 

- # end of refsect2info.module

- local.refsect3info.attrib = empty

- refsect3info.role.attrib = role.attrib

- # doc:Meta-information for a RefSect3.

- refsect3info =

-   element refsect3info { refsect3info.attlist, info.class+ }

- # end of refsect3info.element

- refsect3info.attlist &=

-   common.attrib, refsect3info.role.attrib, local.refsect3info.attrib

- # end of refsect3info.attlist

- 

- # end of refsect3info.module

- local.refsynopsisdivinfo.attrib = empty

- refsynopsisdivinfo.role.attrib = role.attrib

- # doc:Meta-information for a RefSynopsisDiv.

- refsynopsisdivinfo =

-   element refsynopsisdivinfo { refsynopsisdivinfo.attlist, info.class+ }

- # end of refsynopsisdivinfo.element

- refsynopsisdivinfo.attlist &=

-   common.attrib,

-   refsynopsisdivinfo.role.attrib,

-   local.refsynopsisdivinfo.attrib

- # end of refsynopsisdivinfo.attlist

- 

- # end of refsynopsisdivinfo.module

- local.referenceinfo.attrib = empty

- referenceinfo.role.attrib = role.attrib

- # doc:Meta-information for a Reference.

- referenceinfo =

-   element referenceinfo { referenceinfo.attlist, info.class+ }

- # end of referenceinfo.element

- referenceinfo.attlist &=

-   common.attrib, referenceinfo.role.attrib, local.referenceinfo.attrib

- # end of referenceinfo.attlist

- 

- # end of referenceinfo.module

- local.sect1info.attrib = empty

- sect1info.role.attrib = role.attrib

- # doc:Meta-information for a Sect1.

- sect1info = element sect1info { sect1info.attlist, info.class+ }

- # end of sect1info.element

- sect1info.attlist &=

-   common.attrib, sect1info.role.attrib, local.sect1info.attrib

- # end of sect1info.attlist

- local.sect2info.attrib = empty

- sect2info.role.attrib = role.attrib

- # doc:Meta-information for a Sect2.

- sect2info = element sect2info { sect2info.attlist, info.class+ }

- # end of sect2info.element

- sect2info.attlist &=

-   common.attrib, sect2info.role.attrib, local.sect2info.attrib

- # end of sect2info.attlist

- local.sect3info.attrib = empty

- sect3info.role.attrib = role.attrib

- # doc:Meta-information for a Sect3.

- sect3info = element sect3info { sect3info.attlist, info.class+ }

- # end of sect3info.element

- sect3info.attlist &=

-   common.attrib, sect3info.role.attrib, local.sect3info.attrib

- # end of sect3info.attlist

- local.sect4info.attrib = empty

- sect4info.role.attrib = role.attrib

- # doc:Meta-information for a Sect4.

- sect4info = element sect4info { sect4info.attlist, info.class+ }

- # end of sect4info.element

- sect4info.attlist &=

-   common.attrib, sect4info.role.attrib, local.sect4info.attrib

- # end of sect4info.attlist

- local.sect5info.attrib = empty

- sect5info.role.attrib = role.attrib

- # doc:Meta-information for a Sect5.

- sect5info = element sect5info { sect5info.attlist, info.class+ }

- # end of sect5info.element

- sect5info.attlist &=

-   common.attrib, sect5info.role.attrib, local.sect5info.attrib

- # end of sect5info.attlist

- 

- # ......................................................................

- 

- # Section (parallel to Sect*) .........................................

- local.section.attrib = empty

- section.role.attrib = role.attrib

- # doc:A recursive section.

- section =

-   element section {

-     section.attlist,

-     sectioninfo?,

-     sect.title.content,

-     nav.class*,

-     ((divcomponent.mix+,

-       (refentry.class* | section.class* | simplesect*))

-      | refentry.class+

-      | section.class+

-      | simplesect+),

-     nav.class*

-   }

- # end of section.element

- section.attlist &=

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   section.role.attrib,

-   local.section.attrib

- # end of section.attlist

- 

- # end of section.module

- sectioninfo.role.attrib = role.attrib

- local.sectioninfo.attrib = empty

- # doc:Meta-information for a recursive section.

- sectioninfo = element sectioninfo { sectioninfo.attlist, info.class+ }

- # end of sectioninfo.element

- sectioninfo.attlist &=

-   common.attrib, sectioninfo.role.attrib, local.sectioninfo.attrib

- # end of sectioninfo.attlist

- 

- # end of sectioninfo.module

- 

- # end of section.content.module

- 

- # ......................................................................

- 

- # Sect1, Sect2, Sect3, Sect4, Sect5 ....................................

- local.sect1.attrib = empty

- sect1.role.attrib = role.attrib

- # doc:A top-level section of document.

- sect1 =

-   element sect1 {

-     sect1.attlist,

-     sect1info?,

-     sect.title.content,

-     nav.class*,

-     ((divcomponent.mix+, (refentry.class* | sect2* | simplesect*))

-      | refentry.class+

-      | sect2+

-      | simplesect+),

-     nav.class*

-   }

- # end of sect1.element

- 

- # Renderas: Indicates the format in which the heading should

- # appear

- sect1.attlist &=

-   attribute renderas { "sect2" | "sect3" | "sect4" | "sect5" }?,

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   sect1.role.attrib,

-   local.sect1.attrib

- # end of sect1.attlist

- 

- # end of sect1.module

- local.sect2.attrib = empty

- sect2.role.attrib = role.attrib

- # doc:A subsection within a Sect1.

- sect2 =

-   element sect2 {

-     sect2.attlist,

-     sect2info?,

-     sect.title.content,

-     nav.class*,

-     ((divcomponent.mix+, (refentry.class* | sect3* | simplesect*))

-      | refentry.class+

-      | sect3+

-      | simplesect+),

-     nav.class*

-   }

- # end of sect2.element

- 

- # Renderas: Indicates the format in which the heading should

- # appear

- sect2.attlist &=

-   attribute renderas { "sect1" | "sect3" | "sect4" | "sect5" }?,

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   sect2.role.attrib,

-   local.sect2.attrib

- # end of sect2.attlist

- 

- # end of sect2.module

- local.sect3.attrib = empty

- sect3.role.attrib = role.attrib

- # doc:A subsection within a Sect2.

- sect3 =

-   element sect3 {

-     sect3.attlist,

-     sect3info?,

-     sect.title.content,

-     nav.class*,

-     ((divcomponent.mix+, (refentry.class* | sect4* | simplesect*))

-      | refentry.class+

-      | sect4+

-      | simplesect+),

-     nav.class*

-   }

- # end of sect3.element

- 

- # Renderas: Indicates the format in which the heading should

- # appear

- sect3.attlist &=

-   attribute renderas { "sect1" | "sect2" | "sect4" | "sect5" }?,

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   sect3.role.attrib,

-   local.sect3.attrib

- # end of sect3.attlist

- 

- # end of sect3.module

- local.sect4.attrib = empty

- sect4.role.attrib = role.attrib

- # doc:A subsection within a Sect3.

- sect4 =

-   element sect4 {

-     sect4.attlist,

-     sect4info?,

-     sect.title.content,

-     nav.class*,

-     ((divcomponent.mix+, (refentry.class* | sect5* | simplesect*))

-      | refentry.class+

-      | sect5+

-      | simplesect+),

-     nav.class*

-   }

- # end of sect4.element

- 

- # Renderas: Indicates the format in which the heading should

- # appear

- sect4.attlist &=

-   attribute renderas { "sect1" | "sect2" | "sect3" | "sect5" }?,

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   sect4.role.attrib,

-   local.sect4.attrib

- # end of sect4.attlist

- 

- # end of sect4.module

- local.sect5.attrib = empty

- sect5.role.attrib = role.attrib

- # doc:A subsection within a Sect4.

- sect5 =

-   element sect5 {

-     sect5.attlist,

-     sect5info?,

-     sect.title.content,

-     nav.class*,

-     ((divcomponent.mix+, (refentry.class* | simplesect*))

-      | refentry.class+

-      | simplesect+),

-     nav.class*

-   }

- # end of sect5.element

- 

- # Renderas: Indicates the format in which the heading should

- # appear

- sect5.attlist &=

-   attribute renderas { "sect1" | "sect2" | "sect3" | "sect4" }?,

-   label.attrib,

-   status.attrib,

-   common.attrib,

-   sect5.role.attrib,

-   local.sect5.attrib

- # end of sect5.attlist

- 

- # end of sect5.module

- local.simplesect.attrib = empty

- simplesect.role.attrib = role.attrib

- # doc:A section of a document with no subdivisions.

- simplesect =

-   element simplesect {

-     simplesect.attlist, sect.title.content, divcomponent.mix+

-   }

- # end of simplesect.element

- simplesect.attlist &=

-   common.attrib, simplesect.role.attrib, local.simplesect.attrib

- # end of simplesect.attlist

- 

- # end of simplesect.module

- 

- # ......................................................................

- 

- # Bibliography .........................................................

- local.bibliography.attrib = empty

- bibliography.role.attrib = role.attrib

- # doc:A bibliography.

- bibliography =

-   element bibliography {

-     bibliography.attlist,

-     bibliographyinfo?,

-     bookcomponent.title.content?,

-     component.mix*,

-     (bibliodiv+ | (biblioentry | bibliomixed)+)

-   }

- # end of bibliography.element

- bibliography.attlist &=

-   status.attrib,

-   common.attrib,

-   bibliography.role.attrib,

-   local.bibliography.attrib

- # end of bibliography.attlist

- 

- # end of bibliography.module

- local.bibliodiv.attrib = empty

- bibliodiv.role.attrib = role.attrib

- # doc:A section of a Bibliography.

- bibliodiv =

-   element bibliodiv {

-     bibliodiv.attlist,

-     sect.title.content?,

-     component.mix*,

-     (biblioentry | bibliomixed)+

-   }

- # end of bibliodiv.element

- bibliodiv.attlist &=

-   status.attrib,

-   common.attrib,

-   bibliodiv.role.attrib,

-   local.bibliodiv.attrib

- # end of bibliodiv.attlist

- 

- # end of bibliodiv.module

- 

- # end of bibliography.content.module

- 

- # ......................................................................

- 

- # Glossary .............................................................

- local.glossary.attrib = empty

- glossary.role.attrib = role.attrib

- # doc:A glossary.

- glossary =

-   element glossary {

-     glossary.attlist,

-     glossaryinfo?,

-     bookcomponent.title.content?,

-     component.mix*,

-     (glossdiv+ | glossentry+),

-     bibliography?

-   }

- # end of glossary.element

- glossary.attlist &=

-   status.attrib,

-   common.attrib,

-   glossary.role.attrib,

-   local.glossary.attrib

- # end of glossary.attlist

- 

- # end of glossary.module

- local.glossdiv.attrib = empty

- glossdiv.role.attrib = role.attrib

- # doc:A division in a Glossary.

- glossdiv =

-   element glossdiv {

-     glossdiv.attlist, sect.title.content, component.mix*, glossentry+

-   }

- # end of glossdiv.element

- glossdiv.attlist &=

-   status.attrib,

-   common.attrib,

-   glossdiv.role.attrib,

-   local.glossdiv.attrib

- # end of glossdiv.attlist

- 

- # end of glossdiv.module

- 

- # end of glossary.content.module

- 

- # ......................................................................

- 

- # Index and SetIndex ...................................................

- local.indexes.attrib = empty

- indexes.role.attrib = role.attrib

- # doc:An index.

- index =

-   element index {

-     index.attlist,

-     indexinfo?,

-     bookcomponent.title.content?,

-     component.mix*,

-     (indexdiv* | indexentry*)

-   }

- # end of index.element

- index.attlist &=

-   attribute type { text }?,

-   common.attrib,

-   indexes.role.attrib,

-   local.indexes.attrib

- # end of index.attlist

- 

- # doc:An index to a set of books.

- setindex =

-   element setindex {

-     setindex.attlist,

-     setindexinfo?,

-     bookcomponent.title.content?,

-     component.mix*,

-     (indexdiv* | indexentry*)

-   }

- # end of setindex.element

- setindex.attlist &=

-   common.attrib, indexes.role.attrib, local.indexes.attrib

- # end of setindex.attlist

- 

- # end of indexes.module

- 

- # SegmentedList in this content is useful for marking up permuted

- # indices.

- local.indexdiv.attrib = empty

- indexdiv.role.attrib = role.attrib

- # doc:A division in an index.

- indexdiv =

-   element indexdiv {

-     indexdiv.attlist,

-     sect.title.content?,

-     (indexdivcomponent.mix*, (indexentry+ | segmentedlist))

-   }

- # end of indexdiv.element

- indexdiv.attlist &=

-   common.attrib, indexdiv.role.attrib, local.indexdiv.attrib

- # end of indexdiv.attlist

- 

- # end of indexdiv.module

- 

- # Index entries appear in the index, not the text.

- local.indexentry.attrib = empty

- indexentry.role.attrib = role.attrib

- # doc:An entry in an index.

- indexentry =

-   element indexentry {

-     indexentry.attlist,

-     primaryie,

-     (seeie | seealsoie)*,

-     (secondaryie, (seeie | seealsoie | tertiaryie)*)*

-   }

- # end of indexentry.element

- indexentry.attlist &=

-   common.attrib, indexentry.role.attrib, local.indexentry.attrib

- # end of indexentry.attlist

- 

- # end of indexentry.module

- local.primsecterie.attrib = empty

- primsecterie.role.attrib = role.attrib

- # doc:A primary term in an index entry, not in the text.

- primaryie = element primaryie { primaryie.attlist, ndxterm.char.mix* }

- # end of primaryie.element

- 

- # to IndexTerms that these entries represent

- primaryie.attlist &=

-   linkends.attrib,

-   common.attrib,

-   primsecterie.role.attrib,

-   local.primsecterie.attrib

- # end of primaryie.attlist

- 

- # doc:A secondary term in an index entry, rather than in the text.

- secondaryie =

-   element secondaryie { secondaryie.attlist, ndxterm.char.mix* }

- # end of secondaryie.element

- 

- # to IndexTerms that these entries represent

- secondaryie.attlist &=

-   linkends.attrib,

-   common.attrib,

-   primsecterie.role.attrib,

-   local.primsecterie.attrib

- # end of secondaryie.attlist

- 

- # doc:A tertiary term in an index entry, rather than in the text.

- tertiaryie =

-   element tertiaryie { tertiaryie.attlist, ndxterm.char.mix* }

- # end of tertiaryie.element

- 

- # to IndexTerms that these entries represent

- tertiaryie.attlist &=

-   linkends.attrib,

-   common.attrib,

-   primsecterie.role.attrib,

-   local.primsecterie.attrib

- # end of tertiaryie.attlist

- 

- # end of primsecterie.module

- local.seeie.attrib = empty

- seeie.role.attrib = role.attrib

- # doc:A See entry in an index, rather than in the text.

- seeie = element seeie { seeie.attlist, ndxterm.char.mix* }

- # end of seeie.element

- 

- # to IndexEntry to look up

- seeie.attlist &=

-   linkend.attrib, common.attrib, seeie.role.attrib, local.seeie.attrib

- # end of seeie.attlist

- 

- # end of seeie.module

- local.seealsoie.attrib = empty

- seealsoie.role.attrib = role.attrib

- # doc:A See also entry in an index, rather than in the text.

- seealsoie = element seealsoie { seealsoie.attlist, ndxterm.char.mix* }

- # end of seealsoie.element

- 

- # to related IndexEntries

- seealsoie.attlist &=

-   linkends.attrib,

-   common.attrib,

-   seealsoie.role.attrib,

-   local.seealsoie.attrib

- # end of seealsoie.attlist

- 

- # end of seealsoie.module

- 

- # end of index.content.module

- 

- # ......................................................................

- 

- # RefEntry .............................................................

- local.refentry.attrib = empty

- refentry.role.attrib = role.attrib

- # doc:A reference page (originally a UNIX man-style reference page).

- refentry =

-   element refentry {

-     refentry.attlist,

-     beginpage?,

-     ndxterm.class*,

-     refentryinfo?,

-     refmeta?,

-     (remark | link.char.class)*,

-     refnamediv+,

-     refsynopsisdiv?,

-     (refsect1+ | refsection+)

-   }

- # end of refentry.element

- refentry.attlist &=

-   status.attrib,

-   common.attrib,

-   refentry.role.attrib,

-   local.refentry.attrib

- # end of refentry.attlist

- 

- # end of refentry.module

- local.refmeta.attrib = empty

- refmeta.role.attrib = role.attrib

- # doc:Meta-information for a reference entry.

- refmeta =

-   element refmeta {

-     refmeta.attlist,

-     ndxterm.class*,

-     refentrytitle,

-     manvolnum?,

-     refmiscinfo*,

-     ndxterm.class*

-   }

- # end of refmeta.element

- refmeta.attlist &=

-   common.attrib, refmeta.role.attrib, local.refmeta.attrib

- # end of refmeta.attlist

- 

- # end of refmeta.module

- local.refmiscinfo.attrib = empty

- refmiscinfo.role.attrib = role.attrib

- # doc:Meta-information for a reference entry other than the title and volume number.

- refmiscinfo =

-   element refmiscinfo { refmiscinfo.attlist, docinfo.char.mix* }

- # end of refmiscinfo.element

- 

- # Class: Freely assignable parameter; no default

- refmiscinfo.attlist &=

-   attribute class { text }?,

-   common.attrib,

-   refmiscinfo.role.attrib,

-   local.refmiscinfo.attrib

- # end of refmiscinfo.attlist

- 

- # end of refmiscinfo.module

- local.refnamediv.attrib = empty

- refnamediv.role.attrib = role.attrib

- # doc:The name, purpose, and classification of a reference page.

- refnamediv =

-   element refnamediv {

-     refnamediv.attlist,

-     refdescriptor?,

-     refname+,

-     refpurpose,

-     refclass*,

-     (remark | link.char.class)*

-   }

- # end of refnamediv.element

- refnamediv.attlist &=

-   common.attrib, refnamediv.role.attrib, local.refnamediv.attrib

- # end of refnamediv.attlist

- 

- # end of refnamediv.module

- local.refdescriptor.attrib = empty

- refdescriptor.role.attrib = role.attrib

- # doc:A description of the topic of a reference page.

- refdescriptor =

-   element refdescriptor { refdescriptor.attlist, refname.char.mix* }

- # end of refdescriptor.element

- refdescriptor.attlist &=

-   common.attrib, refdescriptor.role.attrib, local.refdescriptor.attrib

- # end of refdescriptor.attlist

- 

- # end of refdescriptor.module

- local.refname.attrib = empty

- refname.role.attrib = role.attrib

- # doc:The name of (one of) the subject(s) of a reference page.

- refname = element refname { refname.attlist, refname.char.mix* }

- # end of refname.element

- refname.attlist &=

-   common.attrib, refname.role.attrib, local.refname.attrib

- # end of refname.attlist

- 

- # end of refname.module

- local.refpurpose.attrib = empty

- refpurpose.role.attrib = role.attrib

- # doc:A short (one sentence) synopsis of the topic of a reference page.

- refpurpose =

-   element refpurpose { refpurpose.attlist, refinline.char.mix* }

- # end of refpurpose.element

- refpurpose.attlist &=

-   common.attrib, refpurpose.role.attrib, local.refpurpose.attrib

- # end of refpurpose.attlist

- 

- # end of refpurpose.module

- local.refclass.attrib = empty

- refclass.role.attrib = role.attrib

- # doc:The scope or other indication of applicability of a reference entry.

- refclass = element refclass { refclass.attlist, refclass.char.mix* }

- # end of refclass.element

- refclass.attlist &=

-   common.attrib, refclass.role.attrib, local.refclass.attrib

- # end of refclass.attlist

- 

- # end of refclass.module

- local.refsynopsisdiv.attrib = empty

- refsynopsisdiv.role.attrib = role.attrib

- # doc:A syntactic synopsis of the subject of the reference page.

- refsynopsisdiv =

-   element refsynopsisdiv {

-     refsynopsisdiv.attlist,

-     refsynopsisdivinfo?,

-     refsect.title.content?,

-     ((refcomponent.mix+, refsect2*) | refsect2+)

-   }

- # end of refsynopsisdiv.element

- refsynopsisdiv.attlist &=

-   common.attrib, refsynopsisdiv.role.attrib, local.refsynopsisdiv.attrib

- # end of refsynopsisdiv.attlist

- 

- # end of refsynopsisdiv.module

- local.refsection.attrib = empty

- refsection.role.attrib = role.attrib

- # doc:A recursive section in a refentry.

- refsection =

-   element refsection {

-     refsection.attlist,

-     refsectioninfo?,

-     refsect.title.content,

-     ((refcomponent.mix+, refsection*) | refsection+)

-   }

- # end of refsection.element

- refsection.attlist &=

-   status.attrib,

-   common.attrib,

-   refsection.role.attrib,

-   local.refsection.attrib

- # end of refsection.attlist

- 

- # end of refsection.module

- local.refsect1.attrib = empty

- refsect1.role.attrib = role.attrib

- # doc:A major subsection of a reference entry.

- refsect1 =

-   element refsect1 {

-     refsect1.attlist,

-     refsect1info?,

-     refsect.title.content,

-     ((refcomponent.mix+, refsect2*) | refsect2+)

-   }

- # end of refsect1.element

- refsect1.attlist &=

-   status.attrib,

-   common.attrib,

-   refsect1.role.attrib,

-   local.refsect1.attrib

- # end of refsect1.attlist

- 

- # end of refsect1.module

- local.refsect2.attrib = empty

- refsect2.role.attrib = role.attrib

- # doc:A subsection of a RefSect1.

- refsect2 =

-   element refsect2 {

-     refsect2.attlist,

-     refsect2info?,

-     refsect.title.content,

-     ((refcomponent.mix+, refsect3*) | refsect3+)

-   }

- # end of refsect2.element

- refsect2.attlist &=

-   status.attrib,

-   common.attrib,

-   refsect2.role.attrib,

-   local.refsect2.attrib

- # end of refsect2.attlist

- 

- # end of refsect2.module

- local.refsect3.attrib = empty

- refsect3.role.attrib = role.attrib

- # doc:A subsection of a RefSect2.

- refsect3 =

-   element refsect3 {

-     refsect3.attlist,

-     refsect3info?,

-     refsect.title.content,

-     refcomponent.mix+

-   }

- # end of refsect3.element

- refsect3.attlist &=

-   status.attrib,

-   common.attrib,

-   refsect3.role.attrib,

-   local.refsect3.attrib

- # end of refsect3.attlist

- 

- # end of refsect3.module

- 

- # end of refentry.content.module

- 

- # ......................................................................

- 

- # Article ..............................................................

- 

- # An Article is a chapter-level, stand-alone document that is often,

- # but need not be, collected into a Book.

- local.article.attrib = empty

- article.role.attrib = role.attrib

- # doc:An article.

- article =

-   element article {

-     article.attlist,

-     div.title.content?,

-     articleinfo?,

-     tocchap?,

-     lot*,

-     bookcomponent.content,

-     (nav.class | appendix.class | colophon | ackno)*

-   }

- # end of article.element

- 

- # Class: Indicates the type of a particular article;

- # all articles have the same structure and general purpose.

- # No default.

- 

- # ParentBook: ID of the enclosing Book

- article.attlist &=

-   attribute class {

-     "journalarticle"

-     | "productsheet"

-     | "whitepaper"

-     | "techreport"

-     | "specification"

-     | "faq"

-   }?,

-   attribute parentbook { xsd:IDREF }?,

-   status.attrib,

-   common.attrib,

-   article.role.attrib,

-   local.article.attrib

- # end of article.attlist

- 

- # end of article.module

- 

- # End of DocBook document hierarchy module V4.5 ........................

- 

- # ......................................................................

docbook-schema/dbnotnx.rnc
file removed
-85
@@ -1,85 +0,0 @@

- # ......................................................................

- 

- # DocBook notations module V4.5 ........................................

- 

- # File dbnotnx.mod .....................................................

- 

- # Copyright 1992-2004 HaL Computer Systems, Inc.,

- # O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software

- # Corporation, Norman Walsh, Sun Microsystems, Inc., and the

- # Organization for the Advancement of Structured Information

- # Standards (OASIS).

- # 

- # $Id: dbnotnx.mod 6340 2006-10-03 13:23:24Z nwalsh $

- # 

- # Permission to use, copy, modify and distribute the DocBook DTD

- # and its accompanying documentation for any purpose and without fee

- # is hereby granted in perpetuity, provided that the above copyright

- # notice and this paragraph appear in all copies.  The copyright

- # holders make no representation about the suitability of the DTD for

- # any purpose.  It is provided "as is" without expressed or implied

- # warranty.

- # 

- # If you modify the DocBook DTD in any way, except for declaring and

- # referencing additional sets of general entities and declaring

- # additional notations, label your DTD as a variant of DocBook.  See

- # the maintenance documentation for more information.

- # 

- # Please direct all questions, bug reports, or suggestions for

- # changes to the docbook@lists.oasis-open.org mailing list. For more

- # information, see http://www.oasis-open.org/docbook/.

- 

- # ......................................................................

- 

- # This module contains the notation declarations used by DocBook.

- # 

- # In DTD driver files referring to this module, please use an entity

- # declaration that uses the public identifier shown below:

- # 

- # <!ENTITY % dbnotn PUBLIC

- # "-//OASIS//ENTITIES DocBook Notations V4.5//EN"

- # "dbnotnx.mod">

- # %dbnotn;

- # 

- # See the documentation for detailed information on the parameter

- # entity and module scheme used in DocBook, customizing DocBook and

- # planning for interchange, and changes made since the last release

- # of DocBook.

- 

- local.notation.class = notAllowed

- notation.class =

-   "BMP"

-   | "CGM-CHAR"

-   | "CGM-BINARY"

-   | "CGM-CLEAR"

-   | "DITROFF"

-   | "DVI"

-   | "EPS"

-   | "EQN"

-   | "FAX"

-   | "GIF"

-   | "GIF87a"

-   | "GIF89a"

-   | "JPG"

-   | "JPEG"

-   | "IGES"

-   | "PCX"

-   | "PIC"

-   | "PNG"

-   | "PS"

-   | "SGML"

-   | "TBL"

-   | "TEX"

-   | "TIFF"

-   | "WMF"

-   | "WPG"

-   | "SVG"

-   | "PDF"

-   | "SWF"

-   | "linespecific"

-   | local.notation.class

- # WordPerfect Graphic format

- 

- # End of DocBook notations module V4.5 .................................

- 

- # ......................................................................

docbook-schema/dbpoolx.rnc
file removed
-5785
@@ -1,5785 +0,0 @@

- # ......................................................................

- 

- # DocBook XML information pool module V4.5 .............................

- 

- # File dbpoolx.mod .....................................................

- 

- # Copyright 1992-2004 HaL Computer Systems, Inc.,

- # O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software

- # Corporation, Norman Walsh, Sun Microsystems, Inc., and the

- # Organization for the Advancement of Structured Information

- # Standards (OASIS).

- # 

- # $Id: dbpoolx.mod 6340 2006-10-03 13:23:24Z nwalsh $

- # 

- # Permission to use, copy, modify and distribute the DocBook XML DTD

- # and its accompanying documentation for any purpose and without fee

- # is hereby granted in perpetuity, provided that the above copyright

- # notice and this paragraph appear in all copies.  The copyright

- # holders make no representation about the suitability of the DTD for

- # any purpose.  It is provided "as is" without expressed or implied

- # warranty.

- # 

- # If you modify the DocBook XML DTD in any way, except for declaring and

- # referencing additional sets of general entities and declaring

- # additional notations, label your DTD as a variant of DocBook.  See

- # the maintenance documentation for more information.

- # 

- # Please direct all questions, bug reports, or suggestions for

- # changes to the docbook@lists.oasis-open.org mailing list. For more

- # information, see http://www.oasis-open.org/docbook/.

- 

- # ......................................................................

- 

- # This module contains the definitions for the objects, inline

- # elements, and so on that are available to be used as the main

- # content of DocBook documents.  Some elements are useful for general

- # publishing, and others are useful specifically for computer

- # documentation.

- # 

- # This module has the following dependencies on other modules:

- # 

- # o It assumes that a %notation.class; entity is defined by the

- #   driver file or other high-level module.  This entity is

- #   referenced in the NOTATION attributes for the graphic-related and

- #   ModeSpec elements.

- # 

- # o It assumes that an appropriately parameterized table module is

- #   available for use with the table-related elements.

- # 

- # In DTD driver files referring to this module, please use an entity

- # declaration that uses the public identifier shown below:

- # 

- # <!ENTITY % dbpool PUBLIC

- # "-//OASIS//ELEMENTS DocBook XML Information Pool V4.5//EN"

- # "dbpoolx.mod">

- # %dbpool;

- # 

- # See the documentation for detailed information on the parameter

- # entity and module scheme used in DocBook, customizing DocBook and

- # planning for interchange, and changes made since the last release

- # of DocBook.

- 

- # ......................................................................

- 

- # Forms entities .......................................................

- 

- # These PEs provide the hook by which the forms module can be inserted

- 

- # into the DTD.

- 

- namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"

- 

- forminlines.hook = notAllowed

- forms.hook = notAllowed

- # ......................................................................

- 

- # General-purpose semantics entities ...................................

- yesorno.attvals = string

- # ......................................................................

- 

- # Entities for module inclusions .......................................

- 

- # ......................................................................

- 

- # Entities for element classes and mixtures ............................

- 

- # "Ubiquitous" classes: ndxterm.class and beginpage

- local.ndxterm.class = notAllowed

- ndxterm.class = indexterm | local.ndxterm.class

- # Object-level classes .................................................

- local.list.class = notAllowed

- list.class =

-   calloutlist

-   | glosslist

-   | bibliolist

-   | itemizedlist

-   | orderedlist

-   | segmentedlist

-   | simplelist

-   | variablelist

-   | local.list.class

- local.admon.class = notAllowed

- admon.class =

-   caution | important | note | tip | warning | local.admon.class

- local.linespecific.class = notAllowed

- linespecific.class =

-   literallayout

-   | programlisting

-   | programlistingco

-   | screen

-   | screenco

-   | screenshot

-   | local.linespecific.class

- local.method.synop.class = notAllowed

- method.synop.class =

-   constructorsynopsis

-   | destructorsynopsis

-   | methodsynopsis

-   | local.method.synop.class

- local.synop.class = notAllowed

- synop.class =

-   synopsis

-   | cmdsynopsis

-   | funcsynopsis

-   | classsynopsis

-   | fieldsynopsis

-   | method.synop.class

-   | local.synop.class

- local.para.class = notAllowed

- para.class = formalpara | para | simpara | local.para.class

- local.informal.class = notAllowed

- informal.class =

-   address

-   | blockquote

-   | graphic

-   | graphicco

-   | mediaobject

-   | mediaobjectco

-   | informalequation

-   | informalexample

-   | informalfigure

-   | informaltable

-   | local.informal.class

- local.formal.class = notAllowed

- formal.class = equation | example | figure | table | local.formal.class

- # The DocBook TC may produce an official EBNF module for DocBook.

- 

- # This PE provides the hook by which it can be inserted into the DTD.

- ebnf.block.hook = notAllowed

- local.compound.class = notAllowed

- compound.class =

-   msgset

-   | procedure

-   | sidebar

-   | qandaset

-   | task

-   | ebnf.block.hook

-   | local.compound.class

- local.genobj.class = notAllowed

- genobj.class =

-   anchor | bridgehead | remark | highlights | local.genobj.class

- local.descobj.class = notAllowed

- descobj.class = abstract | authorblurb | epigraph | local.descobj.class

- # Character-level classes ..............................................

- local.xref.char.class = notAllowed

- xref.char.class = footnoteref | xref | biblioref | local.xref.char.class

- local.gen.char.class = notAllowed

- gen.char.class =

-   abbrev

-   | acronym

-   | citation

-   | citerefentry

-   | citetitle

-   | citebiblioid

-   | emphasis

-   | firstterm

-   | foreignphrase

-   | glossterm

-   | termdef

-   | footnote

-   | phrase

-   | orgname

-   | quote

-   | trademark

-   | wordasword

-   | personname

-   | local.gen.char.class

- local.link.char.class = notAllowed

- link.char.class = link | olink | ulink | local.link.char.class

- # The DocBook TC may produce an official EBNF module for DocBook.

- 

- # This PE provides the hook by which it can be inserted into the DTD.

- ebnf.inline.hook = notAllowed

- local.tech.char.class = notAllowed

- tech.char.class =

-   action

-   | application

-   | classname

-   | methodname

-   | interfacename

-   | exceptionname

-   | ooclass

-   | oointerface

-   | ooexception

-   | package

-   | command

-   | computeroutput

-   | database

-   | email

-   | envar

-   | errorcode

-   | errorname

-   | errortype

-   | errortext

-   | filename

-   | function

-   | guibutton

-   | guiicon

-   | guilabel

-   | guimenu

-   | guimenuitem

-   | guisubmenu

-   | hardware

-   | interface

-   | keycap

-   | keycode

-   | keycombo

-   | keysym

-   | literal

-   | code

-   | constant

-   | markup

-   | medialabel

-   | menuchoice

-   | mousebutton

-   | option

-   | optional

-   | parameter

-   | prompt

-   | property

-   | replaceable

-   | returnvalue

-   | sgmltag

-   | structfield

-   | structname

-   | symbol

-   | systemitem

-   | uri

-   | \token

-   | type

-   | userinput

-   | varname

-   | ebnf.inline.hook

-   | local.tech.char.class

- local.base.char.class = notAllowed

- base.char.class = anchor | local.base.char.class

- local.docinfo.char.class = notAllowed

- docinfo.char.class =

-   author

-   | authorinitials

-   | corpauthor

-   | corpcredit

-   | modespec

-   | othercredit

-   | productname

-   | productnumber

-   | revhistory

-   | local.docinfo.char.class

- local.other.char.class = notAllowed

- other.char.class =

-   remark | subscript | superscript | local.other.char.class

- local.inlineobj.char.class = notAllowed

- inlineobj.char.class =

-   inlinegraphic

-   | inlinemediaobject

-   | inlineequation

-   | local.inlineobj.char.class

- # ......................................................................

- 

- # Entities for content models ..........................................

- formalobject.title.content = title, titleabbrev?

- # Redeclaration placeholder ............................................

- 

- # For redeclaring entities that are declared after this point while

- # retaining their references to the entities that are declared before

- # this point

- 

- # Object-level mixtures ................................................

- 

- #                       list admn line synp para infm form cmpd gen  desc

- # Component mixture       X    X    X    X    X    X    X    X    X    X

- # Sidebar mixture         X    X    X    X    X    X    X    a    X

- # Footnote mixture        X         X    X    X    X

- # Example mixture         X         X    X    X    X

- # Highlights mixture      X    X              X

- # Paragraph mixture       X         X    X         X

- # Admonition mixture      X         X    X    X    X    X    b    c

- # Figure mixture                    X    X         X

- # Table entry mixture     X    X    X         X    d

- # Glossary def mixture    X         X    X    X    X         e

- # Legal notice mixture    X    X    X         X    f

- # 

- # a. Just Procedure; not Sidebar itself or MsgSet.

- # b. No MsgSet.

- # c. No Highlights.

- # d. Just Graphic; no other informal objects.

- # e. No Anchor, BridgeHead, or Highlights.

- # f. Just BlockQuote; no other informal objects.

- local.component.mix = notAllowed

- component.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | formal.class

-   | compound.class

-   | genobj.class

-   | descobj.class

-   | ndxterm.class

-   | beginpage

-   | forms.hook

-   | local.component.mix

- local.sidebar.mix = notAllowed

- sidebar.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | formal.class

-   | procedure

-   | genobj.class

-   | ndxterm.class

-   | beginpage

-   | forms.hook

-   | local.sidebar.mix

- local.qandaset.mix = notAllowed

- qandaset.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | formal.class

-   | procedure

-   | genobj.class

-   | ndxterm.class

-   | forms.hook

-   | local.qandaset.mix

- local.revdescription.mix = notAllowed

- revdescription.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | formal.class

-   | procedure

-   | genobj.class

-   | ndxterm.class

-   | local.revdescription.mix

- local.footnote.mix = notAllowed

- footnote.mix =

-   list.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | local.footnote.mix

- local.example.mix = notAllowed

- example.mix =

-   list.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | ndxterm.class

-   | beginpage

-   | procedure

-   | forms.hook

-   | local.example.mix

- local.highlights.mix = notAllowed

- highlights.mix =

-   list.class

-   | admon.class

-   | para.class

-   | ndxterm.class

-   | local.highlights.mix

- # %formal.class; is explicitly excluded from many contexts in which

- # paragraphs are used

- local.para.mix = notAllowed

- para.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | informal.class

-   | formal.class

-   | local.para.mix

- local.admon.mix = notAllowed

- admon.mix =

-   list.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | formal.class

-   | procedure

-   | sidebar

-   | anchor

-   | bridgehead

-   | remark

-   | ndxterm.class

-   | beginpage

-   | forms.hook

-   | local.admon.mix

- local.figure.mix = notAllowed

- figure.mix =

-   linespecific.class

-   | synop.class

-   | informal.class

-   | ndxterm.class

-   | beginpage

-   | forms.hook

-   | local.figure.mix

- local.tabentry.mix = notAllowed

- tabentry.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | para.class

-   | graphic

-   | mediaobject

-   | forms.hook

-   | local.tabentry.mix

- local.glossdef.mix = notAllowed

- glossdef.mix =

-   list.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | formal.class

-   | remark

-   | ndxterm.class

-   | beginpage

-   | local.glossdef.mix

- local.legalnotice.mix = notAllowed

- legalnotice.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | para.class

-   | blockquote

-   | ndxterm.class

-   | beginpage

-   | local.legalnotice.mix

- local.textobject.mix = notAllowed

- textobject.mix =

-   list.class

-   | admon.class

-   | linespecific.class

-   | para.class

-   | blockquote

-   | local.textobject.mix

- local.mediaobject.mix = notAllowed

- mediaobject.mix =

-   videoobject

-   | audioobject

-   | imageobject

-   | imageobjectco

-   | textobject

-   | local.mediaobject.mix

- local.listpreamble.mix = notAllowed

- listpreamble.mix =

-   admon.class

-   | linespecific.class

-   | synop.class

-   | para.class

-   | informal.class

-   | genobj.class

-   | descobj.class

-   | ndxterm.class

-   | beginpage

-   | forms.hook

-   | local.listpreamble.mix

- # Character-level mixtures .............................................

- 

- # sgml.features

- 

- # not [sgml.features[

- 

- # ]] not sgml.features

- 

- #                     #PCD xref word link cptr base dnfo othr inob (synop)

- # para.char.mix         X    X    X    X    X    X    X    X    X

- # title.char.mix        X    X    X    X    X    X    X    X    X

- # ndxterm.char.mix      X    X    X    X    X    X    X    X    a

- # cptr.char.mix         X              X    X    X         X    a

- # smallcptr.char.mix    X                   b                   a

- # word.char.mix         X         c    X         X         X    a

- # docinfo.char.mix      X         d    X    b              X    a

- # 

- # a. Just InlineGraphic; no InlineEquation.

- # b. Just Replaceable; no other computer terms.

- # c. Just Emphasis and Trademark; no other word elements.

- # d. Just Acronym, Emphasis, and Trademark; no other word elements.

- local.para.char.mix = notAllowed

- para.char.mix =

-   text

-   | xref.char.class

-   | gen.char.class

-   | link.char.class

-   | tech.char.class

-   | base.char.class

-   | docinfo.char.class

-   | other.char.class

-   | inlineobj.char.class

-   | synop.class

-   | ndxterm.class

-   | beginpage

-   | forminlines.hook

-   | local.para.char.mix

- local.title.char.mix = notAllowed

- title.char.mix =

-   text

-   | xref.char.class

-   | gen.char.class

-   | link.char.class

-   | tech.char.class

-   | base.char.class

-   | docinfo.char.class

-   | other.char.class

-   | inlineobj.char.class

-   | ndxterm.class

-   | local.title.char.mix

- local.ndxterm.char.mix = notAllowed

- ndxterm.char.mix =

-   text

-   | xref.char.class

-   | gen.char.class

-   | link.char.class

-   | tech.char.class

-   | base.char.class

-   | docinfo.char.class

-   | other.char.class

-   | inlinegraphic

-   | inlinemediaobject

-   | local.ndxterm.char.mix

- local.cptr.char.mix = notAllowed

- cptr.char.mix =

-   text

-   | link.char.class

-   | tech.char.class

-   | base.char.class

-   | other.char.class

-   | inlinegraphic

-   | inlinemediaobject

-   | ndxterm.class

-   | beginpage

-   | local.cptr.char.mix

- local.smallcptr.char.mix = notAllowed

- smallcptr.char.mix =

-   text

-   | replaceable

-   | inlinegraphic

-   | inlinemediaobject

-   | ndxterm.class

-   | beginpage

-   | local.smallcptr.char.mix

- local.word.char.mix = notAllowed

- word.char.mix =

-   text

-   | acronym

-   | emphasis

-   | trademark

-   | link.char.class

-   | base.char.class

-   | other.char.class

-   | inlinegraphic

-   | inlinemediaobject

-   | ndxterm.class

-   | beginpage

-   | local.word.char.mix

- local.docinfo.char.mix = notAllowed

- docinfo.char.mix =

-   text

-   | link.char.class

-   | emphasis

-   | trademark

-   | replaceable

-   | other.char.class

-   | inlinegraphic

-   | inlinemediaobject

-   | ndxterm.class

-   | local.docinfo.char.mix

- # ENTITY % bibliocomponent.mix (see Bibliographic section, below)

- 

- # ENTITY % person.ident.mix (see Bibliographic section, below)

- 

- # ......................................................................

- 

- # Entities for attributes and attribute components .....................

- 

- # Effectivity attributes ...............................................

- 

- # Arch: Computer or chip architecture to which element applies; no

- # default

- arch.attrib = attribute arch { text }?

- # Condition: General-purpose effectivity attribute

- condition.attrib = attribute condition { text }?

- # Conformance: Standards conformance characteristics

- conformance.attrib = attribute conformance { xsd:NMTOKENS }?

- # OS: Operating system to which element applies; no default

- os.attrib = attribute os { text }?

- # Revision: Editorial revision to which element belongs; no default

- revision.attrib = attribute revision { text }?

- # Security: Security classification; no default

- security.attrib = attribute security { text }?

- # UserLevel: Level of user experience to which element applies; no

- # default

- userlevel.attrib = attribute userlevel { text }?

- # Vendor: Computer vendor to which element applies; no default

- vendor.attrib = attribute vendor { text }?

- # Wordsize: Computer word size (32 bit, 64 bit, etc.); no default

- wordsize.attrib = attribute wordsize { text }?

- local.effectivity.attrib = empty

- effectivity.attrib =

-   arch.attrib,

-   condition.attrib,

-   conformance.attrib,

-   os.attrib,

-   revision.attrib,

-   security.attrib,

-   userlevel.attrib,

-   vendor.attrib,

-   wordsize.attrib,

-   local.effectivity.attrib

- # Common attributes ....................................................

- 

- # Id: Unique identifier of element; no default

- id.attrib = attribute id { xsd:ID }?

- # Id: Unique identifier of element; a value must be supplied; no

- # default

- idreq.attrib = attribute id { xsd:ID }

- # Lang: Indicator of language in which element is written, for

- # translation, character set management, etc.; no default

- lang.attrib = attribute lang { text }?

- # Remap: Previous role of element before conversion; no default

- remap.attrib = attribute remap { text }?

- # Role: New role of element in local environment; no default

- role.attrib = attribute role { text }?

- # XRefLabel: Alternate labeling string for XRef text generation;

- # default is usually title or other appropriate label text already

- # contained in element

- xreflabel.attrib = attribute xreflabel { text }?

- # RevisionFlag: Revision status of element; default is that element

- # wasn't revised

- revisionflag.attrib =

-   attribute revisionflag { "changed" | "added" | "deleted" | "off" }?

- local.common.attrib = empty

- # dir: Bidirectional override

- dir.attrib = attribute dir { "ltr" | "rtl" | "lro" | "rlo" }?

- # xml:base: base URI

- xml-base.attrib = attribute xml:base { text }?

- # Role is included explicitly on each element

- common.attrib =

-   id.attrib,

-   lang.attrib,

-   remap.attrib,

-   xreflabel.attrib,

-   revisionflag.attrib,

-   effectivity.attrib,

-   dir.attrib,

-   xml-base.attrib,

-   local.common.attrib

- # Role is included explicitly on each element

- idreq.common.attrib =

-   idreq.attrib,

-   lang.attrib,

-   remap.attrib,

-   xreflabel.attrib,

-   revisionflag.attrib,

-   effectivity.attrib,

-   dir.attrib,

-   xml-base.attrib,

-   local.common.attrib

- # Semi-common attributes and other attribute entities ..................

- local.graphics.attrib = empty

- # EntityRef: Name of an external entity containing the content

- # of the graphic

- 

- # FileRef: Filename, qualified by a pathname if desired,

- # designating the file containing the content of the graphic

- 

- # Format: Notation of the element content, if any

- 

- # SrcCredit: Information about the source of the Graphic

- 

- # Width: Same as CALS reprowid (desired width)

- 

- # Depth: Same as CALS reprodep (desired depth)

- 

- # Align: Same as CALS hplace with 'none' removed; #IMPLIED means

- # application-specific

- 

- # Scale: Conflation of CALS hscale and vscale

- 

- # Scalefit: Same as CALS scalefit

- graphics.attrib =

-   attribute entityref { xsd:ENTITY }?,

-   attribute fileref { text }?,

-   attribute format { notation.class }?,

-   attribute srccredit { text }?,

-   attribute width { text }?,

-   attribute contentwidth { text }?,

-   attribute depth { text }?,

-   attribute contentdepth { text }?,

-   attribute align { "left" | "right" | "center" }?,

-   attribute valign { "top" | "middle" | "bottom" }?,

-   attribute scale { text }?,

-   attribute scalefit { yesorno.attvals }?,

-   local.graphics.attrib

- local.keyaction.attrib = empty

- # Action: Key combination type; default is unspecified if one

- # child element, Simul if there is more than one; if value is

- # Other, the OtherAction attribute must have a nonempty value

- 

- # OtherAction: User-defined key combination type

- keyaction.attrib =

-   attribute action {

-     "click" | "double-click" | "press" | "seq" | "simul" | "other"

-   }?,

-   attribute otheraction { text }?,

-   local.keyaction.attrib

- # Label: Identifying number or string; default is usually the

- # appropriate number or string autogenerated by a formatter

- label.attrib = attribute label { text }?

- # xml:space: whitespace treatment

- xml-space.attrib = attribute xml:space { "preserve" }?

- # Format: whether element is assumed to contain significant white

- # space

- linespecific.attrib =

-   [ a:defaultValue = "linespecific" ]

-   attribute format { "linespecific" }?,

-   xml-space.attrib,

-   attribute linenumbering { "numbered" | "unnumbered" }?,

-   attribute continuation { "continues" | "restarts" }?,

-   attribute startinglinenumber { text }?,

-   attribute language { text }?

- # Linkend: link to related information; no default

- linkend.attrib = attribute linkend { xsd:IDREF }?

- # Linkend: required link to related information

- linkendreq.attrib = attribute linkend { xsd:IDREF }

- # Linkends: link to one or more sets of related information; no

- # default

- linkends.attrib = attribute linkends { xsd:IDREFS }?

- local.mark.attrib = empty

- mark.attrib =

-   attribute mark { text }?,

-   local.mark.attrib

- # MoreInfo: whether element's content has an associated RefEntry

- moreinfo.attrib =

-   [ a:defaultValue = "none" ]

-   attribute moreinfo { "refentry" | "none" }?

- # Pagenum: number of page on which element appears; no default

- pagenum.attrib = attribute pagenum { text }?

- local.status.attrib = empty

- # Status: Editorial or publication status of the element

- # it applies to, such as "in review" or "approved for distribution"

- status.attrib =

-   attribute status { text }?,

-   local.status.attrib

- # Width: width of the longest line in the element to which it

- # pertains, in number of characters

- width.attrib = attribute width { text }?

- # ......................................................................

- 

- # Title elements .......................................................

- local.title.attrib = empty

- title.role.attrib = role.attrib

- # doc:The text of the title of a section of a document or of a formal block-level element.

- title = element title { title.attlist, title.char.mix* }

- # end of title.element

- title.attlist &=

-   pagenum.attrib, common.attrib, title.role.attrib, local.title.attrib

- # end of title.attlist

- 

- # end of title.module

- local.titleabbrev.attrib = empty

- titleabbrev.role.attrib = role.attrib

- # doc:The abbreviation of a Title.

- titleabbrev =

-   element titleabbrev { titleabbrev.attlist, title.char.mix* }

- # end of titleabbrev.element

- titleabbrev.attlist &=

-   common.attrib, titleabbrev.role.attrib, local.titleabbrev.attrib

- # end of titleabbrev.attlist

- 

- # end of titleabbrev.module

- local.subtitle.attrib = empty

- subtitle.role.attrib = role.attrib

- # doc:The subtitle of a document.

- subtitle = element subtitle { subtitle.attlist, title.char.mix* }

- # end of subtitle.element

- subtitle.attlist &=

-   common.attrib, subtitle.role.attrib, local.subtitle.attrib

- # end of subtitle.attlist

- 

- # end of subtitle.module

- 

- # ......................................................................

- 

- # Bibliographic entities and elements ..................................

- 

- # The bibliographic elements are typically used in the document

- # hierarchy. They do not appear in content models of information

- # pool elements.  See also the document information elements,

- # below.

- local.person.ident.mix = notAllowed

- person.ident.mix =

-   honorific

-   | firstname

-   | surname

-   | lineage

-   | othername

-   | affiliation

-   | authorblurb

-   | contrib

-   | local.person.ident.mix

- local.bibliocomponent.mix = notAllowed

- bibliocomponent.mix =

-   abbrev

-   | abstract

-   | address

-   | artpagenums

-   | author

-   | authorgroup

-   | authorinitials

-   | bibliomisc

-   | biblioset

-   | collab

-   | confgroup

-   | contractnum

-   | contractsponsor

-   | copyright

-   | corpauthor

-   | corpname

-   | corpcredit

-   | date

-   | edition

-   | editor

-   | invpartnumber

-   | isbn

-   | issn

-   | issuenum

-   | orgname

-   | biblioid

-   | citebiblioid

-   | bibliosource

-   | bibliorelation

-   | bibliocoverage

-   | othercredit

-   | pagenums

-   | printhistory

-   | productname

-   | productnumber

-   | pubdate

-   | publisher

-   | publishername

-   | pubsnumber

-   | releaseinfo

-   | revhistory

-   | seriesvolnums

-   | subtitle

-   | title

-   | titleabbrev

-   | volumenum

-   | citetitle

-   | personname

-   | person.ident.mix

-   | ndxterm.class

-   | local.bibliocomponent.mix

- # I don't think this is well placed, but it needs to be here because of

- 

- # the reference to bibliocomponent.mix

- local.info.class = notAllowed

- info.class =

-   graphic

-   | mediaobject

-   | legalnotice

-   | modespec

-   | subjectset

-   | keywordset

-   | itermset

-   | bibliocomponent.mix

-   | local.info.class

- # BiblioList ........................

- local.bibliolist.attrib = empty

- bibliolist.role.attrib = role.attrib

- # doc:A wrapper for a set of bibliography entries.

- bibliolist =

-   element bibliolist {

-     bibliolist.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     (biblioentry | bibliomixed)+

-   }

- # end of bibliolist.element

- bibliolist.attlist &=

-   common.attrib, bibliolist.role.attrib, local.bibliolist.attrib

- # end of bibliolist.attlist

- 

- # end of bibliolist.module

- local.biblioentry.attrib = empty

- biblioentry.role.attrib = role.attrib

- # doc:An entry in a Bibliography.

- biblioentry =

-   element biblioentry {

-     biblioentry.attlist, (articleinfo | bibliocomponent.mix)+

-   }

- # end of biblioentry.element

- biblioentry.attlist &=

-   common.attrib, biblioentry.role.attrib, local.biblioentry.attrib

- # end of biblioentry.attlist

- 

- # end of biblioentry.module

- local.bibliomixed.attrib = empty

- bibliomixed.role.attrib = role.attrib

- # doc:An entry in a Bibliography.

- bibliomixed =

-   element bibliomixed {

-     bibliomixed.attlist, (text | bibliocomponent.mix | bibliomset)*

-   }

- # end of bibliomixed.element

- bibliomixed.attlist &=

-   common.attrib, bibliomixed.role.attrib, local.bibliomixed.attrib

- # end of bibliomixed.attlist

- 

- # end of bibliomixed.module

- local.articleinfo.attrib = empty

- articleinfo.role.attrib = role.attrib

- # doc:Meta-information for an Article.

- articleinfo = element articleinfo { articleinfo.attlist, info.class+ }

- # end of articleinfo.element

- articleinfo.attlist &=

-   common.attrib, articleinfo.role.attrib, local.articleinfo.attrib

- # end of articleinfo.attlist

- 

- # end of articleinfo.module

- local.biblioset.attrib = empty

- biblioset.role.attrib = role.attrib

- # doc:A "raw" container for related bibliographic information.

- biblioset =

-   element biblioset { biblioset.attlist, bibliocomponent.mix+ }

- # end of biblioset.element

- 

- # Relation: Relationship of elements contained within BiblioSet

- biblioset.attlist &=

-   attribute relation { text }?,

-   common.attrib,

-   biblioset.role.attrib,

-   local.biblioset.attrib

- # end of biblioset.attlist

- 

- # end of biblioset.module

- bibliomset.role.attrib = role.attrib

- local.bibliomset.attrib = empty

- # doc:A "cooked" container for related bibliographic information.

- bibliomset =

-   element bibliomset {

-     bibliomset.attlist, (text | bibliocomponent.mix | bibliomset)*

-   }

- # end of bibliomset.element

- 

- # Relation: Relationship of elements contained within BiblioMSet

- bibliomset.attlist &=

-   attribute relation { text }?,

-   common.attrib,

-   bibliomset.role.attrib,

-   local.bibliomset.attrib

- # end of bibliomset.attlist

- 

- # end of bibliomset.module

- local.bibliomisc.attrib = empty

- bibliomisc.role.attrib = role.attrib

- # doc:Untyped bibliographic information.

- bibliomisc = element bibliomisc { bibliomisc.attlist, para.char.mix* }

- # end of bibliomisc.element

- bibliomisc.attlist &=

-   common.attrib, bibliomisc.role.attrib, local.bibliomisc.attrib

- # end of bibliomisc.attlist

- 

- # end of bibliomisc.module

- 

- # ......................................................................

- 

- # Subject, Keyword, and ITermSet elements ..............................

- local.subjectset.attrib = empty

- subjectset.role.attrib = role.attrib

- # doc:A set of terms describing the subject matter of a document.

- subjectset = element subjectset { subjectset.attlist, subject+ }

- # end of subjectset.element

- 

- # Scheme: Controlled vocabulary employed in SubjectTerms

- subjectset.attlist &=

-   attribute scheme { xsd:NMTOKEN }?,

-   common.attrib,

-   subjectset.role.attrib,

-   local.subjectset.attrib

- # end of subjectset.attlist

- 

- # end of subjectset.module

- local.subject.attrib = empty

- subject.role.attrib = role.attrib

- # doc:One of a group of terms describing the subject matter of a document.

- subject = element subject { subject.attlist, subjectterm+ }

- # end of subject.element

- 

- # Weight: Ranking of this group of SubjectTerms relative

- # to others, 0 is low, no highest value specified

- subject.attlist &=

-   attribute weight { text }?,

-   common.attrib,

-   subject.role.attrib,

-   local.subject.attrib

- # end of subject.attlist

- 

- # end of subject.module

- local.subjectterm.attrib = empty

- subjectterm.role.attrib = role.attrib

- # doc:A term in a group of terms describing the subject matter of a document.

- subjectterm = element subjectterm { subjectterm.attlist, text }

- # end of subjectterm.element

- subjectterm.attlist &=

-   common.attrib, subjectterm.role.attrib, local.subjectterm.attrib

- # end of subjectterm.attlist

- 

- # end of subjectterm.module

- 

- # end of subjectset.content.module

- local.keywordset.attrib = empty

- keywordset.role.attrib = role.attrib

- # doc:A set of keywords describing the content of a document.

- keywordset = element keywordset { keywordset.attlist, keyword+ }

- # end of keywordset.element

- keywordset.attlist &=

-   common.attrib, keywordset.role.attrib, local.keywordset.attrib

- # end of keywordset.attlist

- 

- # end of keywordset.module

- local.keyword.attrib = empty

- keyword.role.attrib = role.attrib

- # doc:One of a set of keywords describing the content of a document.

- keyword = element keyword { keyword.attlist, text }

- # end of keyword.element

- keyword.attlist &=

-   common.attrib, keyword.role.attrib, local.keyword.attrib

- # end of keyword.attlist

- 

- # end of keyword.module

- 

- # end of keywordset.content.module

- local.itermset.attrib = empty

- itermset.role.attrib = role.attrib

- # doc:A set of index terms in the meta-information of a document.

- itermset = element itermset { itermset.attlist, indexterm+ }

- # end of itermset.element

- itermset.attlist &=

-   common.attrib, itermset.role.attrib, local.itermset.attrib

- # end of itermset.attlist

- 

- # end of itermset.module

- 

- # Bibliographic info for "blocks"

- local.blockinfo.attrib = empty

- blockinfo.role.attrib = role.attrib

- # doc:Meta-information for a block element.

- blockinfo = element blockinfo { blockinfo.attlist, info.class+ }

- # end of blockinfo.element

- blockinfo.attlist &=

-   common.attrib, blockinfo.role.attrib, local.blockinfo.attrib

- # end of blockinfo.attlist

- 

- # end of blockinfo.module

- 

- # ......................................................................

- 

- # Compound (section-ish) elements ......................................

- 

- # Message set ......................

- local.msgset.attrib = empty

- msgset.role.attrib = role.attrib

- # doc:A detailed set of messages, usually error messages.

- msgset =

-   element msgset {

-     msgset.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     (msgentry+ | simplemsgentry+)

-   }

- # end of msgset.element

- msgset.attlist &= common.attrib, msgset.role.attrib, local.msgset.attrib

- # end of msgset.attlist

- 

- # end of msgset.module

- local.msgentry.attrib = empty

- msgentry.role.attrib = role.attrib

- # doc:A wrapper for an entry in a message set.

- msgentry =

-   element msgentry { msgentry.attlist, msg+, msginfo?, msgexplan* }

- # end of msgentry.element

- msgentry.attlist &=

-   common.attrib, msgentry.role.attrib, local.msgentry.attrib

- # end of msgentry.attlist

- 

- # end of msgentry.module

- local.simplemsgentry.attrib = empty

- simplemsgentry.role.attrib = role.attrib

- # doc:A wrapper for a simpler entry in a message set.

- simplemsgentry =

-   element simplemsgentry { simplemsgentry.attlist, msgtext, msgexplan+ }

- # end of simplemsgentry.element

- simplemsgentry.attlist &=

-   attribute audience { text }?,

-   attribute level { text }?,

-   attribute origin { text }?,

-   common.attrib,

-   simplemsgentry.role.attrib,

-   local.simplemsgentry.attrib

- # end of simplemsgentry.attlist

- 

- # end of simplemsgentry.module

- local.msg.attrib = empty

- msg.role.attrib = role.attrib

- # doc:A message in a message set.

- msg = element msg { msg.attlist, title?, msgmain, (msgsub | msgrel)* }

- # end of msg.element

- msg.attlist &= common.attrib, msg.role.attrib, local.msg.attrib

- # end of msg.attlist

- 

- # end of msg.module

- local.msgmain.attrib = empty

- msgmain.role.attrib = role.attrib

- # doc:The primary component of a message in a message set.

- msgmain = element msgmain { msgmain.attlist, title?, msgtext }

- # end of msgmain.element

- msgmain.attlist &=

-   common.attrib, msgmain.role.attrib, local.msgmain.attrib

- # end of msgmain.attlist

- 

- # end of msgmain.module

- local.msgsub.attrib = empty

- msgsub.role.attrib = role.attrib

- # doc:A subcomponent of a message in a message set.

- msgsub = element msgsub { msgsub.attlist, title?, msgtext }

- # end of msgsub.element

- msgsub.attlist &= common.attrib, msgsub.role.attrib, local.msgsub.attrib

- # end of msgsub.attlist

- 

- # end of msgsub.module

- local.msgrel.attrib = empty

- msgrel.role.attrib = role.attrib

- # doc:A related component of a message in a message set.

- msgrel = element msgrel { msgrel.attlist, title?, msgtext }

- # end of msgrel.element

- msgrel.attlist &= common.attrib, msgrel.role.attrib, local.msgrel.attrib

- # end of msgrel.attlist

- 

- # end of msgrel.module

- 

- # MsgText (defined in the Inlines section, below)

- local.msginfo.attrib = empty

- msginfo.role.attrib = role.attrib

- # doc:Information about a message in a message set.

- msginfo =

-   element msginfo { msginfo.attlist, (msglevel | msgorig | msgaud)* }

- # end of msginfo.element

- msginfo.attlist &=

-   common.attrib, msginfo.role.attrib, local.msginfo.attrib

- # end of msginfo.attlist

- 

- # end of msginfo.module

- local.msglevel.attrib = empty

- msglevel.role.attrib = role.attrib

- # doc:The level of importance or severity of a message in a message set.

- msglevel = element msglevel { msglevel.attlist, smallcptr.char.mix* }

- # end of msglevel.element

- msglevel.attlist &=

-   common.attrib, msglevel.role.attrib, local.msglevel.attrib

- # end of msglevel.attlist

- 

- # end of msglevel.module

- local.msgorig.attrib = empty

- msgorig.role.attrib = role.attrib

- # doc:The origin of a message in a message set.

- msgorig = element msgorig { msgorig.attlist, smallcptr.char.mix* }

- # end of msgorig.element

- msgorig.attlist &=

-   common.attrib, msgorig.role.attrib, local.msgorig.attrib

- # end of msgorig.attlist

- 

- # end of msgorig.module

- local.msgaud.attrib = empty

- msgaud.role.attrib = role.attrib

- # doc:The audience to which a message in a message set is relevant.

- msgaud = element msgaud { msgaud.attlist, para.char.mix* }

- # end of msgaud.element

- msgaud.attlist &= common.attrib, msgaud.role.attrib, local.msgaud.attrib

- # end of msgaud.attlist

- 

- # end of msgaud.module

- local.msgexplan.attrib = empty

- msgexplan.role.attrib = role.attrib

- # doc:Explanatory material relating to a message in a message set.

- msgexplan =

-   element msgexplan { msgexplan.attlist, title?, component.mix+ }

- # end of msgexplan.element

- msgexplan.attlist &=

-   common.attrib, msgexplan.role.attrib, local.msgexplan.attrib

- # end of msgexplan.attlist

- 

- # end of msgexplan.module

- 

- # end of msgset.content.module

- local.task.attrib = empty

- task.role.attrib = role.attrib

- # doc:A task to be completed.

- task =

-   element task {

-     task.attlist,

-     blockinfo?,

-     ndxterm.class*,

-     formalobject.title.content,

-     tasksummary?,

-     taskprerequisites?,

-     procedure,

-     example*,

-     taskrelated?

-   }

- # end of task.element

- task.attlist &= common.attrib, task.role.attrib, local.task.attrib

- # end of task.attlist

- 

- # end of task.module

- local.tasksummary.attrib = empty

- tasksummary.role.attrib = role.attrib

- # doc:A summary of a task.

- tasksummary =

-   element tasksummary {

-     tasksummary.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     component.mix+

-   }

- # end of tasksummary.element

- tasksummary.attlist &=

-   common.attrib, tasksummary.role.attrib, local.tasksummary.attrib

- # end of tasksummary.attlist

- 

- # end of tasksummary.module

- local.taskprerequisites.attrib = empty

- taskprerequisites.role.attrib = role.attrib

- # doc:The prerequisites for a task.

- taskprerequisites =

-   element taskprerequisites {

-     taskprerequisites.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     component.mix+

-   }

- # end of taskprerequisites.element

- taskprerequisites.attlist &=

-   common.attrib,

-   taskprerequisites.role.attrib,

-   local.taskprerequisites.attrib

- # end of taskprerequisites.attlist

- 

- # end of taskprerequisites.module

- local.taskrelated.attrib = empty

- taskrelated.role.attrib = role.attrib

- # doc:Information related to a task.

- taskrelated =

-   element taskrelated {

-     taskrelated.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     component.mix+

-   }

- # end of taskrelated.element

- taskrelated.attlist &=

-   common.attrib, taskrelated.role.attrib, local.taskrelated.attrib

- # end of taskrelated.attlist

- 

- # end of taskrelated.module

- 

- # end of task.content.module

- 

- # QandASet ........................

- local.qandaset.attrib = empty

- qandaset.role.attrib = role.attrib

- # doc:A question-and-answer set.

- qandaset =

-   element qandaset {

-     qandaset.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     qandaset.mix*,

-     (qandadiv+ | qandaentry+)

-   }

- # end of qandaset.element

- qandaset.attlist &=

-   attribute defaultlabel { "qanda" | "number" | "none" }?,

-   common.attrib,

-   qandaset.role.attrib,

-   local.qandaset.attrib

- # end of qandaset.attlist

- 

- # end of qandaset.module

- local.qandadiv.attrib = empty

- qandadiv.role.attrib = role.attrib

- # doc:A titled division in a QandASet.

- qandadiv =

-   element qandadiv {

-     qandadiv.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     qandaset.mix*,

-     (qandadiv+ | qandaentry+)

-   }

- # end of qandadiv.element

- qandadiv.attlist &=

-   common.attrib, qandadiv.role.attrib, local.qandadiv.attrib

- # end of qandadiv.attlist

- 

- # end of qandadiv.module

- local.qandaentry.attrib = empty

- qandaentry.role.attrib = role.attrib

- # doc:A question/answer set within a QandASet.

- qandaentry =

-   element qandaentry {

-     qandaentry.attlist, blockinfo?, revhistory?, question, answer*

-   }

- # end of qandaentry.element

- qandaentry.attlist &=

-   common.attrib, qandaentry.role.attrib, local.qandaentry.attrib

- # end of qandaentry.attlist

- 

- # end of qandaentry.module

- local.question.attrib = empty

- question.role.attrib = role.attrib

- # doc:A question in a QandASet.

- question = element question { question.attlist, label?, qandaset.mix+ }

- # end of question.element

- question.attlist &=

-   common.attrib, question.role.attrib, local.question.attrib

- # end of question.attlist

- 

- # end of question.module

- local.answer.attrib = empty

- answer.role.attrib = role.attrib

- # doc:An answer to a question posed in a QandASet.

- answer =

-   element answer { answer.attlist, label?, qandaset.mix*, qandaentry* }

- # end of answer.element

- answer.attlist &= common.attrib, answer.role.attrib, local.answer.attrib

- # end of answer.attlist

- 

- # end of answer.module

- local.label.attrib = empty

- label.role.attrib = role.attrib

- # doc:A label on a Question or Answer.

- label = element label { label.attlist, word.char.mix* }

- # end of label.element

- label.attlist &= common.attrib, label.role.attrib, local.label.attrib

- # end of label.attlist

- 

- # end of label.module

- 

- # end of qandaset.content.module

- 

- # Procedure ........................

- local.procedure.attrib = empty

- procedure.role.attrib = role.attrib

- # doc:A list of operations to be performed in a well-defined sequence.

- procedure =

-   element procedure {

-     procedure.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     component.mix*,

-     step+

-   }

- # end of procedure.element

- procedure.attlist &=

-   common.attrib, procedure.role.attrib, local.procedure.attrib

- # end of procedure.attlist

- 

- # end of procedure.module

- local.step.attrib = empty

- step.role.attrib = role.attrib

- # doc:A unit of action in a procedure.

- step =

-   element step {

-     step.attlist,

-     title?,

-     ((component.mix+,

-       ((substeps | stepalternatives), component.mix*)?)

-      | ((substeps | stepalternatives), component.mix*))

-   }

- # end of step.element

- 

- # Performance: Whether the Step must be performed

- 

- # not #REQUIRED!

- step.attlist &=

-   [ a:defaultValue = "required" ]

-   attribute performance { "optional" | "required" }?,

-   common.attrib,

-   step.role.attrib,

-   local.step.attrib

- # end of step.attlist

- 

- # end of step.module

- local.substeps.attrib = empty

- substeps.role.attrib = role.attrib

- # doc:A wrapper for steps that occur within steps in a procedure.

- substeps = element substeps { substeps.attlist, step+ }

- # end of substeps.element

- 

- # Performance: whether entire set of substeps must be performed

- 

- # not #REQUIRED!

- substeps.attlist &=

-   [ a:defaultValue = "required" ]

-   attribute performance { "optional" | "required" }?,

-   common.attrib,

-   substeps.role.attrib,

-   local.substeps.attrib

- # end of substeps.attlist

- 

- # end of substeps.module

- local.stepalternatives.attrib = empty

- stepalternatives.role.attrib = role.attrib

- # doc:Alternative steps in a procedure.

- stepalternatives =

-   element stepalternatives { stepalternatives.attlist, step+ }

- # end of stepalternatives.element

- 

- # Performance: Whether (one of) the alternatives must be performed

- 

- # not #REQUIRED!

- stepalternatives.attlist &=

-   [ a:defaultValue = "required" ]

-   attribute performance { "optional" | "required" }?,

-   common.attrib,

-   stepalternatives.role.attrib,

-   local.stepalternatives.attrib

- # end of stepalternatives.attlist

- 

- # end of stepalternatives.module

- 

- # end of procedure.content.module

- 

- # Sidebar ..........................

- local.sidebarinfo.attrib = empty

- sidebarinfo.role.attrib = role.attrib

- # doc:Meta-information for a Sidebar.

- sidebarinfo = element sidebarinfo { sidebarinfo.attlist, info.class+ }

- # end of sidebarinfo.element

- sidebarinfo.attlist &=

-   common.attrib, sidebarinfo.role.attrib, local.sidebarinfo.attrib

- # end of sidebarinfo.attlist

- 

- # end of sidebarinfo.module

- local.sidebar.attrib = empty

- sidebar.role.attrib = role.attrib

- # doc:A portion of a document that is isolated from the main narrative flow.

- sidebar =

-   element sidebar {

-     sidebar.attlist,

-     sidebarinfo?,

-     formalobject.title.content?,

-     sidebar.mix+

-   }

- # end of sidebar.element

- sidebar.attlist &=

-   common.attrib, sidebar.role.attrib, local.sidebar.attrib

- # end of sidebar.attlist

- 

- # end of sidebar.module

- 

- # end of sidebar.content.model

- 

- # ......................................................................

- 

- # Paragraph-related elements ...........................................

- local.abstract.attrib = empty

- abstract.role.attrib = role.attrib

- # doc:A summary.

- abstract = element abstract { abstract.attlist, title?, para.class+ }

- # end of abstract.element

- abstract.attlist &=

-   common.attrib, abstract.role.attrib, local.abstract.attrib

- # end of abstract.attlist

- 

- # end of abstract.module

- local.authorblurb.attrib = empty

- authorblurb.role.attrib = role.attrib

- # doc:A short description or note about an author.

- authorblurb =

-   element authorblurb { authorblurb.attlist, title?, para.class+ }

- # end of authorblurb.element

- authorblurb.attlist &=

-   common.attrib, authorblurb.role.attrib, local.authorblurb.attrib

- # end of authorblurb.attlist

- 

- # end of authorblurb.module

- local.personblurb.attrib = empty

- personblurb.role.attrib = role.attrib

- # doc:A short description or note about a person.

- personblurb =

-   element personblurb { personblurb.attlist, title?, para.class+ }

- # end of personblurb.element

- personblurb.attlist &=

-   common.attrib, personblurb.role.attrib, local.personblurb.attrib

- # end of personblurb.attlist

- 

- # end of personblurb.module

- local.blockquote.attrib = empty

- blockquote.role.attrib = role.attrib

- # doc:A quotation set off from the main text.

- blockquote =

-   element blockquote {

-     blockquote.attlist, blockinfo?, title?, attribution?, component.mix+

-   }

- # end of blockquote.element

- blockquote.attlist &=

-   common.attrib, blockquote.role.attrib, local.blockquote.attrib

- # end of blockquote.attlist

- 

- # end of blockquote.module

- local.attribution.attrib = empty

- attribution.role.attrib = role.attrib

- # doc:The source of a block quote or epigraph.

- attribution =

-   element attribution { attribution.attlist, para.char.mix* }

- # end of attribution.element

- attribution.attlist &=

-   common.attrib, attribution.role.attrib, local.attribution.attrib

- # end of attribution.attlist

- 

- # end of attribution.module

- local.bridgehead.attrib = empty

- bridgehead.role.attrib = role.attrib

- # doc:A free-floating heading.

- bridgehead = element bridgehead { bridgehead.attlist, title.char.mix* }

- # end of bridgehead.element

- 

- # Renderas: Indicates the format in which the BridgeHead

- # should appear

- bridgehead.attlist &=

-   attribute renderas {

-     "other" | "sect1" | "sect2" | "sect3" | "sect4" | "sect5"

-   }?,

-   common.attrib,

-   bridgehead.role.attrib,

-   local.bridgehead.attrib

- # end of bridgehead.attlist

- 

- # end of bridgehead.module

- local.remark.attrib = empty

- remark.role.attrib = role.attrib

- # doc:A remark (or comment) intended for presentation in a draft manuscript.

- remark = element remark { remark.attlist, para.char.mix* }

- # end of remark.element

- remark.attlist &= common.attrib, remark.role.attrib, local.remark.attrib

- # end of remark.attlist

- 

- # end of remark.module

- local.epigraph.attrib = empty

- epigraph.role.attrib = role.attrib

- # doc:A short inscription at the beginning of a document or component.

- epigraph =

-   element epigraph {

-     epigraph.attlist, attribution?, (para.class | literallayout)+

-   }

- # end of epigraph.element

- epigraph.attlist &=

-   common.attrib, epigraph.role.attrib, local.epigraph.attrib

- # end of epigraph.attlist

- 

- # Attribution (defined above)

- 

- # end of epigraph.module

- local.footnote.attrib = empty

- footnote.role.attrib = role.attrib

- # doc:A footnote.

- footnote = element footnote { footnote.attlist, footnote.mix+ }

- # end of footnote.element

- footnote.attlist &=

-   label.attrib,

-   common.attrib,

-   footnote.role.attrib,

-   local.footnote.attrib

- # end of footnote.attlist

- 

- # end of footnote.module

- local.highlights.attrib = empty

- highlights.role.attrib = role.attrib

- # doc:A summary of the main points of the discussed component.

- highlights = element highlights { highlights.attlist, highlights.mix+ }

- # end of highlights.element

- highlights.attlist &=

-   common.attrib, highlights.role.attrib, local.highlights.attrib

- # end of highlights.attlist

- 

- # end of highlights.module

- local.formalpara.attrib = empty

- formalpara.role.attrib = role.attrib

- # doc:A paragraph with a title.

- formalpara =

-   element formalpara { formalpara.attlist, title, ndxterm.class*, para }

- # end of formalpara.element

- formalpara.attlist &=

-   common.attrib, formalpara.role.attrib, local.formalpara.attrib

- # end of formalpara.attlist

- 

- # end of formalpara.module

- local.para.attrib = empty

- para.role.attrib = role.attrib

- # doc:A paragraph.

- para = element para { para.attlist, (para.char.mix | para.mix)* }

- # end of para.element

- para.attlist &= common.attrib, para.role.attrib, local.para.attrib

- # end of para.attlist

- 

- # end of para.module

- local.simpara.attrib = empty

- simpara.role.attrib = role.attrib

- # doc:A paragraph that contains only text and inline markup, no block elements.

- simpara = element simpara { simpara.attlist, para.char.mix* }

- # end of simpara.element

- simpara.attlist &=

-   common.attrib, simpara.role.attrib, local.simpara.attrib

- # end of simpara.attlist

- 

- # end of simpara.module

- local.admon.attrib = empty

- admon.role.attrib = role.attrib

- # doc:A note of caution.

- caution = element caution { caution.attlist, title?, admon.mix+ }

- # end of caution.element

- caution.attlist &= common.attrib, admon.role.attrib, local.admon.attrib

- # end of caution.attlist

- 

- # doc:An admonition set off from the text.

- important = element important { important.attlist, title?, admon.mix+ }

- # end of important.element

- important.attlist &=

-   common.attrib, admon.role.attrib, local.admon.attrib

- # end of important.attlist

- 

- # doc:A message set off from the text.

- note = element note { note.attlist, title?, admon.mix+ }

- # end of note.element

- note.attlist &= common.attrib, admon.role.attrib, local.admon.attrib

- # end of note.attlist

- 

- # doc:A suggestion to the user, set off from the text.

- tip = element tip { tip.attlist, title?, admon.mix+ }

- # end of tip.element

- tip.attlist &= common.attrib, admon.role.attrib, local.admon.attrib

- # end of tip.attlist

- 

- # doc:An admonition set off from the text.

- warning = element warning { warning.attlist, title?, admon.mix+ }

- # end of warning.element

- warning.attlist &= common.attrib, admon.role.attrib, local.admon.attrib

- # end of warning.attlist

- 

- # end of admon.module

- 

- # ......................................................................

- 

- # Lists ................................................................

- 

- # GlossList ........................

- local.glosslist.attrib = empty

- glosslist.role.attrib = role.attrib

- # doc:A wrapper for a set of GlossEntrys.

- glosslist =

-   element glosslist {

-     glosslist.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     glossentry+

-   }

- # end of glosslist.element

- glosslist.attlist &=

-   common.attrib, glosslist.role.attrib, local.glosslist.attrib

- # end of glosslist.attlist

- 

- # end of glosslist.module

- local.glossentry.attrib = empty

- glossentry.role.attrib = role.attrib

- # doc:An entry in a Glossary or GlossList.

- glossentry =

-   element glossentry {

-     glossentry.attlist,

-     glossterm,

-     acronym?,

-     abbrev?,

-     ndxterm.class*,

-     revhistory?,

-     (glosssee | glossdef+)

-   }

- # end of glossentry.element

- 

- # SortAs: String by which the GlossEntry is to be sorted

- # (alphabetized) in lieu of its proper content

- glossentry.attlist &=

-   attribute sortas { text }?,

-   common.attrib,

-   glossentry.role.attrib,

-   local.glossentry.attrib

- # end of glossentry.attlist

- 

- # end of glossentry.module

- 

- # GlossTerm (defined in the Inlines section, below)

- local.glossdef.attrib = empty

- glossdef.role.attrib = role.attrib

- # doc:A definition in a GlossEntry.

- glossdef =

-   element glossdef { glossdef.attlist, glossdef.mix+, glossseealso* }

- # end of glossdef.element

- 

- # Subject: List of subjects; keywords for the definition

- glossdef.attlist &=

-   attribute subject { text }?,

-   common.attrib,

-   glossdef.role.attrib,

-   local.glossdef.attrib

- # end of glossdef.attlist

- 

- # end of glossdef.module

- local.glosssee.attrib = empty

- glosssee.role.attrib = role.attrib

- # doc:A cross-reference from one GlossEntry to another.

- glosssee = element glosssee { glosssee.attlist, para.char.mix* }

- # end of glosssee.element

- 

- # OtherTerm: Reference to the GlossEntry whose GlossTerm

- # should be displayed at the point of the GlossSee

- glosssee.attlist &=

-   attribute otherterm { xsd:IDREF }?,

-   common.attrib,

-   glosssee.role.attrib,

-   local.glosssee.attrib

- # end of glosssee.attlist

- 

- # end of glosssee.module

- local.glossseealso.attrib = empty

- glossseealso.role.attrib = role.attrib

- # doc:A cross-reference from one GlossEntry to another.

- glossseealso =

-   element glossseealso { glossseealso.attlist, para.char.mix* }

- # end of glossseealso.element

- 

- # OtherTerm: Reference to the GlossEntry whose GlossTerm

- # should be displayed at the point of the GlossSeeAlso

- glossseealso.attlist &=

-   attribute otherterm { xsd:IDREF }?,

-   common.attrib,

-   glossseealso.role.attrib,

-   local.glossseealso.attrib

- # end of glossseealso.attlist

- 

- # end of glossseealso.module

- 

- # end of glossentry.content.module

- 

- # ItemizedList and OrderedList .....

- local.itemizedlist.attrib = empty

- itemizedlist.role.attrib = role.attrib

- # doc:A list in which each entry is marked with a bullet or other dingbat.

- itemizedlist =

-   element itemizedlist {

-     itemizedlist.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     listpreamble.mix*,

-     listitem+

-   }

- # end of itemizedlist.element

- 

- # Spacing: Whether the vertical space in the list should be

- # compressed

- 

- # Mark: Keyword, e.g., bullet, dash, checkbox, none;

- # list of keywords and defaults are implementation specific

- itemizedlist.attlist &=

-   attribute spacing { "normal" | "compact" }?,

-   mark.attrib,

-   common.attrib,

-   itemizedlist.role.attrib,

-   local.itemizedlist.attrib

- # end of itemizedlist.attlist

- 

- # end of itemizedlist.module

- local.orderedlist.attrib = empty

- orderedlist.role.attrib = role.attrib

- # doc:A list in which each entry is marked with a sequentially incremented label.

- orderedlist =

-   element orderedlist {

-     orderedlist.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     listpreamble.mix*,

-     listitem+

-   }

- # end of orderedlist.element

- 

- # Numeration: Style of ListItem numbered; default is expected

- # to be Arabic

- 

- # InheritNum: Specifies for a nested list that the numbering

- # of ListItems should include the number of the item

- # within which they are nested (e.g., 1a and 1b within 1,

- # rather than a and b)

- 

- # Continuation: Where list numbering begins afresh (Restarts,

- # the default) or continues that of the immediately preceding

- # list (Continues)

- 

- # Spacing: Whether the vertical space in the list should be

- # compressed

- orderedlist.attlist &=

-   attribute numeration {

-     "arabic" | "upperalpha" | "loweralpha" | "upperroman" | "lowerroman"

-   }?,

-   [ a:defaultValue = "ignore" ]

-   attribute inheritnum { "inherit" | "ignore" }?,

-   [ a:defaultValue = "restarts" ]

-   attribute continuation { "continues" | "restarts" }?,

-   attribute spacing { "normal" | "compact" }?,

-   common.attrib,

-   orderedlist.role.attrib,

-   local.orderedlist.attrib

- # end of orderedlist.attlist

- 

- # end of orderedlist.module

- local.listitem.attrib = empty

- listitem.role.attrib = role.attrib

- # doc:A wrapper for the elements of a list item.

- listitem = element listitem { listitem.attlist, component.mix+ }

- # end of listitem.element

- 

- # Override: Indicates the mark to be used for this ListItem

- # instead of the default mark or the mark specified by

- # the Mark attribute on the enclosing ItemizedList

- listitem.attlist &=

-   attribute override { text }?,

-   common.attrib,

-   listitem.role.attrib,

-   local.listitem.attrib

- # end of listitem.attlist

- 

- # end of listitem.module

- 

- # SegmentedList ....................

- local.segmentedlist.attrib = empty

- segmentedlist.role.attrib = role.attrib

- # doc:A segmented list, a list of sets of elements.

- segmentedlist =

-   element segmentedlist {

-     segmentedlist.attlist,

-     formalobject.title.content?,

-     segtitle+,

-     seglistitem+

-   }

- # end of segmentedlist.element

- segmentedlist.attlist &=

-   common.attrib, segmentedlist.role.attrib, local.segmentedlist.attrib

- # end of segmentedlist.attlist

- 

- # end of segmentedlist.module

- local.segtitle.attrib = empty

- segtitle.role.attrib = role.attrib

- # doc:The title of an element of a list item in a segmented list.

- segtitle = element segtitle { segtitle.attlist, title.char.mix* }

- # end of segtitle.element

- segtitle.attlist &=

-   common.attrib, segtitle.role.attrib, local.segtitle.attrib

- # end of segtitle.attlist

- 

- # end of segtitle.module

- local.seglistitem.attrib = empty

- seglistitem.role.attrib = role.attrib

- # doc:A list item in a segmented list.

- seglistitem = element seglistitem { seglistitem.attlist, seg+ }

- # end of seglistitem.element

- seglistitem.attlist &=

-   common.attrib, seglistitem.role.attrib, local.seglistitem.attrib

- # end of seglistitem.attlist

- 

- # end of seglistitem.module

- local.seg.attrib = empty

- seg.role.attrib = role.attrib

- # doc:An element of a list item in a segmented list.

- seg = element seg { seg.attlist, para.char.mix* }

- # end of seg.element

- seg.attlist &= common.attrib, seg.role.attrib, local.seg.attrib

- # end of seg.attlist

- 

- # end of seg.module

- 

- # end of segmentedlist.content.module

- 

- # SimpleList .......................

- local.simplelist.attrib = empty

- simplelist.role.attrib = role.attrib

- # doc:An undecorated list of single words or short phrases.

- simplelist = element simplelist { simplelist.attlist, member+ }

- # end of simplelist.element

- 

- # Columns: The number of columns the array should contain

- 

- # Type: How the Members of the SimpleList should be

- # formatted: Inline (members separated with commas etc.

- # inline), Vert (top to bottom in n Columns), or Horiz (in

- # the direction of text flow) in n Columns.  If Column

- # is 1 or implied, Type=Vert and Type=Horiz give the same

- # results.

- simplelist.attlist &=

-   attribute columns { text }?,

-   [ a:defaultValue = "vert" ]

-   attribute type { "inline" | "vert" | "horiz" }?,

-   common.attrib,

-   simplelist.role.attrib,

-   local.simplelist.attrib

- # end of simplelist.attlist

- 

- # end of simplelist.module

- local.member.attrib = empty

- member.role.attrib = role.attrib

- # doc:An element of a simple list.

- member = element member { member.attlist, para.char.mix* }

- # end of member.element

- member.attlist &= common.attrib, member.role.attrib, local.member.attrib

- # end of member.attlist

- 

- # end of member.module

- 

- # end of simplelist.content.module

- 

- # VariableList .....................

- local.variablelist.attrib = empty

- variablelist.role.attrib = role.attrib

- # doc:A list in which each entry is composed of a set of one or more terms and an associated description.

- variablelist =

-   element variablelist {

-     variablelist.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     listpreamble.mix*,

-     varlistentry+

-   }

- # end of variablelist.element

- 

- # TermLength: Length beyond which the presentation engine

- # may consider the Term too long and select an alternate

- # presentation of the Term and, or, its associated ListItem.

- variablelist.attlist &=

-   attribute termlength { text }?,

-   attribute spacing { "normal" | "compact" }?,

-   common.attrib,

-   variablelist.role.attrib,

-   local.variablelist.attrib

- # end of variablelist.attlist

- 

- # end of variablelist.module

- local.varlistentry.attrib = empty

- varlistentry.role.attrib = role.attrib

- # doc:A wrapper for a set of terms and the associated description in a variable list.

- varlistentry =

-   element varlistentry { varlistentry.attlist, term+, listitem }

- # end of varlistentry.element

- varlistentry.attlist &=

-   common.attrib, varlistentry.role.attrib, local.varlistentry.attrib

- # end of varlistentry.attlist

- 

- # end of varlistentry.module

- local.term.attrib = empty

- term.role.attrib = role.attrib

- # doc:The word or phrase being defined or described in a variable list.

- term = element term { term.attlist, para.char.mix* }

- # end of term.element

- term.attlist &= common.attrib, term.role.attrib, local.term.attrib

- # end of term.attlist

- 

- # end of term.module

- 

- # ListItem (defined above)

- 

- # end of variablelist.content.module

- 

- # CalloutList ......................

- local.calloutlist.attrib = empty

- calloutlist.role.attrib = role.attrib

- # doc:A list of Callouts.

- calloutlist =

-   element calloutlist {

-     calloutlist.attlist, formalobject.title.content?, callout+

-   }

- # end of calloutlist.element

- calloutlist.attlist &=

-   common.attrib, calloutlist.role.attrib, local.calloutlist.attrib

- # end of calloutlist.attlist

- 

- # end of calloutlist.module

- local.callout.attrib = empty

- callout.role.attrib = role.attrib

- # doc:A &ldquo;called out&rdquo; description of a marked Area.

- callout = element callout { callout.attlist, component.mix+ }

- # end of callout.element

- 

- # AreaRefs: IDs of one or more Areas or AreaSets described

- # by this Callout

- callout.attlist &=

-   attribute arearefs { xsd:IDREFS },

-   common.attrib,

-   callout.role.attrib,

-   local.callout.attrib

- # end of callout.attlist

- 

- # end of callout.module

- 

- # end of calloutlist.content.module

- 

- # ......................................................................

- 

- # Objects ..............................................................

- 

- # Examples etc. ....................

- local.example.attrib = empty

- example.role.attrib = role.attrib

- # doc:A formal example, with a title.

- example =

-   element example {

-     example.attlist,

-     blockinfo?,

-     formalobject.title.content,

-     example.mix+

-   }

- # end of example.element

- example.attlist &=

-   attribute floatstyle { text }?,

-   label.attrib,

-   width.attrib,

-   common.attrib,

-   example.role.attrib,

-   local.example.attrib

- # end of example.attlist

- 

- # end of example.module

- local.informalexample.attrib = empty

- informalexample.role.attrib = role.attrib

- # doc:A displayed example without a title.

- informalexample =

-   element informalexample {

-     informalexample.attlist, blockinfo?, example.mix+

-   }

- # end of informalexample.element

- informalexample.attlist &=

-   attribute floatstyle { text }?,

-   width.attrib,

-   common.attrib,

-   informalexample.role.attrib,

-   local.informalexample.attrib

- # end of informalexample.attlist

- 

- # end of informalexample.module

- local.programlistingco.attrib = empty

- programlistingco.role.attrib = role.attrib

- # doc:A program listing with associated areas used in callouts.

- programlistingco =

-   element programlistingco {

-     programlistingco.attlist, areaspec, programlisting, calloutlist*

-   }

- # end of programlistingco.element

- programlistingco.attlist &=

-   common.attrib,

-   programlistingco.role.attrib,

-   local.programlistingco.attrib

- # end of programlistingco.attlist

- 

- # CalloutList (defined above in Lists)

- 

- # end of informalexample.module

- local.areaspec.attrib = empty

- areaspec.role.attrib = role.attrib

- # doc:A collection of regions in a graphic or code example.

- areaspec = element areaspec { areaspec.attlist, (area | areaset)+ }

- # end of areaspec.element

- 

- # Units: global unit of measure in which coordinates in

- # this spec are expressed:

- # 

- # - CALSPair "x1,y1 x2,y2": lower-left and upper-right

- # coordinates in a rectangle describing repro area in which

- # graphic is placed, where X and Y dimensions are each some

- # number 0..10000 (taken from CALS graphic attributes)

- # 

- # - LineColumn "line column": line number and column number

- # at which to start callout text in "linespecific" content

- # 

- # - LineRange "startline endline": whole lines from startline

- # to endline in "linespecific" content

- # 

- # - LineColumnPair "line1 col1 line2 col2": starting and ending

- # points of area in "linespecific" content that starts at

- # first position and ends at second position (including the

- # beginnings of any intervening lines)

- # 

- # - Other: directive to look at value of OtherUnits attribute

- # to get implementation-specific keyword

- # 

- # The default is implementation-specific; usually dependent on

- # the parent element (GraphicCO gets CALSPair, ProgramListingCO

- # and ScreenCO get LineColumn)

- 

- # OtherUnits: User-defined units

- areaspec.attlist &=

-   attribute units {

-     "calspair" | "linecolumn" | "linerange" | "linecolumnpair" | "other"

-   }?,

-   attribute otherunits { xsd:NMTOKEN }?,

-   common.attrib,

-   areaspec.role.attrib,

-   local.areaspec.attrib

- # end of areaspec.attlist

- 

- # end of areaspec.module

- local.area.attrib = empty

- area.role.attrib = role.attrib

- # doc:A region defined for a Callout in a graphic or code example.

- area = element area { area.attlist, empty }

- # end of area.element

- 

- # bug number/symbol override or initialization

- 

- # to any related information

- 

- # Units: unit of measure in which coordinates in this

- # area are expressed; inherits from AreaSet and AreaSpec

- 

- # OtherUnits: User-defined units

- area.attlist &=

-   label.attrib,

-   linkends.attrib,

-   attribute units {

-     "calspair" | "linecolumn" | "linerange" | "linecolumnpair" | "other"

-   }?,

-   attribute otherunits { xsd:NMTOKEN }?,

-   attribute coords { text },

-   idreq.common.attrib,

-   area.role.attrib,

-   local.area.attrib

- # end of area.attlist

- 

- # end of area.module

- local.areaset.attrib = empty

- areaset.role.attrib = role.attrib

- # doc:A set of related areas in a graphic or code example.

- areaset = element areaset { areaset.attlist, area+ }

- # end of areaset.element

- 

- # bug number/symbol override or initialization

- 

- # Units: unit of measure in which coordinates in this

- # area are expressed; inherits from AreaSpec

- areaset.attlist &=

-   label.attrib,

-   attribute units {

-     "calspair" | "linecolumn" | "linerange" | "linecolumnpair" | "other"

-   }?,

-   attribute otherunits { xsd:NMTOKEN }?,

-   attribute coords { text },

-   idreq.common.attrib,

-   areaset.role.attrib,

-   local.areaset.attrib

- # end of areaset.attlist

- 

- # end of areaset.module

- 

- # end of areaspec.content.module

- local.programlisting.attrib = empty

- programlisting.role.attrib = role.attrib

- # doc:A literal listing of all or part of a program.

- programlisting =

-   element programlisting {

-     programlisting.attlist,

-     (para.char.mix | co | coref | lineannotation | textobject)*

-   }

- # end of programlisting.element

- programlisting.attlist &=

-   width.attrib,

-   linespecific.attrib,

-   common.attrib,

-   programlisting.role.attrib,

-   local.programlisting.attrib

- # end of programlisting.attlist

- 

- # end of programlisting.module

- local.literallayout.attrib = empty

- literallayout.role.attrib = role.attrib

- # doc:A block of text in which line breaks and white space are to be reproduced faithfully.

- literallayout =

-   element literallayout {

-     literallayout.attlist,

-     (para.char.mix | co | coref | textobject | lineannotation)*

-   }

- # end of literallayout.element

- literallayout.attlist &=

-   width.attrib,

-   linespecific.attrib,

-   [ a:defaultValue = "normal" ]

-   attribute class { "monospaced" | "normal" }?,

-   common.attrib,

-   literallayout.role.attrib,

-   local.literallayout.attrib

- # end of literallayout.attlist

- 

- # LineAnnotation (defined in the Inlines section, below)

- 

- # end of literallayout.module

- local.screenco.attrib = empty

- screenco.role.attrib = role.attrib

- # doc:A screen with associated areas used in callouts.

- screenco =

-   element screenco { screenco.attlist, areaspec, screen, calloutlist* }

- # end of screenco.element

- screenco.attlist &=

-   common.attrib, screenco.role.attrib, local.screenco.attrib

- # end of screenco.attlist

- 

- # AreaSpec (defined above)

- 

- # CalloutList (defined above in Lists)

- 

- # end of screenco.module

- local.screen.attrib = empty

- screen.role.attrib = role.attrib

- # doc:Text that a user sees or might see on a computer screen.

- screen =

-   element screen {

-     screen.attlist,

-     (para.char.mix | co | coref | textobject | lineannotation)*

-   }

- # end of screen.element

- screen.attlist &=

-   width.attrib,

-   linespecific.attrib,

-   common.attrib,

-   screen.role.attrib,

-   local.screen.attrib

- # end of screen.attlist

- 

- # end of screen.module

- local.screenshot.attrib = empty

- screenshot.role.attrib = role.attrib

- # doc:A representation of what the user sees or might see on a computer screen.

- screenshot =

-   element screenshot {

-     screenshot.attlist,

-     screeninfo?,

-     (graphic | graphicco | mediaobject | mediaobjectco)

-   }

- # end of screenshot.element

- screenshot.attlist &=

-   common.attrib, screenshot.role.attrib, local.screenshot.attrib

- # end of screenshot.attlist

- 

- # end of screenshot.module

- local.screeninfo.attrib = empty

- screeninfo.role.attrib = role.attrib

- # doc:Information about how a screen shot was produced.

- screeninfo = element screeninfo { screeninfo.attlist, para.char.mix* }

- # end of screeninfo.element

- screeninfo.attlist &=

-   common.attrib, screeninfo.role.attrib, local.screeninfo.attrib

- # end of screeninfo.attlist

- 

- # end of screeninfo.module

- 

- # end of screenshot.content.module

- 

- # Figures etc. .....................

- local.figure.attrib = empty

- figure.role.attrib = role.attrib

- # doc:A formal figure, generally an illustration, with a title.

- figure =

-   element figure {

-     figure.attlist,

-     blockinfo?,

-     formalobject.title.content,

-     (figure.mix | link.char.class)+

-   }

- # end of figure.element

- 

- # Float: Whether the Figure is supposed to be rendered

- # where convenient (yes (1) value) or at the place it occurs

- # in the text (no (0) value, the default)

- figure.attlist &=

-   [ a:defaultValue = "0" ] attribute float { yesorno.attvals }?,

-   attribute floatstyle { text }?,

-   attribute pgwide { yesorno.attvals }?,

-   label.attrib,

-   common.attrib,

-   figure.role.attrib,

-   local.figure.attrib

- # end of figure.attlist

- 

- # end of figure.module

- local.informalfigure.attrib = empty

- informalfigure.role.attrib = role.attrib

- # doc:A untitled figure.

- informalfigure =

-   element informalfigure {

-     informalfigure.attlist, blockinfo?, (figure.mix | link.char.class)+

-   }

- # end of informalfigure.element

- 

- # Float: Whether the Figure is supposed to be rendered

- # where convenient (yes (1) value) or at the place it occurs

- # in the text (no (0) value, the default)

- informalfigure.attlist &=

-   [ a:defaultValue = "0" ] attribute float { yesorno.attvals }?,

-   attribute floatstyle { text }?,

-   attribute pgwide { yesorno.attvals }?,

-   label.attrib,

-   common.attrib,

-   informalfigure.role.attrib,

-   local.informalfigure.attrib

- # end of informalfigure.attlist

- 

- # end of informalfigure.module

- local.graphicco.attrib = empty

- graphicco.role.attrib = role.attrib

- # doc:A graphic that contains callout areas.

- graphicco =

-   element graphicco {

-     graphicco.attlist, areaspec, graphic, calloutlist*

-   }

- # end of graphicco.element

- graphicco.attlist &=

-   common.attrib, graphicco.role.attrib, local.graphicco.attrib

- # end of graphicco.attlist

- 

- # AreaSpec (defined above in Examples)

- 

- # CalloutList (defined above in Lists)

- 

- # end of graphicco.module

- 

- # Graphical data can be the content of Graphic, or you can reference

- # an external file either as an entity (Entitref) or a filename

- # (Fileref).

- local.graphic.attrib = empty

- graphic.role.attrib = role.attrib

- # doc:A displayed graphical object (not an inline).

- graphic = element graphic { graphic.attlist, empty }

- # end of graphic.element

- graphic.attlist &=

-   graphics.attrib,

-   common.attrib,

-   graphic.role.attrib,

-   local.graphic.attrib

- # end of graphic.attlist

- 

- # end of graphic.module

- local.inlinegraphic.attrib = empty

- inlinegraphic.role.attrib = role.attrib

- # doc:An object containing or pointing to graphical data that will be rendered inline.

- inlinegraphic = element inlinegraphic { inlinegraphic.attlist, empty }

- # end of inlinegraphic.element

- inlinegraphic.attlist &=

-   graphics.attrib,

-   common.attrib,

-   inlinegraphic.role.attrib,

-   local.inlinegraphic.attrib

- # end of inlinegraphic.attlist

- 

- # end of inlinegraphic.module

- local.mediaobject.attrib = empty

- mediaobject.role.attrib = role.attrib

- # doc:A displayed media object (video, audio, image, etc.).

- mediaobject =

-   element mediaobject {

-     mediaobject.attlist, objectinfo?, mediaobject.mix+, caption?

-   }

- # end of mediaobject.element

- mediaobject.attlist &=

-   common.attrib, mediaobject.role.attrib, local.mediaobject.attrib

- # end of mediaobject.attlist

- 

- # end of mediaobject.module

- local.inlinemediaobject.attrib = empty

- inlinemediaobject.role.attrib = role.attrib

- # doc:An inline media object (video, audio, image, and so on).

- inlinemediaobject =

-   element inlinemediaobject {

-     inlinemediaobject.attlist, objectinfo?, mediaobject.mix+

-   }

- # end of inlinemediaobject.element

- inlinemediaobject.attlist &=

-   common.attrib,

-   inlinemediaobject.role.attrib,

-   local.inlinemediaobject.attrib

- # end of inlinemediaobject.attlist

- 

- # end of inlinemediaobject.module

- local.videoobject.attrib = empty

- videoobject.role.attrib = role.attrib

- # doc:A wrapper for video data and its associated meta-information.

- videoobject =

-   element videoobject { videoobject.attlist, objectinfo?, videodata }

- # end of videoobject.element

- videoobject.attlist &=

-   common.attrib, videoobject.role.attrib, local.videoobject.attrib

- # end of videoobject.attlist

- 

- # end of videoobject.module

- local.audioobject.attrib = empty

- audioobject.role.attrib = role.attrib

- # doc:A wrapper for audio data and its associated meta-information.

- audioobject =

-   element audioobject { audioobject.attlist, objectinfo?, audiodata }

- # end of audioobject.element

- audioobject.attlist &=

-   common.attrib, audioobject.role.attrib, local.audioobject.attrib

- # end of audioobject.attlist

- 

- # end of audioobject.module

- local.imageobject.attrib = empty

- imageobject.role.attrib = role.attrib

- # doc:A wrapper for image data and its associated meta-information.

- imageobject =

-   element imageobject { imageobject.attlist, objectinfo?, imagedata }

- # end of imageobject.element

- imageobject.attlist &=

-   common.attrib, imageobject.role.attrib, local.imageobject.attrib

- # end of imageobject.attlist

- 

- # end of imageobject.module

- local.textobject.attrib = empty

- textobject.role.attrib = role.attrib

- # doc:A wrapper for a text description of an object and its associated meta-information.

- textobject =

-   element textobject {

-     textobject.attlist,

-     objectinfo?,

-     (phrase | textdata | textobject.mix+)

-   }

- # end of textobject.element

- textobject.attlist &=

-   common.attrib, textobject.role.attrib, local.textobject.attrib

- # end of textobject.attlist

- 

- # end of textobject.module

- local.objectinfo.attrib = empty

- objectinfo.role.attrib = role.attrib

- # doc:Meta-information for an object.

- objectinfo = element objectinfo { objectinfo.attlist, info.class+ }

- # end of objectinfo.element

- objectinfo.attlist &=

-   common.attrib, objectinfo.role.attrib, local.objectinfo.attrib

- # end of objectinfo.attlist

- 

- # end of objectinfo.module

- 

- # EntityRef: Name of an external entity containing the content

- # of the object data

- 

- # FileRef: Filename, qualified by a pathname if desired,

- # designating the file containing the content of the object data

- 

- # Format: Notation of the element content, if any

- 

- # SrcCredit: Information about the source of the image

- local.objectdata.attrib = empty

- objectdata.attrib =

-   attribute entityref { xsd:ENTITY }?,

-   attribute fileref { text }?,

-   attribute format { notation.class }?,

-   attribute srccredit { text }?,

-   local.objectdata.attrib

- local.videodata.attrib = empty

- videodata.role.attrib = role.attrib

- # doc:Pointer to external video data.

- videodata = element videodata { videodata.attlist, empty }

- # end of videodata.element

- 

- # Width: Same as CALS reprowid (desired width)

- 

- # Depth: Same as CALS reprodep (desired depth)

- 

- # Align: Same as CALS hplace with 'none' removed; #IMPLIED means

- # application-specific

- 

- # Scale: Conflation of CALS hscale and vscale

- 

- # Scalefit: Same as CALS scalefit

- videodata.attlist &=

-   attribute width { text }?,

-   attribute contentwidth { text }?,

-   attribute depth { text }?,

-   attribute contentdepth { text }?,

-   attribute align { "left" | "right" | "center" }?,

-   attribute valign { "top" | "middle" | "bottom" }?,

-   attribute scale { text }?,

-   attribute scalefit { yesorno.attvals }?,

-   objectdata.attrib,

-   common.attrib,

-   videodata.role.attrib,

-   local.videodata.attrib

- # end of videodata.attlist

- 

- # end of videodata.module

- local.audiodata.attrib = empty

- audiodata.role.attrib = role.attrib

- # doc:Pointer to external audio data.

- audiodata = element audiodata { audiodata.attlist, empty }

- # end of audiodata.element

- audiodata.attlist &=

-   objectdata.attrib,

-   common.attrib,

-   audiodata.role.attrib,

-   local.audiodata.attrib

- # end of audiodata.attlist

- 

- # end of audiodata.module

- local.imagedata.attrib = empty

- imagedata.role.attrib = role.attrib

- # doc:Pointer to external image data.

- imagedata = element imagedata { imagedata.attlist, empty }

- # end of imagedata.element

- 

- # Width: Same as CALS reprowid (desired width)

- 

- # Depth: Same as CALS reprodep (desired depth)

- 

- # Align: Same as CALS hplace with 'none' removed; #IMPLIED means

- # application-specific

- 

- # Scale: Conflation of CALS hscale and vscale

- 

- # Scalefit: Same as CALS scalefit

- imagedata.attlist &=

-   attribute width { text }?,

-   attribute contentwidth { text }?,

-   attribute depth { text }?,

-   attribute contentdepth { text }?,

-   attribute align { "left" | "right" | "center" }?,

-   attribute valign { "top" | "middle" | "bottom" }?,

-   attribute scale { text }?,

-   attribute scalefit { yesorno.attvals }?,

-   objectdata.attrib,

-   common.attrib,

-   imagedata.role.attrib,

-   local.imagedata.attrib

- # end of imagedata.attlist

- 

- # end of imagedata.module

- local.textdata.attrib = empty

- textdata.role.attrib = role.attrib

- # doc:Pointer to external text data.

- textdata = element textdata { textdata.attlist, empty }

- # end of textdata.element

- textdata.attlist &=

-   attribute encoding { text }?,

-   objectdata.attrib,

-   common.attrib,

-   textdata.role.attrib,

-   local.textdata.attrib

- # end of textdata.attlist

- 

- # end of textdata.module

- local.mediaobjectco.attrib = empty

- mediaobjectco.role.attrib = role.attrib

- # doc:A media object that contains callouts.

- mediaobjectco =

-   element mediaobjectco {

-     mediaobjectco.attlist,

-     objectinfo?,

-     imageobjectco,

-     (imageobjectco | textobject)*

-   }

- # end of mediaobjectco.element

- mediaobjectco.attlist &=

-   common.attrib, mediaobjectco.role.attrib, local.mediaobjectco.attrib

- # end of mediaobjectco.attlist

- 

- # end of mediaobjectco.module

- local.imageobjectco.attrib = empty

- imageobjectco.role.attrib = role.attrib

- # doc:A wrapper for an image object with callouts.

- imageobjectco =

-   element imageobjectco {

-     imageobjectco.attlist, areaspec, imageobject, calloutlist*

-   }

- # end of imageobjectco.element

- imageobjectco.attlist &=

-   common.attrib, imageobjectco.role.attrib, local.imageobjectco.attrib

- # end of imageobjectco.attlist

- 

- # end of imageobjectco.module

- 

- # end of mediaobject.content.module

- 

- # Equations ........................

- 

- # This PE provides a mechanism for replacing equation content,

- 

- # perhaps adding a new or different model (e.g., MathML)

- equation.content = alt?, (graphic+ | mediaobject+ | mathphrase+)

- inlineequation.content =

-   alt?, (graphic+ | inlinemediaobject+ | mathphrase+)

- local.equation.attrib = empty

- equation.role.attrib = role.attrib

- # doc:A displayed mathematical equation.

- equation =

-   element equation {

-     equation.attlist,

-     blockinfo?,

-     formalobject.title.content?,

-     (informalequation | equation.content)

-   }

- # end of equation.element

- equation.attlist &=

-   attribute floatstyle { text }?,

-   label.attrib,

-   common.attrib,

-   equation.role.attrib,

-   local.equation.attrib

- # end of equation.attlist

- 

- # end of equation.module

- local.informalequation.attrib = empty

- informalequation.role.attrib = role.attrib

- # doc:A displayed mathematical equation without a title.

- informalequation =

-   element informalequation {

-     informalequation.attlist, blockinfo?, equation.content

-   }

- # end of informalequation.element

- informalequation.attlist &=

-   attribute floatstyle { text }?,

-   common.attrib,

-   informalequation.role.attrib,

-   local.informalequation.attrib

- # end of informalequation.attlist

- 

- # end of informalequation.module

- local.inlineequation.attrib = empty

- inlineequation.role.attrib = role.attrib

- # doc:A mathematical equation or expression occurring inline.

- inlineequation =

-   element inlineequation {

-     inlineequation.attlist, inlineequation.content

-   }

- # end of inlineequation.element

- inlineequation.attlist &=

-   common.attrib, inlineequation.role.attrib, local.inlineequation.attrib

- # end of inlineequation.attlist

- 

- # end of inlineequation.module

- local.alt.attrib = empty

- alt.role.attrib = role.attrib

- # doc:Text representation for a graphical element.

- alt = element alt { alt.attlist, text }

- # end of alt.element

- alt.attlist &= common.attrib, alt.role.attrib, local.alt.attrib

- # end of alt.attlist

- 

- # end of alt.module

- local.mathphrase.attrib = empty

- mathphrase.role.attrib = role.attrib

- # doc:A mathematical phrase, an expression that can be represented with ordinary text and a small amount of markup.

- mathphrase =

-   element mathphrase {

-     mathphrase.attlist, (text | subscript | superscript | emphasis)*

-   }

- # end of mathphrase.element

- mathphrase.attlist &=

-   common.attrib, mathphrase.role.attrib, local.mathphrase.attrib

- # end of mathphrase.attlist

- 

- # end of mathphrase.module

- 

- # Tables ...........................

- 

- # Choose a table model. CALS or OASIS XML Exchange

- 

- # Do we allow the HTML table model as well?

- 

- # ======================================================

- 

- # xhtmltbl.mod defines HTML tables and sets parameter

- # entities so that, when the CALS table module is read,

- # we end up allowing any table to be CALS or HTML.

- # i.e. This include must come first!

- 

- # ======================================================

- include "htmltblx.rnc"

- # end of allow.html.tables

- 

- # Add label and role attributes to table and informaltable

- 

- # Add common attributes to Table, TGroup, TBody, THead, TFoot, Row,

- # EntryTbl, and Entry (and InformalTable element).

- 

- # Content model for Table.

- 

- # Allow either objects or inlines; beware of REs between elements.

- 

- # Reference CALS Table Model

- include "calstblx.rnc"

- # end of table.module

- 

- # Note that InformalTable is dependent on some of the entity

- # declarations that customize Table.

- local.informaltable.attrib = empty

- # the following entity may have been declared by the XHTML table module

- 

- # doc:A table without a title.

- informaltable =

-   element informaltable {

-     informaltable.attlist, blockinfo?, informal.tbl.table.mdl

-   }

- # end of informaltable.element

- 

- # Frame, Colsep, and Rowsep must be repeated because

- # they are not in entities in the table module.

- 

- # includes TabStyle, ToCentry, ShortEntry,

- # Orient, PgWide

- 

- # includes Label

- 

- # includes common attributes

- informaltable.attlist &=

-   attribute frame { tbl.frame.attval }?,

-   attribute colsep { yesorno.attvals }?,

-   attribute rowsep { yesorno.attvals }?,

-   common.table.attribs,

-   tbl.table.att,

-   local.informaltable.attrib

- # end of informaltable.attlist

- 

- # end of informaltable.module

- local.caption.attrib = empty

- caption.role.attrib = role.attrib

- # doc:A caption.

- caption = element caption { caption.attlist, (text | textobject.mix)* }

- # end of caption.element

- 

- # attrs comes from HTML tables ...

- 

- # common.attrib, but without ID because ID is in attrs

- caption.attlist.content =

-   caption.role.attrib,

-   attrs,

-   attribute align { "top" | "bottom" | "left" | "right" }?,

-   local.caption.attrib

- caption.attlist &= caption.attlist.content

- # end of caption.attlist

- 

- # end of caption.module

- 

- # ......................................................................

- 

- # Synopses .............................................................

- 

- # Synopsis .........................

- local.synopsis.attrib = empty

- synopsis.role.attrib = role.attrib

- # doc:A general-purpose element for representing the syntax of commands or functions.

- synopsis =

-   element synopsis {

-     synopsis.attlist,

-     (para.char.mix

-      | graphic

-      | mediaobject

-      | co

-      | coref

-      | textobject

-      | lineannotation)*

-   }

- # end of synopsis.element

- synopsis.attlist &=

-   label.attrib,

-   linespecific.attrib,

-   common.attrib,

-   synopsis.role.attrib,

-   local.synopsis.attrib

- # end of synopsis.attlist

- 

- # LineAnnotation (defined in the Inlines section, below)

- 

- # end of synopsis.module

- 

- # CmdSynopsis ......................

- local.cmdsynopsis.attrib = empty

- cmdsynopsis.role.attrib = role.attrib

- # doc:A syntax summary for a software command.

- cmdsynopsis =

-   element cmdsynopsis {

-     cmdsynopsis.attlist, (command | arg | group | sbr)+, synopfragment*

-   }

- # end of cmdsynopsis.element

- 

- # Sepchar: Character that should separate command and all

- # top-level arguments; alternate value might be e.g., &Delta;

- cmdsynopsis.attlist &=

-   label.attrib,

-   [ a:defaultValue = " " ] attribute sepchar { text }?,

-   attribute cmdlength { text }?,

-   common.attrib,

-   cmdsynopsis.role.attrib,

-   local.cmdsynopsis.attrib

- # end of cmdsynopsis.attlist

- 

- # end of cmdsynopsis.module

- local.arg.attrib = empty

- arg.role.attrib = role.attrib

- # doc:An argument in a CmdSynopsis.

- arg =

-   element arg {

-     arg.attlist,

-     (text

-      | arg

-      | group

-      | option

-      | synopfragmentref

-      | replaceable

-      | sbr)*

-   }

- # end of arg.element

- 

- # Choice: Whether Arg must be supplied: Opt (optional to

- # supply, e.g. [arg]; the default), Req (required to supply,

- # e.g. {arg}), or Plain (required to supply, e.g. arg)

- 

- # Rep: whether Arg is repeatable: Norepeat (e.g. arg without

- # ellipsis; the default), or Repeat (e.g. arg...)

- arg.attlist &=

-   [ a:defaultValue = "opt" ]

-   attribute choice { "opt" | "req" | "plain" }?,

-   [ a:defaultValue = "norepeat" ]

-   attribute rep { "norepeat" | "repeat" }?,

-   common.attrib,

-   arg.role.attrib,

-   local.arg.attrib

- # end of arg.attlist

- 

- # end of arg.module

- local.group.attrib = empty

- group.role.attrib = role.attrib

- # doc:A group of elements in a CmdSynopsis.

- group =

-   element group {

-     group.attlist,

-     (arg | group | option | synopfragmentref | replaceable | sbr)+

-   }

- # end of group.element

- 

- # Choice: Whether Group must be supplied: Opt (optional to

- # supply, e.g.  [g1|g2|g3]; the default), Req (required to

- # supply, e.g.  {g1|g2|g3}), Plain (required to supply,

- # e.g.  g1|g2|g3), OptMult (can supply zero or more, e.g.

- # [[g1|g2|g3]]), or ReqMult (must supply one or more, e.g.

- # {{g1|g2|g3}})

- 

- # Rep: whether Group is repeatable: Norepeat (e.g. group

- # without ellipsis; the default), or Repeat (e.g. group...)

- group.attlist &=

-   [ a:defaultValue = "opt" ]

-   attribute choice { "opt" | "req" | "plain" }?,

-   [ a:defaultValue = "norepeat" ]

-   attribute rep { "norepeat" | "repeat" }?,

-   common.attrib,

-   group.role.attrib,

-   local.group.attrib

- # end of group.attlist

- 

- # end of group.module

- local.sbr.attrib = empty

- # Synopsis break

- sbr.role.attrib = role.attrib

- # doc:An explicit line break in a command synopsis.

- sbr = element sbr { sbr.attlist, empty }

- # end of sbr.element

- sbr.attlist &= common.attrib, sbr.role.attrib, local.sbr.attrib

- # end of sbr.attlist

- 

- # end of sbr.module

- local.synopfragmentref.attrib = empty

- synopfragmentref.role.attrib = role.attrib

- # doc:A reference to a fragment of a command synopsis.

- synopfragmentref =

-   element synopfragmentref { synopfragmentref.attlist, text }

- # end of synopfragmentref.element

- 

- # to SynopFragment of complex synopsis

- # material for separate referencing

- synopfragmentref.attlist &=

-   linkendreq.attrib,

-   common.attrib,

-   synopfragmentref.role.attrib,

-   local.synopfragmentref.attrib

- # end of synopfragmentref.attlist

- 

- # end of synopfragmentref.module

- local.synopfragment.attrib = empty

- synopfragment.role.attrib = role.attrib

- # doc:A portion of a CmdSynopsis broken out from the main body of the synopsis.

- synopfragment =

-   element synopfragment { synopfragment.attlist, (arg | group)+ }

- # end of synopfragment.element

- synopfragment.attlist &=

-   idreq.common.attrib,

-   synopfragment.role.attrib,

-   local.synopfragment.attrib

- # end of synopfragment.attlist

- 

- # end of synopfragment.module

- 

- # Command (defined in the Inlines section, below)

- 

- # Option (defined in the Inlines section, below)

- 

- # Replaceable (defined in the Inlines section, below)

- 

- # end of cmdsynopsis.content.module

- 

- # FuncSynopsis .....................

- local.funcsynopsis.attrib = empty

- funcsynopsis.role.attrib = role.attrib

- # doc:The syntax summary for a function definition.

- funcsynopsis =

-   element funcsynopsis {

-     funcsynopsis.attlist, (funcsynopsisinfo | funcprototype)+

-   }

- # end of funcsynopsis.element

- funcsynopsis.attlist &=

-   label.attrib,

-   common.attrib,

-   funcsynopsis.role.attrib,

-   local.funcsynopsis.attrib

- # end of funcsynopsis.attlist

- 

- # end of funcsynopsis.module

- local.funcsynopsisinfo.attrib = empty

- funcsynopsisinfo.role.attrib = role.attrib

- # doc:Information supplementing the FuncDefs of a FuncSynopsis.

- funcsynopsisinfo =

-   element funcsynopsisinfo {

-     funcsynopsisinfo.attlist,

-     (cptr.char.mix | textobject | lineannotation)*

-   }

- # end of funcsynopsisinfo.element

- funcsynopsisinfo.attlist &=

-   linespecific.attrib,

-   common.attrib,

-   funcsynopsisinfo.role.attrib,

-   local.funcsynopsisinfo.attrib

- # end of funcsynopsisinfo.attlist

- 

- # end of funcsynopsisinfo.module

- local.funcprototype.attrib = empty

- funcprototype.role.attrib = role.attrib

- # doc:The prototype of a function.

- funcprototype =

-   element funcprototype {

-     funcprototype.attlist,

-     modifier*,

-     funcdef,

-     (void | varargs | (paramdef+, varargs?)),

-     modifier*

-   }

- # end of funcprototype.element

- funcprototype.attlist &=

-   common.attrib, funcprototype.role.attrib, local.funcprototype.attrib

- # end of funcprototype.attlist

- 

- # end of funcprototype.module

- local.funcdef.attrib = empty

- funcdef.role.attrib = role.attrib

- # doc:A function (subroutine) name and its return type.

- funcdef =

-   element funcdef {

-     funcdef.attlist, (text | type | replaceable | function)*

-   }

- # end of funcdef.element

- funcdef.attlist &=

-   common.attrib, funcdef.role.attrib, local.funcdef.attrib

- # end of funcdef.attlist

- 

- # end of funcdef.module

- local.void.attrib = empty

- void.role.attrib = role.attrib

- # doc:An empty element in a function synopsis indicating that the function in question takes no arguments.

- void = element void { void.attlist, empty }

- # end of void.element

- void.attlist &= common.attrib, void.role.attrib, local.void.attrib

- # end of void.attlist

- 

- # end of void.module

- local.varargs.attrib = empty

- varargs.role.attrib = role.attrib

- # doc:An empty element in a function synopsis indicating a variable number of arguments.

- varargs = element varargs { varargs.attlist, empty }

- # end of varargs.element

- varargs.attlist &=

-   common.attrib, varargs.role.attrib, local.varargs.attrib

- # end of varargs.attlist

- 

- # end of varargs.module

- 

- # Processing assumes that only one Parameter will appear in a

- # ParamDef, and that FuncParams will be used at most once, for

- # providing information on the "inner parameters" for parameters that

- # are pointers to functions.

- local.paramdef.attrib = empty

- paramdef.role.attrib = role.attrib

- # doc:Information about a function parameter in a programming language.

- paramdef =

-   element paramdef {

-     paramdef.attlist,

-     (text | initializer | type | replaceable | parameter | funcparams)*

-   }

- # end of paramdef.element

- paramdef.attlist &=

-   attribute choice { "opt" | "req" }?,

-   common.attrib,

-   paramdef.role.attrib,

-   local.paramdef.attrib

- # end of paramdef.attlist

- 

- # end of paramdef.module

- local.funcparams.attrib = empty

- funcparams.role.attrib = role.attrib

- # doc:Parameters for a function referenced through a function pointer in a synopsis.

- funcparams = element funcparams { funcparams.attlist, cptr.char.mix* }

- # end of funcparams.element

- funcparams.attlist &=

-   common.attrib, funcparams.role.attrib, local.funcparams.attrib

- # end of funcparams.attlist

- 

- # end of funcparams.module

- 

- # LineAnnotation (defined in the Inlines section, below)

- 

- # Replaceable (defined in the Inlines section, below)

- 

- # Function (defined in the Inlines section, below)

- 

- # Parameter (defined in the Inlines section, below)

- 

- # end of funcsynopsis.content.module

- 

- # ClassSynopsis .....................

- local.classsynopsis.attrib = empty

- classsynopsis.role.attrib = role.attrib

- # doc:The syntax summary for a class definition.

- classsynopsis =

-   element classsynopsis {

-     classsynopsis.attlist,

-     (ooclass | oointerface | ooexception)+,

-     (classsynopsisinfo | fieldsynopsis | method.synop.class)*

-   }

- # end of classsynopsis.element

- classsynopsis.attlist &=

-   attribute language { text }?,

-   [ a:defaultValue = "class" ]

-   attribute class { "class" | "interface" }?,

-   common.attrib,

-   classsynopsis.role.attrib,

-   local.classsynopsis.attrib

- # end of classsynopsis.attlist

- 

- # end of classsynopsis.module

- local.classsynopsisinfo.attrib = empty

- classsynopsisinfo.role.attrib = role.attrib

- # doc:Information supplementing the contents of a ClassSynopsis.

- classsynopsisinfo =

-   element classsynopsisinfo {

-     classsynopsisinfo.attlist,

-     (cptr.char.mix | textobject | lineannotation)*

-   }

- # end of classsynopsisinfo.element

- classsynopsisinfo.attlist &=

-   linespecific.attrib,

-   common.attrib,

-   classsynopsisinfo.role.attrib,

-   local.classsynopsisinfo.attrib

- # end of classsynopsisinfo.attlist

- 

- # end of classsynopsisinfo.module

- local.ooclass.attrib = empty

- ooclass.role.attrib = role.attrib

- # doc:A class in an object-oriented programming language.

- ooclass =

-   element ooclass { ooclass.attlist, (modifier | package)*, classname }

- # end of ooclass.element

- ooclass.attlist &=

-   common.attrib, ooclass.role.attrib, local.ooclass.attrib

- # end of ooclass.attlist

- 

- # end of ooclass.module

- local.oointerface.attrib = empty

- oointerface.role.attrib = role.attrib

- # doc:An interface in an object-oriented programming language.

- oointerface =

-   element oointerface {

-     oointerface.attlist, (modifier | package)*, interfacename

-   }

- # end of oointerface.element

- oointerface.attlist &=

-   common.attrib, oointerface.role.attrib, local.oointerface.attrib

- # end of oointerface.attlist

- 

- # end of oointerface.module

- local.ooexception.attrib = empty

- ooexception.role.attrib = role.attrib

- # doc:An exception in an object-oriented programming language.

- ooexception =

-   element ooexception {

-     ooexception.attlist, (modifier | package)*, exceptionname

-   }

- # end of ooexception.element

- ooexception.attlist &=

-   common.attrib, ooexception.role.attrib, local.ooexception.attrib

- # end of ooexception.attlist

- 

- # end of ooexception.module

- local.modifier.attrib = empty

- modifier.role.attrib = role.attrib

- # doc:Modifiers in a synopsis.

- modifier = element modifier { modifier.attlist, smallcptr.char.mix* }

- # end of modifier.element

- modifier.attlist &=

-   common.attrib, modifier.role.attrib, local.modifier.attrib

- # end of modifier.attlist

- 

- # end of modifier.module

- local.interfacename.attrib = empty

- interfacename.role.attrib = role.attrib

- # doc:The name of an interface.

- interfacename =

-   element interfacename { interfacename.attlist, cptr.char.mix* }

- # end of interfacename.element

- interfacename.attlist &=

-   common.attrib, interfacename.role.attrib, local.interfacename.attrib

- # end of interfacename.attlist

- 

- # end of interfacename.module

- local.exceptionname.attrib = empty

- exceptionname.role.attrib = role.attrib

- # doc:The name of an exception.

- exceptionname =

-   element exceptionname { exceptionname.attlist, smallcptr.char.mix* }

- # end of exceptionname.element

- exceptionname.attlist &=

-   common.attrib, exceptionname.role.attrib, local.exceptionname.attrib

- # end of exceptionname.attlist

- 

- # end of exceptionname.module

- local.fieldsynopsis.attrib = empty

- fieldsynopsis.role.attrib = role.attrib

- # doc:The name of a field in a class definition.

- fieldsynopsis =

-   element fieldsynopsis {

-     fieldsynopsis.attlist, modifier*, type?, varname, initializer?

-   }

- # end of fieldsynopsis.element

- fieldsynopsis.attlist &=

-   attribute language { text }?,

-   common.attrib,

-   fieldsynopsis.role.attrib,

-   local.fieldsynopsis.attrib

- # end of fieldsynopsis.attlist

- 

- # end of fieldsynopsis.module

- local.initializer.attrib = empty

- initializer.role.attrib = role.attrib

- # doc:The initializer for a FieldSynopsis.

- initializer =

-   element initializer { initializer.attlist, smallcptr.char.mix* }

- # end of initializer.element

- initializer.attlist &=

-   common.attrib, initializer.role.attrib, local.initializer.attrib

- # end of initializer.attlist

- 

- # end of initializer.module

- local.constructorsynopsis.attrib = empty

- constructorsynopsis.role.attrib = role.attrib

- # doc:A syntax summary for a constructor.

- constructorsynopsis =

-   element constructorsynopsis {

-     constructorsynopsis.attlist,

-     modifier*,

-     methodname?,

-     (methodparam+ | void?),

-     exceptionname*

-   }

- # end of constructorsynopsis.element

- constructorsynopsis.attlist &=

-   attribute language { text }?,

-   common.attrib,

-   constructorsynopsis.role.attrib,

-   local.constructorsynopsis.attrib

- # end of constructorsynopsis.attlist

- 

- # end of constructorsynopsis.module

- local.destructorsynopsis.attrib = empty

- destructorsynopsis.role.attrib = role.attrib

- # doc:A syntax summary for a destructor.

- destructorsynopsis =

-   element destructorsynopsis {

-     destructorsynopsis.attlist,

-     modifier*,

-     methodname?,

-     (methodparam+ | void?),

-     exceptionname*

-   }

- # end of destructorsynopsis.element

- destructorsynopsis.attlist &=

-   attribute language { text }?,

-   common.attrib,

-   destructorsynopsis.role.attrib,

-   local.destructorsynopsis.attrib

- # end of destructorsynopsis.attlist

- 

- # end of destructorsynopsis.module

- local.methodsynopsis.attrib = empty

- methodsynopsis.role.attrib = role.attrib

- # doc:A syntax summary for a method.

- methodsynopsis =

-   element methodsynopsis {

-     methodsynopsis.attlist,

-     modifier*,

-     (type | void)?,

-     methodname,

-     (methodparam+ | void?),

-     exceptionname*,

-     modifier*

-   }

- # end of methodsynopsis.element

- methodsynopsis.attlist &=

-   attribute language { text }?,

-   common.attrib,

-   methodsynopsis.role.attrib,

-   local.methodsynopsis.attrib

- # end of methodsynopsis.attlist

- 

- # end of methodsynopsis.module

- local.methodname.attrib = empty

- methodname.role.attrib = role.attrib

- # doc:The name of a method.

- methodname =

-   element methodname { methodname.attlist, smallcptr.char.mix* }

- # end of methodname.element

- methodname.attlist &=

-   common.attrib, methodname.role.attrib, local.methodname.attrib

- # end of methodname.attlist

- 

- # end of methodname.module

- local.methodparam.attrib = empty

- methodparam.role.attrib = role.attrib

- # doc:Parameters to a method.

- methodparam =

-   element methodparam {

-     methodparam.attlist,

-     modifier*,

-     type?,

-     ((parameter, initializer?) | funcparams),

-     modifier*

-   }

- # end of methodparam.element

- methodparam.attlist &=

-   [ a:defaultValue = "req" ]

-   attribute choice { "opt" | "req" | "plain" }?,

-   [ a:defaultValue = "norepeat" ]

-   attribute rep { "norepeat" | "repeat" }?,

-   common.attrib,

-   methodparam.role.attrib,

-   local.methodparam.attrib

- # end of methodparam.attlist

- 

- # end of methodparam.module

- 

- # end of classsynopsis.content.module

- 

- # ......................................................................

- 

- # Document information entities and elements ...........................

- 

- # The document information elements include some elements that are

- # currently used only in the document hierarchy module. They are

- # defined here so that they will be available for use in customized

- # document hierarchies.

- 

- # ..................................

- 

- # Ackno ............................

- local.ackno.attrib = empty

- ackno.role.attrib = role.attrib

- # doc:Acknowledgements in an Article.

- ackno = element ackno { ackno.attlist, docinfo.char.mix* }

- # end of ackno.element

- ackno.attlist &= common.attrib, ackno.role.attrib, local.ackno.attrib

- # end of ackno.attlist

- 

- # end of ackno.module

- 

- # Address ..........................

- local.address.attrib = empty

- address.role.attrib = role.attrib

- # doc:A real-world address, generally a postal address.

- address =

-   element address {

-     address.attlist,

-     (text

-      | personname

-      | person.ident.mix

-      | street

-      | pob

-      | postcode

-      | city

-      | state

-      | country

-      | phone

-      | fax

-      | email

-      | otheraddr)*

-   }

- # end of address.element

- address.attlist &=

-   linespecific.attrib,

-   common.attrib,

-   address.role.attrib,

-   local.address.attrib

- # end of address.attlist

- 

- # end of address.module

- local.street.attrib = empty

- street.role.attrib = role.attrib

- # doc:A street address in an address.

- street = element street { street.attlist, docinfo.char.mix* }

- # end of street.element

- street.attlist &= common.attrib, street.role.attrib, local.street.attrib

- # end of street.attlist

- 

- # end of street.module

- local.pob.attrib = empty

- pob.role.attrib = role.attrib

- # doc:A post office box in an address.

- pob = element pob { pob.attlist, docinfo.char.mix* }

- # end of pob.element

- pob.attlist &= common.attrib, pob.role.attrib, local.pob.attrib

- # end of pob.attlist

- 

- # end of pob.module

- local.postcode.attrib = empty

- postcode.role.attrib = role.attrib

- # doc:A postal code in an address.

- postcode = element postcode { postcode.attlist, docinfo.char.mix* }

- # end of postcode.element

- postcode.attlist &=

-   common.attrib, postcode.role.attrib, local.postcode.attrib

- # end of postcode.attlist

- 

- # end of postcode.module

- local.city.attrib = empty

- city.role.attrib = role.attrib

- # doc:The name of a city in an address.

- city = element city { city.attlist, docinfo.char.mix* }

- # end of city.element

- city.attlist &= common.attrib, city.role.attrib, local.city.attrib

- # end of city.attlist

- 

- # end of city.module

- local.state.attrib = empty

- state.role.attrib = role.attrib

- # doc:A state or province in an address.

- state = element state { state.attlist, docinfo.char.mix* }

- # end of state.element

- state.attlist &= common.attrib, state.role.attrib, local.state.attrib

- # end of state.attlist

- 

- # end of state.module

- local.country.attrib = empty

- country.role.attrib = role.attrib

- # doc:The name of a country.

- country = element country { country.attlist, docinfo.char.mix* }

- # end of country.element

- country.attlist &=

-   common.attrib, country.role.attrib, local.country.attrib

- # end of country.attlist

- 

- # end of country.module

- local.phone.attrib = empty

- phone.role.attrib = role.attrib

- # doc:A telephone number.

- phone = element phone { phone.attlist, docinfo.char.mix* }

- # end of phone.element

- phone.attlist &= common.attrib, phone.role.attrib, local.phone.attrib

- # end of phone.attlist

- 

- # end of phone.module

- local.fax.attrib = empty

- fax.role.attrib = role.attrib

- # doc:A fax number.

- fax = element fax { fax.attlist, docinfo.char.mix* }

- # end of fax.element

- fax.attlist &= common.attrib, fax.role.attrib, local.fax.attrib

- # end of fax.attlist

- 

- # end of fax.module

- 

- # Email (defined in the Inlines section, below)

- local.otheraddr.attrib = empty

- otheraddr.role.attrib = role.attrib

- # doc:Uncategorized information in address.

- otheraddr = element otheraddr { otheraddr.attlist, docinfo.char.mix* }

- # end of otheraddr.element

- otheraddr.attlist &=

-   common.attrib, otheraddr.role.attrib, local.otheraddr.attrib

- # end of otheraddr.attlist

- 

- # end of otheraddr.module

- 

- # end of address.content.module

- 

- # Affiliation ......................

- local.affiliation.attrib = empty

- affiliation.role.attrib = role.attrib

- # doc:The institutional affiliation of an individual.

- affiliation =

-   element affiliation {

-     affiliation.attlist,

-     shortaffil?,

-     jobtitle*,

-     orgname?,

-     orgdiv*,

-     address*

-   }

- # end of affiliation.element

- affiliation.attlist &=

-   common.attrib, affiliation.role.attrib, local.affiliation.attrib

- # end of affiliation.attlist

- 

- # end of affiliation.module

- local.shortaffil.attrib = empty

- shortaffil.role.attrib = role.attrib

- # doc:A brief description of an affiliation.

- shortaffil =

-   element shortaffil { shortaffil.attlist, docinfo.char.mix* }

- # end of shortaffil.element

- shortaffil.attlist &=

-   common.attrib, shortaffil.role.attrib, local.shortaffil.attrib

- # end of shortaffil.attlist

- 

- # end of shortaffil.module

- local.jobtitle.attrib = empty

- jobtitle.role.attrib = role.attrib

- # doc:The title of an individual in an organization.

- jobtitle = element jobtitle { jobtitle.attlist, docinfo.char.mix* }

- # end of jobtitle.element

- jobtitle.attlist &=

-   common.attrib, jobtitle.role.attrib, local.jobtitle.attrib

- # end of jobtitle.attlist

- 

- # end of jobtitle.module

- 

- # OrgName (defined elsewhere in this section)

- local.orgdiv.attrib = empty

- orgdiv.role.attrib = role.attrib

- # doc:A division of an organization.

- orgdiv = element orgdiv { orgdiv.attlist, docinfo.char.mix* }

- # end of orgdiv.element

- orgdiv.attlist &= common.attrib, orgdiv.role.attrib, local.orgdiv.attrib

- # end of orgdiv.attlist

- 

- # end of orgdiv.module

- 

- # Address (defined elsewhere in this section)

- 

- # end of affiliation.content.module

- 

- # ArtPageNums ......................

- local.artpagenums.attrib = empty

- artpagenums.role.attrib = role.attrib

- # doc:The page numbers of an article as published.

- artpagenums =

-   element artpagenums { artpagenums.attlist, docinfo.char.mix* }

- # end of artpagenums.element

- artpagenums.attlist &=

-   common.attrib, artpagenums.role.attrib, local.artpagenums.attrib

- # end of artpagenums.attlist

- 

- # end of artpagenums.module

- 

- # PersonName

- local.personname.attrib = empty

- personname.role.attrib = role.attrib

- # doc:The personal name of an individual.

- personname =

-   element personname {

-     personname.attlist,

-     (honorific | firstname | surname | lineage | othername)+

-   }

- # end of personname.element

- personname.attlist &=

-   common.attrib, personname.role.attrib, local.personname.attrib

- # end of personname.attlist

- 

- # end of personname.module

- 

- # Author ...........................

- local.author.attrib = empty

- author.role.attrib = role.attrib

- # doc:The name of an individual author.

- author =

-   element author {

-     author.attlist,

-     (personname | person.ident.mix+),

-     (personblurb | email | address)*

-   }

- # end of author.element

- author.attlist &= common.attrib, author.role.attrib, local.author.attrib

- # end of author.attlist

- 

- # (see "Personal identity elements" for %person.ident.mix;)

- 

- # end of author.module

- 

- # AuthorGroup ......................

- local.authorgroup.attrib = empty

- authorgroup.role.attrib = role.attrib

- # doc:Wrapper for author information when a document has multiple authors or collabarators.

- authorgroup =

-   element authorgroup {

-     authorgroup.attlist,

-     (author | editor | collab | corpauthor | corpcredit | othercredit)+

-   }

- # end of authorgroup.element

- authorgroup.attlist &=

-   common.attrib, authorgroup.role.attrib, local.authorgroup.attrib

- # end of authorgroup.attlist

- 

- # end of authorgroup.module

- 

- # Author (defined elsewhere in this section)

- 

- # Editor (defined elsewhere in this section)

- local.collab.attrib = empty

- collab.role.attrib = role.attrib

- # doc:Identifies a collaborator.

- collab = element collab { collab.attlist, collabname, affiliation* }

- # end of collab.element

- collab.attlist &= common.attrib, collab.role.attrib, local.collab.attrib

- # end of collab.attlist

- 

- # end of collab.module

- local.collabname.attrib = empty

- collabname.role.attrib = role.attrib

- # doc:The name of a collaborator.

- collabname =

-   element collabname { collabname.attlist, docinfo.char.mix* }

- # end of collabname.element

- collabname.attlist &=

-   common.attrib, collabname.role.attrib, local.collabname.attrib

- # end of collabname.attlist

- 

- # end of collabname.module

- 

- # Affiliation (defined elsewhere in this section)

- 

- # end of collab.content.module

- 

- # CorpAuthor (defined elsewhere in this section)

- 

- # OtherCredit (defined elsewhere in this section)

- 

- # end of authorgroup.content.module

- 

- # AuthorInitials ...................

- local.authorinitials.attrib = empty

- authorinitials.role.attrib = role.attrib

- # doc:The initials or other short identifier for an author.

- authorinitials =

-   element authorinitials { authorinitials.attlist, docinfo.char.mix* }

- # end of authorinitials.element

- authorinitials.attlist &=

-   common.attrib, authorinitials.role.attrib, local.authorinitials.attrib

- # end of authorinitials.attlist

- 

- # end of authorinitials.module

- 

- # ConfGroup ........................

- local.confgroup.attrib = empty

- confgroup.role.attrib = role.attrib

- # doc:A wrapper for document meta-information about a conference.

- confgroup =

-   element confgroup {

-     confgroup.attlist,

-     (confdates | conftitle | confnum | address | confsponsor)*

-   }

- # end of confgroup.element

- confgroup.attlist &=

-   common.attrib, confgroup.role.attrib, local.confgroup.attrib

- # end of confgroup.attlist

- 

- # end of confgroup.module

- local.confdates.attrib = empty

- confdates.role.attrib = role.attrib

- # doc:The dates of a conference for which a document was written.

- confdates = element confdates { confdates.attlist, docinfo.char.mix* }

- # end of confdates.element

- confdates.attlist &=

-   common.attrib, confdates.role.attrib, local.confdates.attrib

- # end of confdates.attlist

- 

- # end of confdates.module

- local.conftitle.attrib = empty

- conftitle.role.attrib = role.attrib

- # doc:The title of a conference for which a document was written.

- conftitle = element conftitle { conftitle.attlist, docinfo.char.mix* }

- # end of conftitle.element

- conftitle.attlist &=

-   common.attrib, conftitle.role.attrib, local.conftitle.attrib

- # end of conftitle.attlist

- 

- # end of conftitle.module

- local.confnum.attrib = empty

- confnum.role.attrib = role.attrib

- # doc:An identifier, frequently numerical, associated with a conference for which a document was written.

- confnum = element confnum { confnum.attlist, docinfo.char.mix* }

- # end of confnum.element

- confnum.attlist &=

-   common.attrib, confnum.role.attrib, local.confnum.attrib

- # end of confnum.attlist

- 

- # end of confnum.module

- 

- # Address (defined elsewhere in this section)

- local.confsponsor.attrib = empty

- confsponsor.role.attrib = role.attrib

- # doc:The sponsor of a conference for which a document was written.

- confsponsor =

-   element confsponsor { confsponsor.attlist, docinfo.char.mix* }

- # end of confsponsor.element

- confsponsor.attlist &=

-   common.attrib, confsponsor.role.attrib, local.confsponsor.attrib

- # end of confsponsor.attlist

- 

- # end of confsponsor.module

- 

- # end of confgroup.content.module

- 

- # ContractNum ......................

- local.contractnum.attrib = empty

- contractnum.role.attrib = role.attrib

- # doc:The contract number of a document.

- contractnum =

-   element contractnum { contractnum.attlist, docinfo.char.mix* }

- # end of contractnum.element

- contractnum.attlist &=

-   common.attrib, contractnum.role.attrib, local.contractnum.attrib

- # end of contractnum.attlist

- 

- # end of contractnum.module

- 

- # ContractSponsor ..................

- local.contractsponsor.attrib = empty

- contractsponsor.role.attrib = role.attrib

- # doc:The sponsor of a contract.

- contractsponsor =

-   element contractsponsor { contractsponsor.attlist, docinfo.char.mix* }

- # end of contractsponsor.element

- contractsponsor.attlist &=

-   common.attrib,

-   contractsponsor.role.attrib,

-   local.contractsponsor.attrib

- # end of contractsponsor.attlist

- 

- # end of contractsponsor.module

- 

- # Copyright ........................

- local.copyright.attrib = empty

- copyright.role.attrib = role.attrib

- # doc:Copyright information about a document.

- copyright = element copyright { copyright.attlist, year+, holder* }

- # end of copyright.element

- copyright.attlist &=

-   common.attrib, copyright.role.attrib, local.copyright.attrib

- # end of copyright.attlist

- 

- # end of copyright.module

- local.year.attrib = empty

- year.role.attrib = role.attrib

- # doc:The year of publication of a document.

- year = element year { year.attlist, docinfo.char.mix* }

- # end of year.element

- year.attlist &= common.attrib, year.role.attrib, local.year.attrib

- # end of year.attlist

- 

- # end of year.module

- local.holder.attrib = empty

- holder.role.attrib = role.attrib

- # doc:The name of the individual or organization that holds a copyright.

- holder = element holder { holder.attlist, docinfo.char.mix* }

- # end of holder.element

- holder.attlist &= common.attrib, holder.role.attrib, local.holder.attrib

- # end of holder.attlist

- 

- # end of holder.module

- 

- # end of copyright.content.module

- 

- # CorpAuthor .......................

- local.corpauthor.attrib = empty

- corpauthor.role.attrib = role.attrib

- # doc:A corporate author, as opposed to an individual.

- corpauthor =

-   element corpauthor { corpauthor.attlist, docinfo.char.mix* }

- # end of corpauthor.element

- corpauthor.attlist &=

-   common.attrib, corpauthor.role.attrib, local.corpauthor.attrib

- # end of corpauthor.attlist

- 

- # end of corpauthor.module

- 

- # CorpCredit ......................

- local.corpcredit.attrib = empty

- corpcredit.role.attrib = role.attrib

- # doc:A corporation or organization credited in a document.

- corpcredit =

-   element corpcredit { corpcredit.attlist, docinfo.char.mix* }

- # end of corpcredit.element

- corpcredit.attlist &=

-   attribute class {

-     "graphicdesigner"

-     | "productioneditor"

-     | "copyeditor"

-     | "technicaleditor"

-     | "translator"

-     | "other"

-   }?,

-   common.attrib,

-   corpcredit.role.attrib,

-   local.corpcredit.attrib

- # end of corpcredit.attlist

- 

- # end of corpcredit.module

- 

- # CorpName .........................

- local.corpname.attrib = empty

- # doc:The name of a corporation.

- corpname = element corpname { corpname.attlist, docinfo.char.mix* }

- # end of corpname.element

- corpname.role.attrib = role.attrib

- corpname.attlist &=

-   common.attrib, corpname.role.attrib, local.corpname.attrib

- # end of corpname.attlist

- 

- # end of corpname.module

- 

- # Date .............................

- local.date.attrib = empty

- date.role.attrib = role.attrib

- # doc:The date of publication or revision of a document.

- date = element date { date.attlist, docinfo.char.mix* }

- # end of date.element

- date.attlist &= common.attrib, date.role.attrib, local.date.attrib

- # end of date.attlist

- 

- # end of date.module

- 

- # Edition ..........................

- local.edition.attrib = empty

- edition.role.attrib = role.attrib

- # doc:The name or number of an edition of a document.

- edition = element edition { edition.attlist, docinfo.char.mix* }

- # end of edition.element

- edition.attlist &=

-   common.attrib, edition.role.attrib, local.edition.attrib

- # end of edition.attlist

- 

- # end of edition.module

- 

- # Editor ...........................

- local.editor.attrib = empty

- editor.role.attrib = role.attrib

- # doc:The name of the editor of a document.

- editor =

-   element editor {

-     editor.attlist,

-     (personname | person.ident.mix+),

-     (personblurb | email | address)*

-   }

- # end of editor.element

- editor.attlist &= common.attrib, editor.role.attrib, local.editor.attrib

- # end of editor.attlist

- 

- # (see "Personal identity elements" for %person.ident.mix;)

- 

- # end of editor.module

- 

- # ISBN .............................

- local.isbn.attrib = empty

- isbn.role.attrib = role.attrib

- # doc:The International Standard Book Number of a document.

- isbn = element isbn { isbn.attlist, docinfo.char.mix* }

- # end of isbn.element

- isbn.attlist &= common.attrib, isbn.role.attrib, local.isbn.attrib

- # end of isbn.attlist

- 

- # end of isbn.module

- 

- # ISSN .............................

- local.issn.attrib = empty

- issn.role.attrib = role.attrib

- # doc:The International Standard Serial Number of a periodical.

- issn = element issn { issn.attlist, docinfo.char.mix* }

- # end of issn.element

- issn.attlist &= common.attrib, issn.role.attrib, local.issn.attrib

- # end of issn.attlist

- 

- # end of issn.module

- 

- # BiblioId .................

- biblio.class.attrib =

-   attribute class {

-     "uri"

-     | "doi"

-     | "isbn"

-     | "isrn"

-     | "issn"

-     | "libraryofcongress"

-     | "pubnumber"

-     | "other"

-   }?,

-   attribute otherclass { text }?

- local.biblioid.attrib = empty

- biblioid.role.attrib = role.attrib

- # doc:An identifier for a document.

- biblioid = element biblioid { biblioid.attlist, docinfo.char.mix* }

- # end of biblioid.element

- biblioid.attlist &=

-   biblio.class.attrib,

-   common.attrib,

-   biblioid.role.attrib,

-   local.biblioid.attrib

- # end of biblioid.attlist

- 

- # end of biblioid.module

- 

- # CiteBiblioId .................

- local.citebiblioid.attrib = empty

- citebiblioid.role.attrib = role.attrib

- # doc:A citation of a bibliographic identifier.

- citebiblioid =

-   element citebiblioid { citebiblioid.attlist, docinfo.char.mix* }

- # end of citebiblioid.element

- citebiblioid.attlist &=

-   biblio.class.attrib,

-   common.attrib,

-   citebiblioid.role.attrib,

-   local.citebiblioid.attrib

- # end of citebiblioid.attlist

- 

- # end of citebiblioid.module

- 

- # BiblioSource .................

- local.bibliosource.attrib = empty

- bibliosource.role.attrib = role.attrib

- # doc:The source of a document.

- bibliosource =

-   element bibliosource { bibliosource.attlist, docinfo.char.mix* }

- # end of bibliosource.element

- bibliosource.attlist &=

-   biblio.class.attrib,

-   common.attrib,

-   bibliosource.role.attrib,

-   local.bibliosource.attrib

- # end of bibliosource.attlist

- 

- # end of bibliosource.module

- 

- # BiblioRelation .................

- local.bibliorelation.attrib = empty

- local.bibliorelation.types = notAllowed

- bibliorelation.type.attrib =

-   attribute type {

-     "isversionof"

-     | "hasversion"

-     | "isreplacedby"

-     | "replaces"

-     | "isrequiredby"

-     | "requires"

-     | "ispartof"

-     | "haspart"

-     | "isreferencedby"

-     | "references"

-     | "isformatof"

-     | "hasformat"

-     | "othertype"

-     | local.bibliorelation.types

-   }?,

-   attribute othertype { text }?

- bibliorelation.role.attrib = role.attrib

- # doc:The relationship of a document to another.

- bibliorelation =

-   element bibliorelation { bibliorelation.attlist, docinfo.char.mix* }

- # end of bibliorelation.element

- bibliorelation.attlist &=

-   biblio.class.attrib,

-   bibliorelation.type.attrib,

-   common.attrib,

-   bibliorelation.role.attrib,

-   local.bibliorelation.attrib

- # end of bibliorelation.attlist

- 

- # end of bibliorelation.module

- 

- # BiblioCoverage .................

- local.bibliocoverage.attrib = empty

- bibliocoverage.role.attrib = role.attrib

- # doc:The spatial or temporal coverage of a document.

- bibliocoverage =

-   element bibliocoverage { bibliocoverage.attlist, docinfo.char.mix* }

- # end of bibliocoverage.element

- bibliocoverage.attlist &=

-   attribute spatial {

-     "dcmipoint" | "iso3166" | "dcmibox" | "tgn" | "otherspatial"

-   }?,

-   attribute otherspatial { text }?,

-   attribute temporal { "dcmiperiod" | "w3c-dtf" | "othertemporal" }?,

-   attribute othertemporal { text }?,

-   common.attrib,

-   bibliocoverage.role.attrib,

-   local.bibliocoverage.attrib

- # end of bibliocoverage.attlist

- 

- # end of bibliocoverage.module

- 

- # InvPartNumber ....................

- local.invpartnumber.attrib = empty

- invpartnumber.role.attrib = role.attrib

- # doc:An inventory part number.

- invpartnumber =

-   element invpartnumber { invpartnumber.attlist, docinfo.char.mix* }

- # end of invpartnumber.element

- invpartnumber.attlist &=

-   common.attrib, invpartnumber.role.attrib, local.invpartnumber.attrib

- # end of invpartnumber.attlist

- 

- # end of invpartnumber.module

- 

- # IssueNum .........................

- local.issuenum.attrib = empty

- issuenum.role.attrib = role.attrib

- # doc:The number of an issue of a journal.

- issuenum = element issuenum { issuenum.attlist, docinfo.char.mix* }

- # end of issuenum.element

- issuenum.attlist &=

-   common.attrib, issuenum.role.attrib, local.issuenum.attrib

- # end of issuenum.attlist

- 

- # end of issuenum.module

- 

- # LegalNotice ......................

- local.legalnotice.attrib = empty

- legalnotice.role.attrib = role.attrib

- # doc:A statement of legal obligations or requirements.

- legalnotice =

-   element legalnotice {

-     legalnotice.attlist, blockinfo?, title?, legalnotice.mix+

-   }

- # end of legalnotice.element

- legalnotice.attlist &=

-   common.attrib, legalnotice.role.attrib, local.legalnotice.attrib

- # end of legalnotice.attlist

- 

- # end of legalnotice.module

- 

- # ModeSpec .........................

- local.modespec.attrib = empty

- modespec.role.attrib = role.attrib

- # doc:Application-specific information necessary for the completion of an OLink.

- modespec = element modespec { modespec.attlist, docinfo.char.mix* }

- # end of modespec.element

- 

- # Application: Type of action required for completion

- # of the links to which the ModeSpec is relevant (e.g.,

- # retrieval query)

- modespec.attlist &=

-   attribute application { notation.class }?,

-   common.attrib,

-   modespec.role.attrib,

-   local.modespec.attrib

- # end of modespec.attlist

- 

- # end of modespec.module

- 

- # OrgName ..........................

- local.orgname.attrib = empty

- orgname.role.attrib = role.attrib

- # doc:The name of an organization other than a corporation.

- orgname = element orgname { orgname.attlist, docinfo.char.mix* }

- # end of orgname.element

- orgname.attlist &=

-   common.attrib,

-   attribute class {

-     "corporation" | "nonprofit" | "consortium" | "informal" | "other"

-   }?,

-   attribute otherclass { text }?,

-   orgname.role.attrib,

-   local.orgname.attrib

- # end of orgname.attlist

- 

- # end of orgname.module

- 

- # OtherCredit ......................

- local.othercredit.attrib = empty

- othercredit.role.attrib = role.attrib

- # doc:A person or entity, other than an author or editor, credited in a document.

- othercredit =

-   element othercredit {

-     othercredit.attlist,

-     (personname | person.ident.mix+),

-     (personblurb | email | address)*

-   }

- # end of othercredit.element

- othercredit.attlist &=

-   attribute class {

-     "graphicdesigner"

-     | "productioneditor"

-     | "copyeditor"

-     | "technicaleditor"

-     | "translator"

-     | "other"

-   }?,

-   common.attrib,

-   othercredit.role.attrib,

-   local.othercredit.attrib

- # end of othercredit.attlist

- 

- # (see "Personal identity elements" for %person.ident.mix;)

- 

- # end of othercredit.module

- 

- # PageNums .........................

- local.pagenums.attrib = empty

- pagenums.role.attrib = role.attrib

- # doc:The numbers of the pages in a book, for use in a bibliographic entry.

- pagenums = element pagenums { pagenums.attlist, docinfo.char.mix* }

- # end of pagenums.element

- pagenums.attlist &=

-   common.attrib, pagenums.role.attrib, local.pagenums.attrib

- # end of pagenums.attlist

- 

- # end of pagenums.module

- 

- # Personal identity elements .......

- 

- # These elements are used only within Author, Editor, and

- # OtherCredit.

- local.contrib.attrib = empty

- contrib.role.attrib = role.attrib

- # doc:A summary of the contributions made to a document by a credited source.

- contrib = element contrib { contrib.attlist, docinfo.char.mix* }

- # end of contrib.element

- contrib.attlist &=

-   common.attrib, contrib.role.attrib, local.contrib.attrib

- # end of contrib.attlist

- 

- # end of contrib.module

- local.firstname.attrib = empty

- firstname.role.attrib = role.attrib

- # doc:The first name of a person.

- firstname = element firstname { firstname.attlist, docinfo.char.mix* }

- # end of firstname.element

- firstname.attlist &=

-   common.attrib, firstname.role.attrib, local.firstname.attrib

- # end of firstname.attlist

- 

- # end of firstname.module

- local.honorific.attrib = empty

- honorific.role.attrib = role.attrib

- # doc:The title of a person.

- honorific = element honorific { honorific.attlist, docinfo.char.mix* }

- # end of honorific.element

- honorific.attlist &=

-   common.attrib, honorific.role.attrib, local.honorific.attrib

- # end of honorific.attlist

- 

- # end of honorific.module

- local.lineage.attrib = empty

- lineage.role.attrib = role.attrib

- # doc:The portion of a person's name indicating a relationship to ancestors.

- lineage = element lineage { lineage.attlist, docinfo.char.mix* }

- # end of lineage.element

- lineage.attlist &=

-   common.attrib, lineage.role.attrib, local.lineage.attrib

- # end of lineage.attlist

- 

- # end of lineage.module

- local.othername.attrib = empty

- othername.role.attrib = role.attrib

- # doc:A component of a persons name that is not a first name, surname, or lineage.

- othername = element othername { othername.attlist, docinfo.char.mix* }

- # end of othername.element

- othername.attlist &=

-   common.attrib, othername.role.attrib, local.othername.attrib

- # end of othername.attlist

- 

- # end of othername.module

- local.surname.attrib = empty

- surname.role.attrib = role.attrib

- # doc:A family name; in western cultures the last name.

- surname = element surname { surname.attlist, docinfo.char.mix* }

- # end of surname.element

- surname.attlist &=

-   common.attrib, surname.role.attrib, local.surname.attrib

- # end of surname.attlist

- 

- # end of surname.module

- 

- # end of person.ident.module

- 

- # PrintHistory .....................

- local.printhistory.attrib = empty

- printhistory.role.attrib = role.attrib

- # doc:The printing history of a document.

- printhistory =

-   element printhistory { printhistory.attlist, para.class+ }

- # end of printhistory.element

- printhistory.attlist &=

-   common.attrib, printhistory.role.attrib, local.printhistory.attrib

- # end of printhistory.attlist

- 

- # end of printhistory.module

- 

- # ProductName ......................

- local.productname.attrib = empty

- productname.role.attrib = role.attrib

- # doc:The formal name of a product.

- productname =

-   element productname { productname.attlist, para.char.mix* }

- # end of productname.element

- 

- # Class: More precisely identifies the item the element names

- productname.attlist &=

-   [ a:defaultValue = "trade" ]

-   attribute class { "service" | "trade" | "registered" | "copyright" }?,

-   common.attrib,

-   productname.role.attrib,

-   local.productname.attrib

- # end of productname.attlist

- 

- # end of productname.module

- 

- # ProductNumber ....................

- local.productnumber.attrib = empty

- productnumber.role.attrib = role.attrib

- # doc:A number assigned to a product.

- productnumber =

-   element productnumber { productnumber.attlist, docinfo.char.mix* }

- # end of productnumber.element

- productnumber.attlist &=

-   common.attrib, productnumber.role.attrib, local.productnumber.attrib

- # end of productnumber.attlist

- 

- # end of productnumber.module

- 

- # PubDate ..........................

- local.pubdate.attrib = empty

- pubdate.role.attrib = role.attrib

- # doc:The date of publication of a document.

- pubdate = element pubdate { pubdate.attlist, docinfo.char.mix* }

- # end of pubdate.element

- pubdate.attlist &=

-   common.attrib, pubdate.role.attrib, local.pubdate.attrib

- # end of pubdate.attlist

- 

- # end of pubdate.module

- 

- # Publisher ........................

- local.publisher.attrib = empty

- publisher.role.attrib = role.attrib

- # doc:The publisher of a document.

- publisher =

-   element publisher { publisher.attlist, publishername, address* }

- # end of publisher.element

- publisher.attlist &=

-   common.attrib, publisher.role.attrib, local.publisher.attrib

- # end of publisher.attlist

- 

- # end of publisher.module

- local.publishername.attrib = empty

- publishername.role.attrib = role.attrib

- # doc:The name of the publisher of a document.

- publishername =

-   element publishername { publishername.attlist, docinfo.char.mix* }

- # end of publishername.element

- publishername.attlist &=

-   common.attrib, publishername.role.attrib, local.publishername.attrib

- # end of publishername.attlist

- 

- # end of publishername.module

- 

- # Address (defined elsewhere in this section)

- 

- # end of publisher.content.module

- 

- # PubsNumber .......................

- local.pubsnumber.attrib = empty

- pubsnumber.role.attrib = role.attrib

- # doc:A number assigned to a publication other than an ISBN or ISSN or inventory part number.

- pubsnumber =

-   element pubsnumber { pubsnumber.attlist, docinfo.char.mix* }

- # end of pubsnumber.element

- pubsnumber.attlist &=

-   common.attrib, pubsnumber.role.attrib, local.pubsnumber.attrib

- # end of pubsnumber.attlist

- 

- # end of pubsnumber.module

- 

- # ReleaseInfo ......................

- local.releaseinfo.attrib = empty

- releaseinfo.role.attrib = role.attrib

- # doc:Information about a particular release of a document.

- releaseinfo =

-   element releaseinfo { releaseinfo.attlist, docinfo.char.mix* }

- # end of releaseinfo.element

- releaseinfo.attlist &=

-   common.attrib, releaseinfo.role.attrib, local.releaseinfo.attrib

- # end of releaseinfo.attlist

- 

- # end of releaseinfo.module

- 

- # RevHistory .......................

- local.revhistory.attrib = empty

- revhistory.role.attrib = role.attrib

- # doc:A history of the revisions to a document.

- revhistory = element revhistory { revhistory.attlist, revision+ }

- # end of revhistory.element

- revhistory.attlist &=

-   common.attrib, revhistory.role.attrib, local.revhistory.attrib

- # end of revhistory.attlist

- 

- # end of revhistory.module

- local.revision.attrib = empty

- revision.role.attrib = role.attrib

- # doc:An entry describing a single revision in the history of the revisions to a document.

- revision =

-   element revision {

-     revision.attlist,

-     revnumber?,

-     date,

-     (author | authorinitials)*,

-     (revremark | revdescription)?

-   }

- # end of revision.element

- revision.attlist &=

-   common.attrib, revision.role.attrib, local.revision.attrib

- # end of revision.attlist

- 

- # end of revision.module

- local.revnumber.attrib = empty

- revnumber.role.attrib = role.attrib

- # doc:A document revision number.

- revnumber = element revnumber { revnumber.attlist, docinfo.char.mix* }

- # end of revnumber.element

- revnumber.attlist &=

-   common.attrib, revnumber.role.attrib, local.revnumber.attrib

- # end of revnumber.attlist

- 

- # end of revnumber.module

- 

- # Date (defined elsewhere in this section)

- 

- # AuthorInitials (defined elsewhere in this section)

- local.revremark.attrib = empty

- revremark.role.attrib = role.attrib

- # doc:A description of a revision to a document.

- revremark = element revremark { revremark.attlist, docinfo.char.mix* }

- # end of revremark.element

- revremark.attlist &=

-   common.attrib, revremark.role.attrib, local.revremark.attrib

- # end of revremark.attlist

- 

- # end of revremark.module

- local.revdescription.attrib = empty

- revdescription.role.attrib = role.attrib

- # doc:A extended description of a revision to a document.

- revdescription =

-   element revdescription { revdescription.attlist, revdescription.mix+ }

- # end of revdescription.element

- revdescription.attlist &=

-   common.attrib, revdescription.role.attrib, local.revdescription.attrib

- # end of revdescription.attlist

- 

- # end of revdescription.module

- 

- # end of revhistory.content.module

- 

- # SeriesVolNums ....................

- local.seriesvolnums.attrib = empty

- seriesvolnums.role.attrib = role.attrib

- # doc:Numbers of the volumes in a series of books.

- seriesvolnums =

-   element seriesvolnums { seriesvolnums.attlist, docinfo.char.mix* }

- # end of seriesvolnums.element

- seriesvolnums.attlist &=

-   common.attrib, seriesvolnums.role.attrib, local.seriesvolnums.attrib

- # end of seriesvolnums.attlist

- 

- # end of seriesvolnums.module

- 

- # VolumeNum ........................

- local.volumenum.attrib = empty

- volumenum.role.attrib = role.attrib

- # doc:The volume number of a document in a set (as of books in a set or articles in a journal).

- volumenum = element volumenum { volumenum.attlist, docinfo.char.mix* }

- # end of volumenum.element

- volumenum.attlist &=

-   common.attrib, volumenum.role.attrib, local.volumenum.attrib

- # end of volumenum.attlist

- 

- # end of volumenum.module

- 

- # ..................................

- 

- # end of docinfo.content.module

- 

- # ......................................................................

- 

- # Inline, link, and ubiquitous elements ................................

- 

- # Technical and computer terms .........................................

- local.accel.attrib = empty

- accel.role.attrib = role.attrib

- # doc:A graphical user interface (GUI) keyboard shortcut.

- accel = element accel { accel.attlist, smallcptr.char.mix* }

- # end of accel.element

- accel.attlist &= common.attrib, accel.role.attrib, local.accel.attrib

- # end of accel.attlist

- 

- # end of accel.module

- local.action.attrib = empty

- action.role.attrib = role.attrib

- # doc:A response to a user event.

- action = element action { action.attlist, cptr.char.mix* }

- # end of action.element

- action.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   action.role.attrib,

-   local.action.attrib

- # end of action.attlist

- 

- # end of action.module

- local.application.attrib = empty

- application.role.attrib = role.attrib

- # doc:The name of a software program.

- application =

-   element application { application.attlist, para.char.mix* }

- # end of application.element

- application.attlist &=

-   attribute class { "hardware" | "software" }?,

-   moreinfo.attrib,

-   common.attrib,

-   application.role.attrib,

-   local.application.attrib

- # end of application.attlist

- 

- # end of application.module

- local.classname.attrib = empty

- classname.role.attrib = role.attrib

- # doc:The name of a class, in the object-oriented programming sense.

- classname = element classname { classname.attlist, smallcptr.char.mix* }

- # end of classname.element

- classname.attlist &=

-   common.attrib, classname.role.attrib, local.classname.attrib

- # end of classname.attlist

- 

- # end of classname.module

- local.package.attrib = empty

- package.role.attrib = role.attrib

- # doc:A package.

- package = element package { package.attlist, smallcptr.char.mix* }

- # end of package.element

- package.attlist &=

-   common.attrib, package.role.attrib, local.package.attrib

- # end of package.attlist

- 

- # end of package.module

- local.co.attrib = empty

- # CO is a callout area of the LineColumn unit type (a single character

- # position); the position is directly indicated by the location of CO.

- co.role.attrib = role.attrib

- # doc:The location of a callout embedded in text.

- co = element co { co.attlist, empty }

- # end of co.element

- 

- # bug number/symbol override or initialization

- 

- # to any related information

- co.attlist &=

-   label.attrib,

-   linkends.attrib,

-   idreq.common.attrib,

-   co.role.attrib,

-   local.co.attrib

- # end of co.attlist

- 

- # end of co.module

- local.coref.attrib = empty

- # COREF is a reference to a CO

- coref.role.attrib = role.attrib

- # doc:A cross reference to a co.

- coref = element coref { coref.attlist, empty }

- # end of coref.element

- 

- # bug number/symbol override or initialization

- 

- # to any related information

- coref.attlist &=

-   label.attrib,

-   linkendreq.attrib,

-   common.attrib,

-   coref.role.attrib,

-   local.coref.attrib

- # end of coref.attlist

- 

- # end of coref.module

- local.command.attrib = empty

- command.role.attrib = role.attrib

- # doc:The name of an executable program or other software command.

- command = element command { command.attlist, cptr.char.mix* }

- # end of command.element

- command.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   command.role.attrib,

-   local.command.attrib

- # end of command.attlist

- 

- # end of command.module

- local.computeroutput.attrib = empty

- computeroutput.role.attrib = role.attrib

- # doc:Data, generally text, displayed or presented by a computer.

- computeroutput =

-   element computeroutput {

-     computeroutput.attlist, (cptr.char.mix | co)*

-   }

- # end of computeroutput.element

- computeroutput.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   computeroutput.role.attrib,

-   local.computeroutput.attrib

- # end of computeroutput.attlist

- 

- # end of computeroutput.module

- local.database.attrib = empty

- database.role.attrib = role.attrib

- # doc:The name of a database, or part of a database.

- database = element database { database.attlist, cptr.char.mix* }

- # end of database.element

- 

- # Class: Type of database the element names; no default

- database.attlist &=

-   attribute class {

-     "name"

-     | "table"

-     | "field"

-     | "key1"

-     | "key2"

-     | "record"

-     | "index"

-     | "view"

-     | "primarykey"

-     | "secondarykey"

-     | "foreignkey"

-     | "altkey"

-     | "procedure"

-     | "datatype"

-     | "constraint"

-     | "rule"

-     | "user"

-     | "group"

-   }?,

-   moreinfo.attrib,

-   common.attrib,

-   database.role.attrib,

-   local.database.attrib

- # end of database.attlist

- 

- # end of database.module

- local.email.attrib = empty

- email.role.attrib = role.attrib

- # doc:An email address.

- email = element email { email.attlist, docinfo.char.mix* }

- # end of email.element

- email.attlist &= common.attrib, email.role.attrib, local.email.attrib

- # end of email.attlist

- 

- # end of email.module

- local.envar.attrib = empty

- envar.role.attrib = role.attrib

- # doc:A software environment variable.

- envar = element envar { envar.attlist, smallcptr.char.mix* }

- # end of envar.element

- envar.attlist &= common.attrib, envar.role.attrib, local.envar.attrib

- # end of envar.attlist

- 

- # end of envar.module

- local.errorcode.attrib = empty

- errorcode.role.attrib = role.attrib

- # doc:An error code.

- errorcode = element errorcode { errorcode.attlist, smallcptr.char.mix* }

- # end of errorcode.element

- errorcode.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   errorcode.role.attrib,

-   local.errorcode.attrib

- # end of errorcode.attlist

- 

- # end of errorcode.module

- local.errorname.attrib = empty

- errorname.role.attrib = role.attrib

- # doc:An error name.

- errorname = element errorname { errorname.attlist, smallcptr.char.mix* }

- # end of errorname.element

- errorname.attlist &=

-   common.attrib, errorname.role.attrib, local.errorname.attrib

- # end of errorname.attlist

- 

- # end of errorname.module

- local.errortext.attrib = empty

- errortext.role.attrib = role.attrib

- # doc:An error message..

- errortext = element errortext { errortext.attlist, smallcptr.char.mix* }

- # end of errortext.element

- errortext.attlist &=

-   common.attrib, errortext.role.attrib, local.errortext.attrib

- # end of errortext.attlist

- 

- # end of errortext.module

- local.errortype.attrib = empty

- errortype.role.attrib = role.attrib

- # doc:The classification of an error message.

- errortype = element errortype { errortype.attlist, smallcptr.char.mix* }

- # end of errortype.element

- errortype.attlist &=

-   common.attrib, errortype.role.attrib, local.errortype.attrib

- # end of errortype.attlist

- 

- # end of errortype.module

- local.filename.attrib = empty

- filename.role.attrib = role.attrib

- # doc:The name of a file.

- filename = element filename { filename.attlist, cptr.char.mix* }

- # end of filename.element

- 

- # Class: Type of filename the element names; no default

- 

- # Path: Search path (possibly system-specific) in which

- # file can be found

- filename.attlist &=

-   attribute class {

-     "headerfile"

-     | "partition"

-     | "devicefile"

-     | "libraryfile"

-     | "directory"

-     | "extension"

-     | "symlink"

-   }?,

-   attribute path { text }?,

-   moreinfo.attrib,

-   common.attrib,

-   filename.role.attrib,

-   local.filename.attrib

- # end of filename.attlist

- 

- # end of filename.module

- local.function.attrib = empty

- function.role.attrib = role.attrib

- # doc:The name of a function or subroutine, as in a programming language.

- function = element function { function.attlist, cptr.char.mix* }

- # end of function.element

- function.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   function.role.attrib,

-   local.function.attrib

- # end of function.attlist

- 

- # end of function.module

- local.guibutton.attrib = empty

- guibutton.role.attrib = role.attrib

- # doc:The text on a button in a GUI.

- guibutton =

-   element guibutton {

-     guibutton.attlist,

-     (smallcptr.char.mix | accel | superscript | subscript)*

-   }

- # end of guibutton.element

- guibutton.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   guibutton.role.attrib,

-   local.guibutton.attrib

- # end of guibutton.attlist

- 

- # end of guibutton.module

- local.guiicon.attrib = empty

- guiicon.role.attrib = role.attrib

- # doc:Graphic and/or text appearing as a icon in a GUI.

- guiicon =

-   element guiicon {

-     guiicon.attlist,

-     (smallcptr.char.mix | accel | superscript | subscript)*

-   }

- # end of guiicon.element

- guiicon.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   guiicon.role.attrib,

-   local.guiicon.attrib

- # end of guiicon.attlist

- 

- # end of guiicon.module

- local.guilabel.attrib = empty

- guilabel.role.attrib = role.attrib

- # doc:The text of a label in a GUI.

- guilabel =

-   element guilabel {

-     guilabel.attlist,

-     (smallcptr.char.mix | accel | superscript | subscript)*

-   }

- # end of guilabel.element

- guilabel.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   guilabel.role.attrib,

-   local.guilabel.attrib

- # end of guilabel.attlist

- 

- # end of guilabel.module

- local.guimenu.attrib = empty

- guimenu.role.attrib = role.attrib

- # doc:The name of a menu in a GUI.

- guimenu =

-   element guimenu {

-     guimenu.attlist,

-     (smallcptr.char.mix | accel | superscript | subscript)*

-   }

- # end of guimenu.element

- guimenu.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   guimenu.role.attrib,

-   local.guimenu.attrib

- # end of guimenu.attlist

- 

- # end of guimenu.module

- local.guimenuitem.attrib = empty

- guimenuitem.role.attrib = role.attrib

- # doc:The name of a terminal menu item in a GUI.

- guimenuitem =

-   element guimenuitem {

-     guimenuitem.attlist,

-     (smallcptr.char.mix | accel | superscript | subscript)*

-   }

- # end of guimenuitem.element

- guimenuitem.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   guimenuitem.role.attrib,

-   local.guimenuitem.attrib

- # end of guimenuitem.attlist

- 

- # end of guimenuitem.module

- local.guisubmenu.attrib = empty

- guisubmenu.role.attrib = role.attrib

- # doc:The name of a submenu in a GUI.

- guisubmenu =

-   element guisubmenu {

-     guisubmenu.attlist,

-     (smallcptr.char.mix | accel | superscript | subscript)*

-   }

- # end of guisubmenu.element

- guisubmenu.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   guisubmenu.role.attrib,

-   local.guisubmenu.attrib

- # end of guisubmenu.attlist

- 

- # end of guisubmenu.module

- local.hardware.attrib = empty

- hardware.role.attrib = role.attrib

- # doc:A physical part of a computer system.

- hardware = element hardware { hardware.attlist, cptr.char.mix* }

- # end of hardware.element

- hardware.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   hardware.role.attrib,

-   local.hardware.attrib

- # end of hardware.attlist

- 

- # end of hardware.module

- local.interface.attrib = empty

- interface.role.attrib = role.attrib

- # doc:An element of a GUI.

- interface =

-   element interface { interface.attlist, (smallcptr.char.mix | accel)* }

- # end of interface.element

- 

- # Class: Type of the Interface item; no default

- interface.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   interface.role.attrib,

-   local.interface.attrib

- # end of interface.attlist

- 

- # end of interface.module

- local.keycap.attrib = empty

- keycap.role.attrib = role.attrib

- # doc:The text printed on a key on a keyboard.

- keycap = element keycap { keycap.attlist, cptr.char.mix* }

- # end of keycap.element

- keycap.attlist &=

-   attribute function {

-     "alt"

-     | "control"

-     | "shift"

-     | "meta"

-     | "escape"

-     | "enter"

-     | "tab"

-     | "backspace"

-     | "command"

-     | "option"

-     | "space"

-     | "delete"

-     | "insert"

-     | "up"

-     | "down"

-     | "left"

-     | "right"

-     | "home"

-     | "end"

-     | "pageup"

-     | "pagedown"

-     | "other"

-   }?,

-   attribute otherfunction { text }?,

-   moreinfo.attrib,

-   common.attrib,

-   keycap.role.attrib,

-   local.keycap.attrib

- # end of keycap.attlist

- 

- # end of keycap.module

- local.keycode.attrib = empty

- keycode.role.attrib = role.attrib

- # doc:The internal, frequently numeric, identifier for a key on a keyboard.

- keycode = element keycode { keycode.attlist, smallcptr.char.mix* }

- # end of keycode.element

- keycode.attlist &=

-   common.attrib, keycode.role.attrib, local.keycode.attrib

- # end of keycode.attlist

- 

- # end of keycode.module

- local.keycombo.attrib = empty

- keycombo.role.attrib = role.attrib

- # doc:A combination of input actions.

- keycombo =

-   element keycombo {

-     keycombo.attlist, (keycap | keycombo | keysym | mousebutton)+

-   }

- # end of keycombo.element

- keycombo.attlist &=

-   keyaction.attrib,

-   moreinfo.attrib,

-   common.attrib,

-   keycombo.role.attrib,

-   local.keycombo.attrib

- # end of keycombo.attlist

- 

- # end of keycombo.module

- local.keysym.attrib = empty

- keysysm.role.attrib = role.attrib

- # doc:The symbolic name of a key on a keyboard.

- keysym = element keysym { keysym.attlist, smallcptr.char.mix* }

- # end of keysym.element

- keysym.attlist &=

-   common.attrib, keysysm.role.attrib, local.keysym.attrib

- # end of keysym.attlist

- 

- # end of keysym.module

- local.lineannotation.attrib = empty

- lineannotation.role.attrib = role.attrib

- # doc:A comment on a line in a verbatim listing.

- lineannotation =

-   element lineannotation { lineannotation.attlist, para.char.mix* }

- # end of lineannotation.element

- lineannotation.attlist &=

-   common.attrib, lineannotation.role.attrib, local.lineannotation.attrib

- # end of lineannotation.attlist

- 

- # end of lineannotation.module

- local.literal.attrib = empty

- literal.role.attrib = role.attrib

- # doc:Inline text that is some literal value.

- literal = element literal { literal.attlist, cptr.char.mix* }

- # end of literal.element

- literal.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   literal.role.attrib,

-   local.literal.attrib

- # end of literal.attlist

- 

- # end of literal.module

- local.code.attrib = empty

- code.role.attrib = role.attrib

- # doc:An inline code fragment.

- code = element code { code.attlist, cptr.char.mix* }

- # end of code.element

- code.attlist &=

-   attribute language { text }?,

-   common.attrib,

-   code.role.attrib,

-   local.code.attrib

- # end of code.attlist

- 

- # end of code.module

- local.constant.attrib = empty

- constant.role.attrib = role.attrib

- # doc:A programming or system constant.

- constant = element constant { constant.attlist, smallcptr.char.mix* }

- # end of constant.element

- constant.attlist &=

-   attribute class { "limit" }?,

-   common.attrib,

-   constant.role.attrib,

-   local.constant.attrib

- # end of constant.attlist

- 

- # end of constant.module

- local.varname.attrib = empty

- varname.role.attrib = role.attrib

- # doc:The name of a variable.

- varname = element varname { varname.attlist, smallcptr.char.mix* }

- # end of varname.element

- varname.attlist &=

-   common.attrib, varname.role.attrib, local.varname.attrib

- # end of varname.attlist

- 

- # end of varname.module

- local.markup.attrib = empty

- markup.role.attrib = role.attrib

- # doc:A string of formatting markup in text that is to be represented literally.

- markup = element markup { markup.attlist, smallcptr.char.mix* }

- # end of markup.element

- markup.attlist &= common.attrib, markup.role.attrib, local.markup.attrib

- # end of markup.attlist

- 

- # end of markup.module

- local.medialabel.attrib = empty

- medialabel.role.attrib = role.attrib

- # doc:A name that identifies the physical medium on which some information resides.

- medialabel =

-   element medialabel { medialabel.attlist, smallcptr.char.mix* }

- # end of medialabel.element

- 

- # Class: Type of medium named by the element; no default

- medialabel.attlist &=

-   attribute class { "cartridge" | "cdrom" | "disk" | "tape" }?,

-   common.attrib,

-   medialabel.role.attrib,

-   local.medialabel.attrib

- # end of medialabel.attlist

- 

- # end of medialabel.module

- local.menuchoice.attrib = empty

- menuchoice.role.attrib = role.attrib

- # doc:A selection or series of selections from a menu.

- menuchoice =

-   element menuchoice {

-     menuchoice.attlist,

-     shortcut?,

-     (guibutton

-      | guiicon

-      | guilabel

-      | guimenu

-      | guimenuitem

-      | guisubmenu

-      | interface)+

-   }

- # end of menuchoice.element

- menuchoice.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   menuchoice.role.attrib,

-   local.menuchoice.attrib

- # end of menuchoice.attlist

- 

- # end of menuchoice.module

- 

- # See also KeyCombo

- local.shortcut.attrib = empty

- shortcut.role.attrib = role.attrib

- # doc:A key combination for an action that is also accessible through a menu.

- shortcut =

-   element shortcut {

-     shortcut.attlist, (keycap | keycombo | keysym | mousebutton)+

-   }

- # end of shortcut.element

- shortcut.attlist &=

-   keyaction.attrib,

-   moreinfo.attrib,

-   common.attrib,

-   shortcut.role.attrib,

-   local.shortcut.attrib

- # end of shortcut.attlist

- 

- # end of shortcut.module

- 

- # end of menuchoice.content.module

- local.mousebutton.attrib = empty

- mousebutton.role.attrib = role.attrib

- # doc:The conventional name of a mouse button.

- mousebutton =

-   element mousebutton { mousebutton.attlist, smallcptr.char.mix* }

- # end of mousebutton.element

- mousebutton.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   mousebutton.role.attrib,

-   local.mousebutton.attrib

- # end of mousebutton.attlist

- 

- # end of mousebutton.module

- local.msgtext.attrib = empty

- msgtext.role.attrib = role.attrib

- # doc:The actual text of a message component in a message set.

- msgtext = element msgtext { msgtext.attlist, component.mix+ }

- # end of msgtext.element

- msgtext.attlist &=

-   common.attrib, msgtext.role.attrib, local.msgtext.attrib

- # end of msgtext.attlist

- 

- # end of msgtext.module

- local.option.attrib = empty

- option.role.attrib = role.attrib

- # doc:An option for a software command.

- option = element option { option.attlist, cptr.char.mix* }

- # end of option.element

- option.attlist &= common.attrib, option.role.attrib, local.option.attrib

- # end of option.attlist

- 

- # end of option.module

- local.optional.attrib = empty

- optional.role.attrib = role.attrib

- # doc:Optional information.

- optional = element optional { optional.attlist, cptr.char.mix* }

- # end of optional.element

- optional.attlist &=

-   common.attrib, optional.role.attrib, local.optional.attrib

- # end of optional.attlist

- 

- # end of optional.module

- local.parameter.attrib = empty

- parameter.role.attrib = role.attrib

- # doc:A value or a symbolic reference to a value.

- parameter = element parameter { parameter.attlist, cptr.char.mix* }

- # end of parameter.element

- 

- # Class: Type of the Parameter; no default

- parameter.attlist &=

-   attribute class { "command" | "function" | "option" }?,

-   moreinfo.attrib,

-   common.attrib,

-   parameter.role.attrib,

-   local.parameter.attrib

- # end of parameter.attlist

- 

- # end of parameter.module

- local.prompt.attrib = empty

- prompt.role.attrib = role.attrib

- # doc:A character or string indicating the start of an input field in a  computer display.

- prompt = element prompt { prompt.attlist, (smallcptr.char.mix | co)* }

- # end of prompt.element

- prompt.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   prompt.role.attrib,

-   local.prompt.attrib

- # end of prompt.attlist

- 

- # end of prompt.module

- local.property.attrib = empty

- property.role.attrib = role.attrib

- # doc:A unit of data associated with some part of a computer system.

- property = element property { property.attlist, cptr.char.mix* }

- # end of property.element

- property.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   property.role.attrib,

-   local.property.attrib

- # end of property.attlist

- 

- # end of property.module

- local.replaceable.attrib = empty

- replaceable.role.attrib = role.attrib

- # doc:Content that may or must be replaced by the user.

- replaceable =

-   element replaceable {

-     replaceable.attlist,

-     (text

-      | link.char.class

-      | optional

-      | base.char.class

-      | other.char.class

-      | inlinegraphic

-      | inlinemediaobject

-      | co)*

-   }

- # end of replaceable.element

- 

- # Class: Type of information the element represents; no

- # default

- replaceable.attlist &=

-   attribute class { "command" | "function" | "option" | "parameter" }?,

-   common.attrib,

-   replaceable.role.attrib,

-   local.replaceable.attrib

- # end of replaceable.attlist

- 

- # end of replaceable.module

- local.returnvalue.attrib = empty

- returnvalue.role.attrib = role.attrib

- # doc:The value returned by a function.

- returnvalue =

-   element returnvalue { returnvalue.attlist, smallcptr.char.mix* }

- # end of returnvalue.element

- returnvalue.attlist &=

-   common.attrib, returnvalue.role.attrib, local.returnvalue.attrib

- # end of returnvalue.attlist

- 

- # end of returnvalue.module

- local.sgmltag.attrib = empty

- sgmltag.role.attrib = role.attrib

- # doc:A component of SGML markup.

- sgmltag = element sgmltag { sgmltag.attlist, smallcptr.char.mix* }

- # end of sgmltag.element

- 

- # Class: Type of SGML construct the element names; no default

- sgmltag.attlist &=

-   attribute class {

-     "attribute"

-     | "attvalue"

-     | "element"

-     | "endtag"

-     | "emptytag"

-     | "genentity"

-     | "numcharref"

-     | "paramentity"

-     | "pi"

-     | "xmlpi"

-     | "starttag"

-     | "sgmlcomment"

-     | "prefix"

-     | "namespace"

-     | "localname"

-   }?,

-   attribute namespace { text }?,

-   common.attrib,

-   sgmltag.role.attrib,

-   local.sgmltag.attrib

- # end of sgmltag.attlist

- 

- # end of sgmltag.module

- local.structfield.attrib = empty

- structfield.role.attrib = role.attrib

- # doc:A field in a structure (in the programming language sense).

- structfield =

-   element structfield { structfield.attlist, smallcptr.char.mix* }

- # end of structfield.element

- structfield.attlist &=

-   common.attrib, structfield.role.attrib, local.structfield.attrib

- # end of structfield.attlist

- 

- # end of structfield.module

- local.structname.attrib = empty

- structname.role.attrib = role.attrib

- # doc:The name of a structure (in the programming language sense).

- structname =

-   element structname { structname.attlist, smallcptr.char.mix* }

- # end of structname.element

- structname.attlist &=

-   common.attrib, structname.role.attrib, local.structname.attrib

- # end of structname.attlist

- 

- # end of structname.module

- local.symbol.attrib = empty

- symbol.role.attrib = role.attrib

- # doc:A name that is replaced by a value before processing.

- symbol = element symbol { symbol.attlist, smallcptr.char.mix* }

- # end of symbol.element

- 

- # Class: Type of symbol; no default

- symbol.attlist &=

-   attribute class { "limit" }?,

-   common.attrib,

-   symbol.role.attrib,

-   local.symbol.attrib

- # end of symbol.attlist

- 

- # end of symbol.module

- local.systemitem.attrib = empty

- systemitem.role.attrib = role.attrib

- # doc:A system-related item or term.

- systemitem =

-   element systemitem {

-     systemitem.attlist, (cptr.char.mix | acronym | co)*

-   }

- # end of systemitem.element

- 

- # Class: Type of system item the element names; no default

- systemitem.attlist &=

-   attribute class {

-     "constant"

-     | "daemon"

-     | "domainname"

-     | "etheraddress"

-     | "event"

-     | "eventhandler"

-     | "filesystem"

-     | "fqdomainname"

-     | "groupname"

-     | "ipaddress"

-     | "library"

-     | "macro"

-     | "netmask"

-     | "newsgroup"

-     | "osname"

-     | "protocol"

-     | "resource"

-     | "systemname"

-     | "username"

-     | "process"

-     | "server"

-     | "service"

-   }?,

-   moreinfo.attrib,

-   common.attrib,

-   systemitem.role.attrib,

-   local.systemitem.attrib

- # end of systemitem.attlist

- 

- # end of systemitem.module

- local.uri.attrib = empty

- uri.role.attrib = role.attrib

- # doc:A Uniform Resource Identifier.

- uri = element uri { uri.attlist, smallcptr.char.mix* }

- # end of uri.element

- 

- # Type: Type of URI; no default

- uri.attlist &=

-   attribute type { text }?,

-   common.attrib,

-   uri.role.attrib,

-   local.uri.attrib

- # end of uri.attlist

- 

- # end of uri.module

- local.token.attrib = empty

- token.role.attrib = role.attrib

- # doc:A unit of information.

- \token = element token { token.attlist, smallcptr.char.mix* }

- # end of token.element

- token.attlist &= common.attrib, token.role.attrib, local.token.attrib

- # end of token.attlist

- 

- # end of token.module

- local.type.attrib = empty

- type.role.attrib = role.attrib

- # doc:The classification of a value.

- type = element type { type.attlist, smallcptr.char.mix* }

- # end of type.element

- type.attlist &= common.attrib, type.role.attrib, local.type.attrib

- # end of type.attlist

- 

- # end of type.module

- local.userinput.attrib = empty

- userinput.role.attrib = role.attrib

- # doc:Data entered by the user.

- userinput =

-   element userinput { userinput.attlist, (cptr.char.mix | co)* }

- # end of userinput.element

- userinput.attlist &=

-   moreinfo.attrib,

-   common.attrib,

-   userinput.role.attrib,

-   local.userinput.attrib

- # end of userinput.attlist

- 

- # end of userinput.module

- local.termdef.attrib = empty

- termdef.role.attrib = role.attrib

- # doc:An inline definition of a term.

- termdef = element termdef { termdef.attlist, para.char.mix* }

- # end of termdef.element

- termdef.attlist &=

-   common.attrib, termdef.role.attrib, local.termdef.attrib

- # end of termdef.attlist

- 

- # end of termdef.module

- 

- # General words and phrases ............................................

- local.abbrev.attrib = empty

- abbrev.role.attrib = role.attrib

- # doc:An abbreviation, especially one followed by a period.

- abbrev = element abbrev { abbrev.attlist, word.char.mix* }

- # end of abbrev.element

- abbrev.attlist &= common.attrib, abbrev.role.attrib, local.abbrev.attrib

- # end of abbrev.attlist

- 

- # end of abbrev.module

- local.acronym.attrib = empty

- acronym.role.attrib = role.attrib

- # doc:An often pronounceable word made from the initial (or selected) letters of a name or phrase.

- acronym = element acronym { acronym.attlist, word.char.mix* }

- # end of acronym.element

- acronym.attlist &=

-   common.attrib, acronym.role.attrib, local.acronym.attrib

- # end of acronym.attlist

- 

- # end of acronym.module

- local.citation.attrib = empty

- citation.role.attrib = role.attrib

- # doc:An inline bibliographic reference to another published work.

- citation = element citation { citation.attlist, para.char.mix* }

- # end of citation.element

- citation.attlist &=

-   common.attrib, citation.role.attrib, local.citation.attrib

- # end of citation.attlist

- 

- # end of citation.module

- local.citerefentry.attrib = empty

- citerefentry.role.attrib = role.attrib

- # doc:A citation to a reference page.

- citerefentry =

-   element citerefentry {

-     citerefentry.attlist, refentrytitle, manvolnum?

-   }

- # end of citerefentry.element

- citerefentry.attlist &=

-   common.attrib, citerefentry.role.attrib, local.citerefentry.attrib

- # end of citerefentry.attlist

- 

- # end of citerefentry.module

- local.refentrytitle.attrib = empty

- refentrytitle.role.attrib = role.attrib

- # doc:The title of a reference page.

- refentrytitle =

-   element refentrytitle { refentrytitle.attlist, para.char.mix* }

- # end of refentrytitle.element

- refentrytitle.attlist &=

-   common.attrib, refentrytitle.role.attrib, local.refentrytitle.attrib

- # end of refentrytitle.attlist

- 

- # end of refentrytitle.module

- local.manvolnum.attrib = empty

- namvolnum.role.attrib = role.attrib

- # doc:A reference volume number.

- manvolnum = element manvolnum { manvolnum.attlist, word.char.mix* }

- # end of manvolnum.element

- manvolnum.attlist &=

-   common.attrib, namvolnum.role.attrib, local.manvolnum.attrib

- # end of manvolnum.attlist

- 

- # end of manvolnum.module

- local.citetitle.attrib = empty

- citetitle.role.attrib = role.attrib

- # doc:The title of a cited work.

- citetitle = element citetitle { citetitle.attlist, para.char.mix* }

- # end of citetitle.element

- 

- # Pubwork: Genre of published work cited; no default

- citetitle.attlist &=

-   attribute pubwork {

-     "article"

-     | "book"

-     | "chapter"

-     | "part"

-     | "refentry"

-     | "section"

-     | "journal"

-     | "series"

-     | "set"

-     | "manuscript"

-     | "cdrom"

-     | "dvd"

-     | "wiki"

-     | "gopher"

-     | "bbs"

-     | "emailmessage"

-     | "webpage"

-     | "newsposting"

-   }?,

-   common.attrib,

-   citetitle.role.attrib,

-   local.citetitle.attrib

- # end of citetitle.attlist

- 

- # end of citetitle.module

- local.emphasis.attrib = empty

- emphasis.role.attrib = role.attrib

- # doc:Emphasized text.

- emphasis = element emphasis { emphasis.attlist, para.char.mix* }

- # end of emphasis.element

- emphasis.attlist &=

-   common.attrib, emphasis.role.attrib, local.emphasis.attrib

- # end of emphasis.attlist

- 

- # end of emphasis.module

- local.foreignphrase.attrib = empty

- foreignphrase.role.attrib = role.attrib

- # doc:A word or phrase in a language other than the primary language of the document.

- foreignphrase =

-   element foreignphrase { foreignphrase.attlist, para.char.mix* }

- # end of foreignphrase.element

- foreignphrase.attlist &=

-   common.attrib, foreignphrase.role.attrib, local.foreignphrase.attrib

- # end of foreignphrase.attlist

- 

- # end of foreignphrase.module

- local.glossterm.attrib = empty

- glossterm.role.attrib = role.attrib

- # doc:A glossary term.

- glossterm = element glossterm { glossterm.attlist, para.char.mix* }

- # end of glossterm.element

- 

- # to GlossEntry if Glossterm used in text

- 

- # BaseForm: Provides the form of GlossTerm to be used

- # for indexing

- glossterm.attlist &=

-   attribute baseform { text }?,

-   linkend.attrib,

-   common.attrib,

-   glossterm.role.attrib,

-   local.glossterm.attrib

- # end of glossterm.attlist

- 

- # end of glossterm.module

- local.firstterm.attrib = empty

- firstterm.role.attrib = role.attrib

- # doc:The first occurrence of a term.

- firstterm = element firstterm { firstterm.attlist, para.char.mix* }

- # end of firstterm.element

- 

- # to GlossEntry or other explanation

- firstterm.attlist &=

-   attribute baseform { text }?,

-   linkend.attrib,

-   common.attrib,

-   firstterm.role.attrib,

-   local.firstterm.attrib

- # end of firstterm.attlist

- 

- # end of firstterm.module

- local.phrase.attrib = empty

- phrase.role.attrib = role.attrib

- # doc:A span of text.

- phrase = element phrase { phrase.attlist, para.char.mix* }

- # end of phrase.element

- phrase.attlist &= common.attrib, phrase.role.attrib, local.phrase.attrib

- # end of phrase.attlist

- 

- # end of phrase.module

- local.quote.attrib = empty

- quote.role.attrib = role.attrib

- # doc:An inline quotation.

- quote = element quote { quote.attlist, para.char.mix* }

- # end of quote.element

- quote.attlist &= common.attrib, quote.role.attrib, local.quote.attrib

- # end of quote.attlist

- 

- # end of quote.module

- local.ssscript.attrib = empty

- ssscript.role.attrib = role.attrib

- # doc:A subscript (as in H{^2}O, the molecular formula for water).

- subscript =

-   element subscript {

-     subscript.attlist,

-     (text

-      | link.char.class

-      | emphasis

-      | replaceable

-      | symbol

-      | inlinegraphic

-      | inlinemediaobject

-      | base.char.class

-      | other.char.class)*

-   }

- # end of subscript.element

- subscript.attlist &=

-   common.attrib, ssscript.role.attrib, local.ssscript.attrib

- # end of subscript.attlist

- 

- # doc:A superscript (as in x^2, the mathematical notation for x multiplied by itself).

- superscript =

-   element superscript {

-     superscript.attlist,

-     (text

-      | link.char.class

-      | emphasis

-      | replaceable

-      | symbol

-      | inlinegraphic

-      | inlinemediaobject

-      | base.char.class

-      | other.char.class)*

-   }

- # end of superscript.element

- superscript.attlist &=

-   common.attrib, ssscript.role.attrib, local.ssscript.attrib

- # end of superscript.attlist

- 

- # end of ssscript.module

- local.trademark.attrib = empty

- trademark.role.attrib = role.attrib

- # doc:A trademark.

- trademark =

-   element trademark {

-     trademark.attlist,

-     (text

-      | link.char.class

-      | tech.char.class

-      | base.char.class

-      | other.char.class

-      | inlinegraphic

-      | inlinemediaobject

-      | emphasis)*

-   }

- # end of trademark.element

- 

- # Class: More precisely identifies the item the element names

- trademark.attlist &=

-   [ a:defaultValue = "trade" ]

-   attribute class { "service" | "trade" | "registered" | "copyright" }?,

-   common.attrib,

-   trademark.role.attrib,

-   local.trademark.attrib

- # end of trademark.attlist

- 

- # end of trademark.module

- local.wordasword.attrib = empty

- wordasword.role.attrib = role.attrib

- # doc:A word meant specifically as a word and not representing anything else.

- wordasword = element wordasword { wordasword.attlist, word.char.mix* }

- # end of wordasword.element

- wordasword.attlist &=

-   common.attrib, wordasword.role.attrib, local.wordasword.attrib

- # end of wordasword.attlist

- 

- # end of wordasword.module

- 

- # Links and cross-references ...........................................

- local.link.attrib = empty

- link.role.attrib = role.attrib

- # doc:A hypertext link.

- link = element link { link.attlist, para.char.mix* }

- # end of link.element

- 

- # Endterm: ID of element containing text that is to be

- # fetched from elsewhere in the document to appear as

- # the content of this element

- 

- # to linked-to object

- 

- # Type: Freely assignable parameter

- link.attlist &=

-   attribute endterm { xsd:IDREF }?,

-   attribute xrefstyle { text }?,

-   attribute type { text }?,

-   linkendreq.attrib,

-   common.attrib,

-   link.role.attrib,

-   local.link.attrib

- # end of link.attlist

- 

- # end of link.module

- local.olink.attrib = empty

- olink.role.attrib = role.attrib

- # doc:A link that addresses its target indirectly, through an entity.

- olink = element olink { olink.attlist, para.char.mix* }

- # end of olink.element

- 

- # TargetDocEnt: Name of an entity to be the target of the link

- 

- # LinkMode: ID of a ModeSpec containing instructions for

- # operating on the entity named by TargetDocEnt

- 

- # LocalInfo: Information that may be passed to ModeSpec

- 

- # Type: Freely assignable parameter

- olink.attlist &=

-   attribute targetdocent { xsd:ENTITY }?,

-   attribute linkmode { xsd:IDREF }?,

-   attribute localinfo { text }?,

-   attribute type { text }?,

-   attribute targetdoc { text }?,

-   attribute targetptr { text }?,

-   attribute xrefstyle { text }?,

-   common.attrib,

-   olink.role.attrib,

-   local.olink.attrib

- # end of olink.attlist

- 

- # end of olink.module

- local.ulink.attrib = empty

- ulink.role.attrib = role.attrib

- # doc:A link that addresses its target by means of a URL (Uniform Resource Locator).

- ulink = element ulink { ulink.attlist, para.char.mix* }

- # end of ulink.element

- 

- # URL: uniform resource locator; the target of the ULink

- 

- # Type: Freely assignable parameter

- ulink.attlist &=

-   attribute url { text },

-   attribute type { text }?,

-   attribute xrefstyle { text }?,

-   common.attrib,

-   ulink.role.attrib,

-   local.ulink.attrib

- # end of ulink.attlist

- 

- # end of ulink.module

- local.footnoteref.attrib = empty

- footnoteref.role.attrib = role.attrib

- # doc:A cross reference to a footnote (a footnote mark).

- footnoteref = element footnoteref { footnoteref.attlist, empty }

- # end of footnoteref.element

- 

- # to footnote content supplied elsewhere

- footnoteref.attlist &=

-   linkendreq.attrib,

-   label.attrib,

-   common.attrib,

-   footnoteref.role.attrib,

-   local.footnoteref.attrib

- # end of footnoteref.attlist

- 

- # end of footnoteref.module

- local.xref.attrib = empty

- xref.role.attrib = role.attrib

- # doc:A cross reference to another part of the document.

- xref = element xref { xref.attlist, empty }

- # end of xref.element

- 

- # Endterm: ID of element containing text that is to be

- # fetched from elsewhere in the document to appear as

- # the content of this element

- 

- # to linked-to object

- xref.attlist &=

-   attribute endterm { xsd:IDREF }?,

-   attribute xrefstyle { text }?,

-   common.attrib,

-   linkendreq.attrib,

-   xref.role.attrib,

-   local.xref.attrib

- # end of xref.attlist

- 

- # end of xref.module

- local.biblioref.attrib = empty

- biblioref.role.attrib = role.attrib

- # doc:A cross reference to a bibliographic entry.

- biblioref = element biblioref { biblioref.attlist, empty }

- # end of biblioref.element

- biblioref.attlist &=

-   attribute endterm { xsd:IDREF }?,

-   attribute xrefstyle { text }?,

-   attribute units { text }?,

-   attribute begin { text }?,

-   attribute end { text }?,

-   common.attrib,

-   linkendreq.attrib,

-   biblioref.role.attrib,

-   local.biblioref.attrib

- # end of biblioref.attlist

- 

- # end of biblioref.module

- 

- # Ubiquitous elements ..................................................

- local.anchor.attrib = empty

- anchor.role.attrib = role.attrib

- # doc:A spot in the document.

- anchor = element anchor { anchor.attlist, empty }

- # end of anchor.element

- 

- # required

- 

- # replaces Lang

- anchor.attlist &=

-   idreq.attrib,

-   pagenum.attrib,

-   remap.attrib,

-   xreflabel.attrib,

-   revisionflag.attrib,

-   effectivity.attrib,

-   anchor.role.attrib,

-   local.anchor.attrib

- # end of anchor.attlist

- 

- # end of anchor.module

- local.beginpage.attrib = empty

- beginpage.role.attrib = role.attrib

- # doc:The location of a page break in a print version of the document.

- beginpage = element beginpage { beginpage.attlist, empty }

- # end of beginpage.element

- 

- # PageNum: Number of page that begins at this point

- beginpage.attlist &=

-   pagenum.attrib,

-   common.attrib,

-   beginpage.role.attrib,

-   local.beginpage.attrib

- # end of beginpage.attlist

- 

- # end of beginpage.module

- 

- # IndexTerms appear in the text flow for generating or linking an

- # index.

- local.indexterm.attrib = empty

- indexterm.role.attrib = role.attrib

- # doc:A wrapper for terms to be indexed.

- indexterm =

-   element indexterm {

-     indexterm.attlist,

-     primary?,

-     ((secondary,

-       ((tertiary, (see | seealso+)?)

-        | see

-        | seealso+)?)

-      | see

-      | seealso+)?

-   }

- # end of indexterm.element

- 

- # Scope: Indicates which generated indices the IndexTerm

- # should appear in: Global (whole document set), Local (this

- # document only), or All (both)

- 

- # Significance: Whether this IndexTerm is the most pertinent

- # of its series (Preferred) or not (Normal, the default)

- 

- # Class: Indicates type of IndexTerm; default is Singular,

- # or EndOfRange if StartRef is supplied; StartOfRange value

- # must be supplied explicitly on starts of ranges

- 

- # StartRef: ID of the IndexTerm that starts the indexing

- # range ended by this IndexTerm

- 

- # Zone: IDs of the elements to which the IndexTerm applies,

- # and indicates that the IndexTerm applies to those entire

- # elements rather than the point at which the IndexTerm

- # occurs

- indexterm.attlist &=

-   pagenum.attrib,

-   attribute scope { "all" | "global" | "local" }?,

-   [ a:defaultValue = "normal" ]

-   attribute significance { "preferred" | "normal" }?,

-   attribute class { "singular" | "startofrange" | "endofrange" }?,

-   attribute startref { xsd:IDREF }?,

-   attribute zone { xsd:IDREFS }?,

-   attribute type { text }?,

-   common.attrib,

-   indexterm.role.attrib,

-   local.indexterm.attrib

- # end of indexterm.attlist

- 

- # end of indexterm.module

- local.primsecter.attrib = empty

- primsecter.role.attrib = role.attrib

- # doc:The primary word or phrase under which an index term should be sorted.

- primary = element primary { primary.attlist, ndxterm.char.mix* }

- # end of primary.element

- 

- # SortAs: Alternate sort string for index sorting, e.g.,

- # "fourteen" for an element containing "14"

- primary.attlist &=

-   attribute sortas { text }?,

-   common.attrib,

-   primsecter.role.attrib,

-   local.primsecter.attrib

- # end of primary.attlist

- 

- # doc:A secondary word or phrase in an index term.

- secondary = element secondary { secondary.attlist, ndxterm.char.mix* }

- # end of secondary.element

- 

- # SortAs: Alternate sort string for index sorting, e.g.,

- # "fourteen" for an element containing "14"

- secondary.attlist &=

-   attribute sortas { text }?,

-   common.attrib,

-   primsecter.role.attrib,

-   local.primsecter.attrib

- # end of secondary.attlist

- 

- # doc:A tertiary word or phrase in an index term.

- tertiary = element tertiary { tertiary.attlist, ndxterm.char.mix* }

- # end of tertiary.element

- 

- # SortAs: Alternate sort string for index sorting, e.g.,

- # "fourteen" for an element containing "14"

- tertiary.attlist &=

-   attribute sortas { text }?,

-   common.attrib,

-   primsecter.role.attrib,

-   local.primsecter.attrib

- # end of tertiary.attlist

- 

- # end of primsecter.module

- local.seeseealso.attrib = empty

- seeseealso.role.attrib = role.attrib

- # doc:Part of an index term directing the reader instead to another entry in the index.

- see = element see { see.attlist, ndxterm.char.mix* }

- # end of see.element

- see.attlist &=

-   common.attrib, seeseealso.role.attrib, local.seeseealso.attrib

- # end of see.attlist

- 

- # doc:Part of an index term directing the reader also to another entry in the index.

- seealso = element seealso { seealso.attlist, ndxterm.char.mix* }

- # end of seealso.element

- seealso.attlist &=

-   common.attrib, seeseealso.role.attrib, local.seeseealso.attrib

- # end of seealso.attlist

- 

- # end of seeseealso.module

- 

- # end of indexterm.content.module

- 

- # End of DocBook XML information pool module V4.5 ......................

- 

- # ......................................................................

docbook-schema/docbook.rnc
file removed
-499
@@ -1,499 +0,0 @@

- # ......................................................................

- 

- # DocBook XML DTD V4.5 .................................................

- 

- # File docbookx.dtd ....................................................

- 

- # Copyright 1992-2006 HaL Computer Systems, Inc.,

- # O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software

- # Corporation, Norman Walsh, Sun Microsystems, Inc., and the

- # Organization for the Advancement of Structured Information

- # Standards (OASIS).

- # 

- # See also http://docbook.org/specs/

- # 

- # $Id: docbookx.dtd 6340 2006-10-03 13:23:24Z nwalsh $

- # 

- # Permission to use, copy, modify and distribute the DocBook XML DTD

- # and its accompanying documentation for any purpose and without fee

- # is hereby granted in perpetuity, provided that the above copyright

- # notice and this paragraph appear in all copies.  The copyright

- # holders make no representation about the suitability of the DTD for

- # any purpose.  It is provided "as is" without expressed or implied

- # warranty.

- # 

- # If you modify the DocBook DTD in any way, except for declaring and

- # referencing additional sets of general entities and declaring

- # additional notations, label your DTD as a variant of DocBook.  See

- # the maintenance documentation for more information.

- # 

- # Please direct all questions, bug reports, or suggestions for

- # changes to the docbook@lists.oasis-open.org mailing list. For more

- # information, see http://www.oasis-open.org/docbook/.

- 

- # ......................................................................

- 

- # This is the driver file for V4.5 of the DocBook DTD.

- # Please use the following formal public identifier to identify it:

- # 

- # "-//OASIS//DTD DocBook XML V4.5//EN"

- # 

- # For example, if your document's top-level element is Book, and

- # you are using DocBook directly, use the FPI in the DOCTYPE

- # declaration:

- # 

- # <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"

- #                "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"

- #                [...]>

- # 

- # Or, if you have a higher-level driver file that customizes DocBook,

- # use the FPI in the parameter entity declaration:

- # 

- # <!ENTITY % DocBookDTD PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"

- #            "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

- # %DocBookDTD;

- # 

- # See the documentation for detailed information on the parameter

- # entity and module scheme used in DocBook, customizing DocBook and

- # planning for interchange, and changes made since the last release

- # of DocBook.

- 

- # ......................................................................

- 

- # Enable SGML features .................................................

- 

- # ......................................................................

- 

- # Notation declarations ................................................

- 

- include "dbnotnx.rnc"

- # ......................................................................

- 

- # ISO character entity sets ............................................

- 

- # euro sign, U+20AC NEW

- 

- # ......................................................................

- 

- # DTD modules ..........................................................

- 

- # Information pool ..............

- include "dbpoolx.rnc"

- # Redeclaration placeholder .....

- 

- # Document hierarchy ............

- include "dbhierx.rnc"

- start =

-   articleinfo

-   | honorific

-   | legalnotice

-   | procedure

-   | simplelist

-   | keycode

-   | refsynopsisdiv

-   | article

-   | phrase

-   | destructorsynopsis

-   | itemizedlist

-   | audioobject

-   | link

-   | sect1info

-   | xref

-   | glossaryinfo

-   | varname

-   | keywordset

-   | informalequation

-   | toc

-   | pagenums

-   | lot

-   | shortcut

-   | glosslist

-   | option

-   | bibliosource

-   | variablelist

-   | filename

-   | pob

-   | colgroup

-   | foreignphrase

-   | group

-   | substeps

-   | conftitle

-   | textobject

-   | menuchoice

-   | colspec

-   | contractsponsor

-   | tocback

-   | contractnum

-   | constant

-   | dedication

-   | inlineequation

-   | bibliographyinfo

-   | country

-   | glossseealso

-   | bridgehead

-   | mousebutton

-   | surname

-   | stepalternatives

-   | tertiaryie

-   | mediaobject

-   | msgentry

-   | fax

-   | initializer

-   | table

-   | task

-   | setinfo

-   | videodata

-   | bibliodiv

-   | issuenum

-   | phone

-   | state

-   | refsynopsisdivinfo

-   | member

-   | glossentry

-   | term

-   | msgtext

-   | tr

-   | errortype

-   | confdates

-   | inlinegraphic

-   | th

-   | segmentedlist

-   | remark

-   | preface

-   | structname

-   | publisher

-   | td

-   | oointerface

-   | refsection

-   | type

-   | taskrelated

-   | msgrel

-   | artpagenums

-   | bibliomixed

-   | revnumber

-   | firstterm

-   | seeie

-   | spanspec

-   | toclevel5

-   | trademark

-   | toclevel4

-   | toclevel3

-   | toclevel2

-   | indexentry

-   | toclevel1

-   | colophon

-   | methodparam

-   | sidebarinfo

-   | productnumber

-   | funcprototype

-   | inlinemediaobject

-   | refclass

-   | lotentry

-   | paramdef

-   | classsynopsisinfo

-   | qandaset

-   | footnote

-   | msglevel

-   | keysym

-   | citation

-   | simplemsgentry

-   | othercredit

-   | subjectset

-   | keycap

-   | orderedlist

-   | refmiscinfo

-   | blockinfo

-   | programlistingco

-   | abbrev

-   | sidebar

-   | informalfigure

-   | tip

-   | primaryie

-   | appendixinfo

-   | partintro

-   | glossdiv

-   | confgroup

-   | segtitle

-   | taskprerequisites

-   | street

-   | tbody

-   | caption

-   | markup

-   | setindex

-   | msgsub

-   | subscript

-   | orgname

-   | fieldsynopsis

-   | refname

-   | void

-   | sect5

-   | sect4

-   | sect3

-   | chapter

-   | sect2

-   | sect1

-   | modifier

-   | col

-   | orgdiv

-   | city

-   | bibliolist

-   | funcparams

-   | application

-   | \token

-   | imageobject

-   | literal

-   | funcsynopsis

-   | olink

-   | package

-   | collab

-   | seealsoie

-   | primary

-   | glossterm

-   | termdef

-   | area

-   | ackno

-   | function

-   | collabname

-   | lineannotation

-   | guisubmenu

-   | msgexplan

-   | errorname

-   | property

-   | synopfragmentref

-   | refentryinfo

-   | entry

-   | manvolnum

-   | synopsis

-   | emphasis

-   | appendix

-   | bookinfo

-   | contrib

-   | otheraddr

-   | copyright

-   | methodname

-   | email

-   | ooclass

-   | videoobject

-   | abstract

-   | firstname

-   | revremark

-   | glossdef

-   | guibutton

-   | informalexample

-   | screen

-   | errorcode

-   | command

-   | seriesvolnums

-   | refpurpose

-   | parameter

-   | equation

-   | tfoot

-   | code

-   | jobtitle

-   | sgmltag

-   | screenco

-   | holder

-   | isbn

-   | corpcredit

-   | biblioset

-   | part

-   | symbol

-   | row

-   | bibliomisc

-   | imagedata

-   | secondary

-   | classname

-   | callout

-   | screenshot

-   | bibliomset

-   | indexterm

-   | refsect3

-   | tocchap

-   | para

-   | refsect2

-   | refsect1

-   | date

-   | refdescriptor

-   | wordasword

-   | epigraph

-   | audiodata

-   | hardware

-   | confsponsor

-   | authorgroup

-   | warning

-   | authorinitials

-   | medialabel

-   | varlistentry

-   | authorblurb

-   | itermset

-   | refsect3info

-   | informaltable

-   | guimenuitem

-   | postcode

-   | subjectterm

-   | refnamediv

-   | note

-   | figure

-   | envar

-   | listitem

-   | methodsynopsis

-   | affiliation

-   | funcsynopsisinfo

-   | structfield

-   | blockquote

-   | keyword

-   | chapterinfo

-   | tertiary

-   | year

-   | subtitle

-   | personblurb

-   | refentry

-   | citebiblioid

-   | seglistitem

-   | bibliography

-   | msg

-   | constructorsynopsis

-   | refsect2info

-   | volumenum

-   | database

-   | funcdef

-   | uri

-   | graphicco

-   | biblioid

-   | msgmain

-   | printhistory

-   | glosssee

-   | beginpage

-   | glossary

-   | set

-   | highlights

-   | objectinfo

-   | tocpart

-   | guiicon

-   | revhistory

-   | seg

-   | see

-   | msgorig

-   | areaspec

-   | partinfo

-   | index

-   | sectioninfo

-   | refsectioninfo

-   | optional

-   | confnum

-   | replaceable

-   | refsect1info

-   | corpauthor

-   | step

-   | anchor

-   | arg

-   | mathphrase

-   | setindexinfo

-   | keycombo

-   | address

-   | cmdsynopsis

-   | computeroutput

-   | literallayout

-   | qandaentry

-   | sect5info

-   | bibliocoverage

-   | coref

-   | editor

-   | superscript

-   | personname

-   | pubsnumber

-   | graphic

-   | simplesect

-   | accel

-   | secondaryie

-   | biblioref

-   | publishername

-   | bibliorelation

-   | prefaceinfo

-   | revision

-   | screeninfo

-   | sbr

-   | example

-   | citetitle

-   | issn

-   | invpartnumber

-   | indexdiv

-   | sect4info

-   | corpname

-   | lineage

-   | ooexception

-   | reference

-   | revdescription

-   | title

-   | edition

-   | co

-   | msgaud

-   | guimenu

-   | shortaffil

-   | titleabbrev

-   | msginfo

-   | refmeta

-   | qandadiv

-   | mediaobjectco

-   | seealso

-   | exceptionname

-   | answer

-   | programlisting

-   | tgroup

-   | refentrytitle

-   | book

-   | errortext

-   | varargs

-   | sect3info

-   | citerefentry

-   | tasksummary

-   | quote

-   | othername

-   | prompt

-   | entrytbl

-   | interfacename

-   | acronym

-   | modespec

-   | msgset

-   | thead

-   | textdata

-   | userinput

-   | attribution

-   | footnoteref

-   | action

-   | tocentry

-   | tocfront

-   | author

-   | imageobjectco

-   | alt

-   | question

-   | ulink

-   | subject

-   | pubdate

-   | returnvalue

-   | label

-   | caution

-   | section

-   | systemitem

-   | referenceinfo

-   | sect2info

-   | calloutlist

-   | classsynopsis

-   | productname

-   | simpara

-   | synopfragment

-   | important

-   | interface

-   | releaseinfo

-   | formalpara

-   | areaset

-   | biblioentry

-   | indexinfo

-   | guilabel

- # ......................................................................

- 

- # Other general entities ...............................................

- 

- # End of DocBook XML DTD V4.5 ..........................................

- 

- # ......................................................................

docbook-schema/htmltblx.rnc
file removed
-225
@@ -1,225 +0,0 @@

- # ......................................................................

- 

- # DocBook XML HTML Table Module V4.5 ...................................

- 

- # File htmltblx.mod ....................................................

- 

- # Copyright 2003-2006 ArborText, Inc., Norman Walsh, Sun Microsystems,

- # Inc., and the Organization for the Advancement of Structured Information

- # Standards (OASIS).

- # 

- # $Id: htmltblx.mod 6340 2006-10-03 13:23:24Z nwalsh $

- # 

- # Permission to use, copy, modify and distribute the DocBook XML DTD

- # and its accompanying documentation for any purpose and without fee

- # is hereby granted in perpetuity, provided that the above copyright

- # notice and this paragraph appear in all copies.  The copyright

- # holders make no representation about the suitability of the DTD for

- # any purpose.  It is provided "as is" without expressed or implied

- # warranty.

- # 

- # If you modify the DocBook XML DTD in any way, except for declaring and

- # referencing additional sets of general entities and declaring

- # additional notations, label your DTD as a variant of DocBook.  See

- # the maintenance documentation for more information.

- # 

- # Please direct all questions, bug reports, or suggestions for

- # changes to the docbook@lists.oasis-open.org mailing list. For more

- # information, see http://www.oasis-open.org/docbook/.

- 

- # ......................................................................

- 

- # This module contains the definitions for elements that are

- # isomorphic to the HTML elements. One could argue we should

- # instead have based ourselves on the XHTML Table Module, but the

- # HTML one is more like what browsers are likely to accept today

- # and users are likely to use.

- # 

- # This module has been developed for use with the DocBook V4.5

- # "union table model" in which elements and attlists common to both

- # models are defined (as the union) in the CALS table module by

- # setting various parameter entities appropriately in this file.

- # 

- # In DTD driver files referring to this module, please use an entity

- # declaration that uses the public identifier shown below:

- # 

- # <!ENTITY % htmltbl PUBLIC

- # "-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN"

- # "htmltblx.mod">

- # %htmltbl;

- # 

- # See the documentation for detailed information on the parameter

- # entity and module scheme used in DocBook, customizing DocBook and

- # planning for interchange, and changes made since the last release

- # of DocBook.

- 

- # ======================= XHTML Tables =======================================

- 

- namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"

- 

- html.coreattrs =

-   common.attrib,

-   attribute class { text }?,

-   attribute style { text }?,

-   attribute title { text }?

- # Does not contain lang or dir because they are in %common.attribs

- i18n = attribute xml:lang { xsd:NMTOKEN }?

- events =

-   attribute onclick { text }?,

-   attribute ondblclick { text }?,

-   attribute onmousedown { text }?,

-   attribute onmouseup { text }?,

-   attribute onmouseover { text }?,

-   attribute onmousemove { text }?,

-   attribute onmouseout { text }?,

-   attribute onkeypress { text }?,

-   attribute onkeydown { text }?,

-   attribute onkeyup { text }?

- attrs = html.coreattrs, i18n, events

- cellhalign =

-   attribute align { "left" | "center" | "right" | "justify" | "char" }?,

-   attribute char { text }?,

-   attribute charoff { text }?

- cellvalign =

-   attribute valign { "top" | "middle" | "bottom" | "baseline" }?

- # doc:A group of columns in an HTML table.

- colgroup = element colgroup { colgroup.attlist, col* }

- # doc:Specifications for a column in an HTML table.

- col = element col { col.attlist, empty }

- # doc:A row in an HTML table.

- tr = element tr { tr.attlist, (th | td)+ }

- # doc:A table header entry in an HTML table.

- th =

-   element th {

-     th.attlist, (para.char.mix | tabentry.mix | table | informaltable)*

-   }

- # doc:A table ntry in an HTML table.

- td =

-   element td {

-     td.attlist, (para.char.mix | tabentry.mix | table | informaltable)*

-   }

- colgroup.attlist &=

-   attrs,

-   [ a:defaultValue = "1" ] attribute span { text }?,

-   attribute width { text }?,

-   cellhalign,

-   cellvalign

- col.attlist &=

-   attrs,

-   [ a:defaultValue = "1" ] attribute span { text }?,

-   attribute width { text }?,

-   cellhalign,

-   cellvalign

- tr.attlist &=

-   attrs,

-   cellhalign,

-   cellvalign,

-   attribute bgcolor { text }?

- th.attlist &=

-   attrs,

-   attribute abbr { text }?,

-   attribute axis { text }?,

-   attribute headers { xsd:IDREFS }?,

-   attribute scope { "row" | "col" | "rowgroup" | "colgroup" }?,

-   [ a:defaultValue = "1" ] attribute rowspan { text }?,

-   [ a:defaultValue = "1" ] attribute colspan { text }?,

-   cellhalign,

-   cellvalign,

-   attribute nowrap { "nowrap" }?,

-   attribute bgcolor { text }?,

-   attribute width { text }?,

-   attribute height { text }?

- td.attlist &=

-   attrs,

-   attribute abbr { text }?,

-   attribute axis { text }?,

-   attribute headers { xsd:IDREFS }?,

-   attribute scope { "row" | "col" | "rowgroup" | "colgroup" }?,

-   [ a:defaultValue = "1" ] attribute rowspan { text }?,

-   [ a:defaultValue = "1" ] attribute colspan { text }?,

-   cellhalign,

-   cellvalign,

-   attribute nowrap { "nowrap" }?,

-   attribute bgcolor { text }?,

-   attribute width { text }?,

-   attribute height { text }?

- # ======================================================

- 

- # Set up to read in the CALS model configured to

- # merge with the XHTML table model

- 

- # ======================================================

- tables.role.attrib = role.attrib

- # Add label and role attributes to table and informaltable

- bodyatt =

-   attribute floatstyle { text }?,

-   attribute rowheader { "firstcol" | "norowheader" }?,

-   label.attrib

- # Add common attributes to Table, TGroup, TBody, THead, TFoot, Row, 

- # EntryTbl, and Entry (and InformalTable element).

- secur =

-   common.attrib,

-   attribute class { text }?,

-   attribute style { text }?,

-   attribute title { text }?,

-   i18n,

-   events,

-   tables.role.attrib

- common.table.attribs = bodyatt, secur

- # Content model for Table (that also allows HTML tables)

- tbl.table.mdl =

-   (blockinfo?,

-    formalobject.title.content,

-    ndxterm.class*,

-    textobject*,

-    (graphic+ | mediaobject+ | tgroup+))

-   | (caption, (col* | colgroup*), thead?, tfoot?, (tbody+ | tr+))

- informal.tbl.table.mdl =

-   (textobject*, (graphic+ | mediaobject+ | tgroup+))

-   | ((col* | colgroup*), thead?, tfoot?, (tbody+ | tr+))

- # Attributes for Table (including HTML ones)

- 

- # N.B. rules = (none | groups | rows | cols | all) but it can't be spec'd

- 

- # that way because 'all' already occurs in a different enumeration in

- 

- # CALS tables (frame).

- tbl.table.att =

-   attribute tabstyle { text }?,

-   attribute tocentry { yesorno.attvals }?,

-   attribute shortentry { yesorno.attvals }?,

-   attribute orient { "port" | "land" }?,

-   attribute pgwide { yesorno.attvals }?,

-   attribute summary { text }?,

-   attribute width { text }?,

-   attribute border { text }?,

-   attribute rules { text }?,

-   attribute cellspacing { text }?,

-   attribute cellpadding { text }?,

-   attribute align { "left" | "center" | "right" }?,

-   attribute bgcolor { text }?

- tbl.frame.attval =

-   "void"

-   | "above"

-   | "below"

-   | "hsides"

-   | "lhs"

-   | "rhs"

-   | "vsides"

-   | "box"

-   | "border"

-   | "top"

-   | "bottom"

-   | "topbot"

-   | "all"

-   | "sides"

-   | "none"

- # Allow either objects or inlines; beware of REs between elements.

- tbl.entry.mdl = para.char.mix | tabentry.mix

- # thead, tfoot, and tbody are defined in both table models,

- # so we set up parameter entities to define union models for them

- tbl.hdft.mdl = tr+ | (colspec*, row+)

- tbl.tbody.mdl = tr+ | row+

- # End of DocBook XML HTML Table Module V4.5 ............................

- 

- # ......................................................................

en-US/Author_Group.adoc
file added
+23
@@ -0,0 +1,23 @@

+ 

+ :experimental:

+ 

+ .Florian Weimer

+ 

+ *Red Hat*

+ Product Security Team

+ 

+ fweimer@redhat.com

+ 

+ .Nikos Mavrogiannopoulos

+ 

+ *Red Hat*

+ Crypto Team

+ 

+ nmav@redhat.com

+ 

+ .Robert Relyea

+ 

+ *Red Hat*

+ Crypto Team

+ 

+ rrelyea@redhat.com 

\ No newline at end of file

en-US/Author_Group.xml
file removed
-17
@@ -1,17 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- <!ENTITY % BOOK_ENTITIES SYSTEM "Defensive_Coding.ent">

- %BOOK_ENTITIES;

- ]>

- <authorgroup>

-         <author>

-                 <firstname>Florian</firstname>

-                 <surname>Weimer</surname>

-                 <affiliation>

-                         <orgname>Red Hat</orgname>

-                         <orgdiv>Product Security Team</orgdiv>

-                 </affiliation>

-                 <email>fweimer@redhat.com</email>

-         </author>

- </authorgroup>

- 

en-US/Book_Info.adoc
file added
+18
@@ -0,0 +1,18 @@

+ 

+ :experimental:

+ 

+ A Guide to Improving Software Security

+ 

+ [abstract]

+ --

+ 

+ This document provides guidelines for improving software

+ security through secure coding. It covers common

+ programming languages and libraries, and focuses on

+ concrete recommendations.

+ 

+ --

+ image:Common_Content/images/title_logo.svg[]

+ include::Common_Content/Legal_Notice.adoc[]

+ 

+ include::Author_Group.adoc[]

en-US/C-Allocators.adoc
file added
+166
@@ -0,0 +1,166 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-C-Allocators]]

+ ==== Memory Allocators

+ 

+ ===== `malloc` and Related Functions

+ 

+ The C library interfaces for memory allocation are provided by

+ `malloc`, `free` and

+ `realloc`, and the

+ `calloc` function. In addition to these

+ generic functions, there are derived functions such as

+ `strdup` which perform allocation using

+ `malloc` internally, but do not return

+ untyped heap memory (which could be used for any object).

+ 

+ The C compiler knows about these functions and can use their

+ expected behavior for optimizations. For instance, the compiler

+ assumes that an existing pointer (or a pointer derived from an

+ existing pointer by arithmetic) will not point into the memory

+ area returned by `malloc`.

+ 

+ If the allocation fails, `realloc` does not

+ free the old pointer. Therefore, the idiom `ptr =

+ realloc(ptr, size);` is wrong because the memory

+ pointed to by `ptr` leaks in case of an error.

+ 

+ [[sect-Defensive_Coding-C-Use-After-Free]]

+ ====== Use-after-free errors

+ 

+ After `free`, the pointer is invalid.

+ Further pointer dereferences are not allowed (and are usually

+ detected by [application]*valgrind*). Less obvious

+ is that any *use* of the old pointer value is

+ not allowed, either. In particular, comparisons with any other

+ pointer (or the null pointer) are undefined according to the C

+ standard.

+ 

+ The same rules apply to `realloc` if the

+ memory area cannot be enlarged in-place. For instance, the

+ compiler may assume that a comparison between the old and new

+ pointer will always return false, so it is impossible to detect

+ movement this way.

+ 

+ ====== Handling Memory Allocation Errors

+ 

+ Recovering from out-of-memory errors is often difficult or even

+ impossible. In these cases, `malloc` and

+ other allocation functions return a null pointer. Dereferencing

+ this pointer lead to a crash. Such dereferences can even be

+ exploitable for code execution if the dereference is combined

+ with an array subscript.

+ 

+ In general, if you cannot check all allocation calls and

+ handle failure, you should abort the program on allocation

+ failure, and not rely on the null pointer dereference to

+ terminate the process. See

+ <<sect-Defensive_Coding-Tasks-Serialization-Decoders>>

+ for related memory allocation concerns.

+ 

+ [[sect-Defensive_Coding-C-Allocators-alloca]]

+ ===== `alloca` and Other Forms of Stack-based Allocation

+ 

+ Allocation on the stack is risky because stack overflow checking

+ is implicit. There is a guard page at the end of the memory

+ area reserved for the stack. If the program attempts to read

+ from or write to this guard page, a `SIGSEGV`

+ signal is generated and the program typically terminates.

+ 

+ This is sufficient for detecting typical stack overflow

+ situations such as unbounded recursion, but it fails when the

+ stack grows in increments larger than the size of the guard

+ page. In this case, it is possible that the stack pointer ends

+ up pointing into a memory area which has been allocated for a

+ different purposes. Such misbehavior can be exploitable.

+ 

+ A common source for large stack growth are calls to

+ `alloca` and related functions such as

+ `strdupa`. These functions should be avoided

+ because of the lack of error checking. (They can be used safely

+ if the allocated size is less than the page size (typically,

+ 4096 bytes), but this case is relatively rare.) Additionally,

+ relying on `alloca` makes it more difficult

+ to reorganize the code because it is not allowed to use the

+ pointer after the function calling `alloca`

+ has returned, even if this function has been inlined into its

+ caller.

+ 

+ Similar concerns apply to *variable-length

+ arrays* (VLAs), a feature of the C99 standard which

+ started as a GNU extension. For large objects exceeding the

+ page size, there is no error checking, either.

+ 

+ In both cases, negative or very large sizes can trigger a

+ stack-pointer wraparound, and the stack pointer and end up

+ pointing into caller stack frames, which is fatal and can be

+ exploitable.

+ 

+ If you want to use `alloca` or VLAs for

+ performance reasons, consider using a small on-stack array (less

+ than the page size, large enough to fulfill most requests). If

+ the requested size is small enough, use the on-stack array.

+ Otherwise, call `malloc`. When exiting the

+ function, check if `malloc` had been called,

+ and free the buffer as needed.

+ 

+ [[sect-Defensive_Coding-C-Allocators-Arrays]]

+ ===== Array Allocation

+ 

+ When allocating arrays, it is important to check for overflows.

+ The `calloc` function performs such checks.

+ 

+ If `malloc` or `realloc`

+ is used, the size check must be written manually. For instance,

+ to allocate an array of `n` elements of type

+ `T`, check that the requested size is not

+ greater than `((size_t) -1) / sizeof(T)`. See

+ <<sect-Defensive_Coding-C-Arithmetic>>.

+ 

+ [[sect-Defensive_Coding-C-Allocators-Custom]]

+ ===== Custom Memory Allocators

+ 

+ Custom memory allocates come in two forms: replacements for

+ `malloc`, and completely different interfaces

+ for memory management. Both approaches can reduce the

+ effectiveness of [application]*valgrind* and similar

+ tools, and the heap corruption detection provided by GNU libc, so

+ they should be avoided.

+ 

+ Memory allocators are difficult to write and contain many

+ performance and security pitfalls.

+ 

+ * When computing array sizes or rounding up allocation

+ requests (to the next allocation granularity, or for

+ alignment purposes), checks for arithmetic overflow are

+ required.

+ 

+ * Size computations for array allocations need overflow

+ checking. See <<sect-Defensive_Coding-C-Allocators-Arrays>>.

+ 

+ * It can be difficult to beat well-tuned general-purpose

+ allocators. In micro benchmarks, pool allocators can show

+ huge wins, and size-specific pools can reduce internal

+ fragmentation. But often, utilization of individual pools

+ is poor, and external fragmentation increases the overall

+ memory usage.

+ 

+ ===== Conservative Garbage Collection

+ 

+ Garbage collection can be an alternative to explicit memory

+ management using `malloc` and

+ `free`. The Boehm-Dehmers-Weiser allocator

+ can be used from C programs, with minimal type annotations.

+ Performance is competitive with `malloc` on

+ 64-bit architectures, especially for multi-threaded programs.

+ The stop-the-world pauses may be problematic for some real-time

+ applications, though.

+ 

+ However, using a conservative garbage collector may reduce

+ opportunities for code reduce because once one library in a

+ program uses garbage collection, the whole process memory needs

+ to be subject to it, so that no pointers are missed. The

+ Boehm-Dehmers-Weiser collector also reserves certain signals for

+ internal use, so it is not fully transparent to the rest of the

+ program.

en-US/C-Allocators.xml
file removed
-209
@@ -1,209 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-C-Allocators">

-   <title>Memory allocators</title>

- 

-   <section>

-     <title><function>malloc</function> and related functions</title>

-     <para>

-       The C library interfaces for memory allocation are provided by

-       <function>malloc</function>, <function>free</function> and

-       <function>realloc</function>, and the

-       <function>calloc</function> function.  In addition to these

-       generic functions, there are derived functions such as

-       <function>strdup</function> which perform allocation using

-       <function>malloc</function> internally, but do not return

-       untyped heap memory (which could be used for any object).

-     </para>

-     <para>

-       The C compiler knows about these functions and can use their

-       expected behavior for optimizations.  For instance, the compiler

-       assumes that an existing pointer (or a pointer derived from an

-       existing pointer by arithmetic) will not point into the memory

-       area returned by <function>malloc</function>.

-     </para>

-     <para>

-       If the allocation fails, <function>realloc</function> does not

-       free the old pointer.  Therefore, the idiom <literal>ptr =

-       realloc(ptr, size);</literal> is wrong because the memory

-       pointed to by <literal>ptr</literal> leaks in case of an error.

-     </para>

-     <section id="sect-Defensive_Coding-C-Use-After-Free">

-       <title>Use-after-free errors</title>

-       <para>

- 	After <function>free</function>, the pointer is invalid.

- 	Further pointer dereferences are not allowed (and are usually

- 	detected by <application>valgrind</application>).  Less obvious

- 	is that any <emphasis>use</emphasis> of the old pointer value is

- 	not allowed, either.  In particular, comparisons with any other

- 	pointer (or the null pointer) are undefined according to the C

- 	standard.

-       </para>

-       <para>

- 	The same rules apply to <function>realloc</function> if the

- 	memory area cannot be enlarged in-place.  For instance, the

- 	compiler may assume that a comparison between the old and new

- 	pointer will always return false, so it is impossible to detect

- 	movement this way.

-       </para>

-     </section>

-     <section>

-       <title>Handling memory allocation errors</title>

-       <para>

- 	Recovering from out-of-memory errors is often difficult or even

- 	impossible.  In these cases, <function>malloc</function> and

- 	other allocation functions return a null pointer.  Dereferencing

- 	this pointer lead to a crash.  Such dereferences can even be

- 	exploitable for code execution if the dereference is combined

- 	with an array subscript.

-       </para>

-       <para>

- 	In general, if you cannot check all allocation calls and

- 	handle failure, you should abort the program on allocation

- 	failure, and not rely on the null pointer dereference to

- 	terminate the process.  See

- 	<xref

- 	linkend="sect-Defensive_Coding-Tasks-Serialization-Decoders"/>

- 	for related memory allocation concerns.

-       </para>

-     </section>

-   </section>

- 

-   <section id="sect-Defensive_Coding-C-Allocators-alloca">

-     <title><function>alloca</function> and other forms of stack-based

-     allocation</title>

-     <para>

-       Allocation on the stack is risky because stack overflow checking

-       is implicit.  There is a guard page at the end of the memory

-       area reserved for the stack.  If the program attempts to read

-       from or write to this guard page, a <literal>SIGSEGV</literal>

-       signal is generated and the program typically terminates.

-     </para>

-     <para>

-       This is sufficient for detecting typical stack overflow

-       situations such as unbounded recursion, but it fails when the

-       stack grows in increments larger than the size of the guard

-       page.  In this case, it is possible that the stack pointer ends

-       up pointing into a memory area which has been allocated for a

-       different purposes.  Such misbehavior can be exploitable.

-     </para>

-     <para>

-       A common source for large stack growth are calls to

-       <function>alloca</function> and related functions such as

-       <function>strdupa</function>.  These functions should be avoided

-       because of the lack of error checking.  (They can be used safely

-       if the allocated size is less than the page size (typically,

-       4096 bytes), but this case is relatively rare.)  Additionally,

-       relying on <function>alloca</function> makes it more difficult

-       to reorgnize the code because it is not allowed to use the

-       pointer after the function calling <function>alloca</function>

-       has returned, even if this function has been inlined into its

-       caller.

-     </para>

-     <para>

-       Similar concerns apply to <emphasis>variable-length

-       arrays</emphasis> (VLAs), a feature of the C99 standard which

-       started as a GNU extension.  For large objects exceeding the

-       page size, there is no error checking, either.

-     </para>

-     <para>

-       In both cases, negative or very large sizes can trigger a

-       stack-pointer wraparound, and the stack pointer and end up

-       pointing into caller stack frames, which is fatal and can be

-       exploitable.

-     </para>

-     <para>

-       If you want to use <function>alloca</function> or VLAs for

-       performance reasons, consider using a small on-stack array (less

-       than the page size, large enough to fulfill most requests).  If

-       the requested size is small enough, use the on-stack array.

-       Otherwise, call <function>malloc</function>.  When exiting the

-       function, check if <function>malloc</function> had been called,

-       and free the buffer as needed.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-C-Allocators-Arrays">

-     <title>Array allocation</title>

-     <para>

-       When allocating arrays, it is important to check for overflows.

-       The <function>calloc</function> function performs such checks.

-     </para>

-     <para>

-       If <function>malloc</function> or <function>realloc</function>

-       is used, the size check must be written manually.  For instance,

-       to allocate an array of <literal>n</literal> elements of type

-       <literal>T</literal>, check that the requested size is not

-       greater than <literal>((size_t) -1) / sizeof(T)</literal>.  See

-       <xref linkend="sect-Defensive_Coding-C-Arithmetic"/>.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-C-Allocators-Custom">

-     <title>Custom memory allocators</title>

-     <para>

-       Custom memory allocates come in two forms: replacements for

-       <function>malloc</function>, and completely different interfaces

-       for memory management.  Both approaches can reduce the

-       effectiveness of <application>valgrind</application> and similar

-       tools, and the heap corruption detection provided by GNU libc, so

-       they should be avoided.

-     </para>

-     <para>

-       Memory allocators are difficult to write and contain many

-       performance and security pitfalls.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  When computing array sizes or rounding up allocation

- 	  requests (to the next allocation granularity, or for

- 	  alignment purposes), checks for arithmetic overflow are

- 	  required.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Size computations for array allocations need overflow

- 	  checking.  See <xref

- 	  linkend="sect-Defensive_Coding-C-Allocators-Arrays"/>.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  It can be difficult to beat well-tuned general-purpose

- 	  allocators.  In micro-benchmarks, pool allocators can show

- 	  huge wins, and size-specific pools can reduce internal

- 	  fragmentation.  But often, utilization of individual pools

- 	  is poor, and external fragmentation increases the overall

- 	  memory usage.

- 	</para>

-       </listitem>

-     </itemizedlist>

-   </section>

- 

-   <section>

-     <title>Conservative garbage collection</title>

-     <para>

-       Garbage collection can be an alternative to explicit memory

-       management using <function>malloc</function> and

-       <function>free</function>.  The Boehm-Dehmers-Weiser allocator

-       can be used from C programs, with minimal type annotations.

-       Performance is competitive with <function>malloc</function> on

-       64-bit architectures, especially for multi-threaded programs.

-       The stop-the-world pauses may be problematic for some real-time

-       applications, though.

-     </para>

-     <para>

-       However, using a conservative garbage collector may reduce

-       opertunities for code reduce because once one library in a

-       program uses garbage collection, the whole process memory needs

-       to be subject to it, so that no pointers are missed.  The

-       Boehm-Dehmers-Weiser collector also reserves certain signals for

-       internal use, so it is not fully transparent to the rest of the

-       program.

-     </para>

-   </section>

- </section>

- 

en-US/C-Language.adoc
file added
+216
@@ -0,0 +1,216 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-C-Language]]

+ ==== The Core Language

+ 

+ C provides no memory safety. Most recommendations in this section

+ deal with this aspect of the language.

+ 

+ [[sect-Defensive_Coding-C-Undefined]]

+ ===== Undefined Behavior

+ 

+ Some C constructs are defined to be undefined by the C standard.

+ This does not only mean that the standard does not describe

+ what happens when the construct is executed. It also allows

+ optimizing compilers such as GCC to assume that this particular

+ construct is never reached. In some cases, this has caused

+ GCC to optimize security checks away. (This is not a flaw in GCC

+ or the C language. But C certainly has some areas which are more

+ difficult to use than others.)

+ 

+ Common sources of undefined behavior are:

+ 

+ * out-of-bounds array accesses

+ 

+ * null pointer dereferences

+ 

+ * overflow in signed integer arithmetic

+ 

+ [[sect-Defensive_Coding-C-Pointers]]

+ ===== Recommendations for Pointers and Array Handling

+ 

+ Always keep track of the size of the array you are working with.

+ Often, code is more obviously correct when you keep a pointer

+ past the last element of the array, and calculate the number of

+ remaining elements by substracting the current position from

+ that pointer. The alternative, updating a separate variable

+ every time when the position is advanced, is usually less

+ obviously correct.

+ 

+ <<ex-Defensive_Coding-C-Pointers-remaining>>

+ shows how to extract Pascal-style strings from a character

+ buffer. The two pointers kept for length checks are

+ `inend` and `outend`.

+ `inp` and `outp` are the

+ respective positions.

+ The number of input bytes is checked using the expression

+ `len > (size_t)(inend - inp)`.

+ The cast silences a compiler warning;

+ `inend` is always larger than

+ `inp`.

+ 

+ [[ex-Defensive_Coding-C-Pointers-remaining]]

+ .Array processing in C

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/C-Pointers-remaining.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ It is important that the length checks always have the form

+ `len > (size_t)(inend - inp)`, where

+ `len` is a variable of type

+ `size_t` which denotes the *total*

+ number of bytes which are about to be read or written next. In

+ general, it is not safe to fold multiple such checks into one,

+ as in `len1 + len2 > (size_t)(inend - inp)`,

+ because the expression on the left can overflow or wrap around

+ (see <<sect-Defensive_Coding-C-Arithmetic>>), and it

+ no longer reflects the number of bytes to be processed.

+ 

+ [[sect-Defensive_Coding-C-Arithmetic]]

+ ===== Recommendations for Integer Arithmetic

+ 

+ Overflow in signed integer arithmetic is undefined. This means

+ that it is not possible to check for overflow after it happened,

+ see <<ex-Defensive_Coding-C-Arithmetic-bad>>.

+ 

+ [[ex-Defensive_Coding-C-Arithmetic-bad]]

+ .Incorrect overflow detection in C

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/C-Arithmetic-add.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ The following approaches can be used to check for overflow,

+ without actually causing it.

+ 

+ * Use a wider type to perform the calculation, check that the

+ result is within bounds, and convert the result to the

+ original type. All intermediate results must be checked in

+ this way.

+ 

+ * Perform the calculation in the corresponding unsigned type

+ and use bit fiddling to detect the overflow.

+ <<ex-Defensive_Coding-C-Arithmetic-add_unsigned>>

+ shows how to perform an overflow check for unsigned integer

+ addition. For three or more terms, all the intermediate

+ additions have to be checked in this way.

+ 

+ [[ex-Defensive_Coding-C-Arithmetic-add_unsigned]]

+ .Overflow checking for unsigned addition

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/C-Arithmetic-add_unsigned.adoc[]

+ ----

+ 

+ ====

+ 

+ * Compute bounds for acceptable input values which are known

+ to avoid overflow, and reject other values. This is the

+ preferred way for overflow checking on multiplications,

+ see <<ex-Defensive_Coding-C-Arithmetic-mult>>.

+ 

+ [[ex-Defensive_Coding-C-Arithmetic-mult]]

+ .Overflow checking for unsigned multiplication

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/C-Arithmetic-mult.adoc[]

+ ----

+ 

+ ====

+ 

+ Basic arithmetic operations are commutative, so for bounds checks,

+ there are two different but mathematically equivalent

+ expressions. Sometimes, one of the expressions results in

+ better code because parts of it can be reduced to a constant.

+ This applies to overflow checks for multiplication `a *

+ b` involving a constant `a`, where the

+ expression is reduced to `b > C` for some

+ constant `C` determined at compile time. The

+ other expression, `b && a > ((unsigned)-1) /

+ b`, is more difficult to optimize at compile time.

+ 

+ When a value is converted to a signed integer, GCC always

+ chooses the result based on 2's complement arithmetic. This GCC

+ extension (which is also implemented by other compilers) helps a

+ lot when implementing overflow checks.

+ 

+ Sometimes, it is necessary to compare unsigned and signed

+ integer variables. This results in a compiler warning,

+ *comparison between signed and unsigned integer

+ expressions*, because the comparison often gives

+ unexpected results for negative values. When adding a cast,

+ make sure that negative values are covered properly. If the

+ bound is unsigned and the checked quantity is signed, you should

+ cast the checked quantity to an unsigned type as least as wide

+ as either operand type. As a result, negative values will fail

+ the bounds check. (You can still check for negative values

+ separately for clarity, and the compiler will optimize away this

+ redundant check.)

+ 

+ Legacy code should be compiled with the [option]`-fwrapv`

+ GCC option. As a result, GCC will provide 2's complement

+ semantics for integer arithmetic, including defined behavior on

+ integer overflow.

+ 

+ [[sect-Defensive_Coding-C-Globals]]

+ ===== Global Variables

+ 

+ Global variables should be avoided because they usually lead to

+ thread safety hazards. In any case, they should be declared

+ `static`, so that access is restricted to a

+ single translation unit.

+ 

+ Global constants are not a problem, but declaring them can be

+ tricky. <<ex-Defensive_Coding-C-Globals-String_Array>>

+ shows how to declare a constant array of constant strings.

+ The second `const` is needed to make the

+ array constant, and not just the strings. It must be placed

+ after the `*`, and not before it.

+ 

+ [[ex-Defensive_Coding-C-Globals-String_Array]]

+ .Declaring a constant array of constant strings

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/C-Globals-String_Array.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ Sometimes, static variables local to functions are used as a

+ replacement for proper memory management. Unlike non-static

+ local variables, it is possible to return a pointer to static

+ local variables to the caller. But such variables are

+ well-hidden, but effectively global (just as static variables at

+ file scope). It is difficult to add thread safety afterwards if

+ such interfaces are used. Merely dropping the

+ `static` keyword in such cases leads to

+ undefined behavior.

+ 

+ Another source for static local variables is a desire to reduce

+ stack space usage on embedded platforms, where the stack may

+ span only a few hundred bytes. If this is the only reason why

+ the `static` keyword is used, it can just be

+ dropped, unless the object is very large (larger than

+ 128 kilobytes on 32-bit platforms). In the latter case, it is

+ recommended to allocate the object using

+ `malloc`, to obtain proper array checking, for

+ the same reasons outlined in <<sect-Defensive_Coding-C-Allocators-alloca>>.

en-US/C-Language.xml
file removed
-221
@@ -1,221 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-C-Language">

-   <title>The core language</title>

-   <para>

-     C provides no memory safety.  Most recommendations in this section

-     deal with this aspect of the language.

-   </para>

- 

-   <section id="sect-Defensive_Coding-C-Undefined">

-     <title>Undefined behavior</title>

-     <para>

-       Some C constructs are defined to be undefined by the C standard.

-       This does not only mean that the standard does not describe

-       what happens when the construct is executed.  It also allows

-       optimizing compilers such as GCC to assume that this particular

-       construct is never reached.  In some cases, this has caused

-       GCC to optimize security checks away.  (This is not a flaw in GCC

-       or the C language.  But C certainly has some areas which are more

-       difficult to use than others.)

-     </para>

- 

-     <para>

-       Common sources of undefined behavior are:

-     </para>

-     <itemizedlist>

-       <listitem><para>out-of-bounds array accesses</para></listitem>

-       <listitem><para>null pointer dereferences</para></listitem>

-       <listitem><para>overflow in signed integer arithmetic</para></listitem>

-     </itemizedlist>

-   </section>

- 

-   <section id="sect-Defensive_Coding-C-Pointers">

-     <title>Recommendations for pointers and array handling</title>

-     <para>

-       Always keep track of the size of the array you are working with.

-       Often, code is more obviously correct when you keep a pointer

-       past the last element of the array, and calculate the number of

-       remaining elements by substracting the current position from

-       that pointer.  The alternative, updating a separate variable

-       every time when the position is advanced, is usually less

-       obviously correct.

-     </para>

-     <para>

-       <xref linkend="ex-Defensive_Coding-C-Pointers-remaining"/>

-       shows how to extract Pascal-style strings from a character

-       buffer.  The two pointers kept for length checks are

-       <varname>inend</varname> and <varname>outend</varname>.

-       <varname>inp</varname> and <varname>outp</varname> are the

-       respective positions.

-       The number of input bytes is checked using the expression

-       <literal>len > (size_t)(inend - inp)</literal>.

-       The cast silences a compiler warning;

-       <varname>inend</varname> is always larger than

-       <varname>inp</varname>.

-     </para>

-     <example id="ex-Defensive_Coding-C-Pointers-remaining">

-       <title>Array processing in C</title>

-       <xi:include href="snippets/C-Pointers-remaining.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       It is important that the length checks always have the form

-       <literal>len > (size_t)(inend - inp)</literal>, where

-       <varname>len</varname> is a variable of type

-       <type>size_t</type> which denotes the <emphasis>total</emphasis>

-       number of bytes which are about to be read or written next.  In

-       general, it is not safe to fold multiple such checks into one,

-       as in <literal>len1 + len2 > (size_t)(inend - inp)</literal>,

-       because the expression on the left can overflow or wrap around

-       (see <xref linkend="sect-Defensive_Coding-C-Arithmetic"/>), and it

-       no longer reflects the number of bytes to be processed.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-C-Arithmetic">

-     <title>Recommendations for integer arithmetic</title>

-     <para>

-       Overflow in signed integer arithmetic is undefined.  This means

-       that it is not possible to check for overflow after it happened,

-       see <xref linkend="ex-Defensive_Coding-C-Arithmetic-bad"/>.

-     </para>

-     <example id="ex-Defensive_Coding-C-Arithmetic-bad">

-       <title>Incorrect overflow detection in C</title>

-       <xi:include href="snippets/C-Arithmetic-add.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       The following approaches can be used to check for overflow,

-       without actually causing it.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Use a wider type to perform the calculation, check that the

- 	  result is within bounds, and convert the result to the

- 	  original type.  All intermediate results must be checked in

- 	  this way.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Perform the calculation in the corresponding unsigned type

- 	  and use bit fiddling to detect the overflow.

- 	  <xref linkend="ex-Defensive_Coding-C-Arithmetic-add_unsigned"/>

- 	  shows how to perform an overflow check for unsigned integer

- 	  addition.  For three or more terms, all the intermediate

- 	  additions have to be checked in this way.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <example id="ex-Defensive_Coding-C-Arithmetic-add_unsigned">

-       <title>Overflow checking for unsigned addition</title>

-       <xi:include href="snippets/C-Arithmetic-add_unsigned.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Compute bounds for acceptable input values which are known

- 	  to avoid overflow, and reject other values.  This is the

- 	  preferred way for overflow checking on multiplications,

- 	  see <xref linkend="ex-Defensive_Coding-C-Arithmetic-mult"/>.

- 	  <!-- This approach can result in bogus compiler warnings

- 	       with signed types:

- 	       http://gcc.gnu.org/bugzilla/post_bug.cgi -->

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <example id="ex-Defensive_Coding-C-Arithmetic-mult">

-       <title>Overflow checking for unsigned multiplication</title>

-       <xi:include href="snippets/C-Arithmetic-mult.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       Basic arithmetic operations are commutative, so for bounds checks,

-       there are two different but mathematically equivalent

-       expressions.  Sometimes, one of the expressions results in

-       better code because parts of it can be reduced to a constant.

-       This applies to overflow checks for multiplication <literal>a *

-       b</literal> involving a constant <literal>a</literal>, where the

-       expression is reduced to <literal>b &gt; C</literal> for some

-       constant <literal>C</literal> determined at compile time.  The

-       other expression, <literal>b &amp;&amp; a > ((unsigned)-1) /

-       b</literal>, is more difficult to optimize at compile time.

-     </para>

-     <para>

-       When a value is converted to a signed integer, GCC always

-       chooses the result based on 2's complement arithmetic.  This GCC

-       extension (which is also implemented by other compilers) helps a

-       lot when implementing overflow checks.

-     </para>

-     <para>

-       Sometimes, it is necessary to compare unsigned and signed

-       integer variables.  This results in a compiler warning,

-       <emphasis>comparison between signed and unsigned integer

-       expressions</emphasis>, because the comparison often gives

-       unexpected results for negative values.  When adding a cast,

-       make sure that negative values are covered properly.  If the

-       bound is unsigned and the checked quantity is signed, you should

-       cast the checked quantity to an unsigned type as least as wide

-       as either operand type.  As a result, negative values will fail

-       the bounds check.  (You can still check for negative values

-       separately for clarity, and the compiler will optimize away this

-       redundant check.)

-     </para>

-     <para>

-       Legacy code should be compiled with the <option>-fwrapv</option>

-       GCC option.  As a result, GCC will provide 2's complement

-       semantics for integer arithmetic, including defined behavior on

-       integer overflow.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-C-Globals">

-     <title>Global variables</title>

-     <para>

-       Global variables should be avoided because they usually lead to

-       thread safety hazards.  In any case, they should be declared

-       <literal>static</literal>, so that access is restricted to a

-       single translation unit.

-     </para>

-     <para>

-       Global constants are not a problem, but declaring them can be

-       tricky.  <xref linkend="ex-Defensive_Coding-C-Globals-String_Array"/>

-       shows how to declare a constant array of constant strings.

-       The second <literal>const</literal> is needed to make the

-       array constant, and not just the strings.  It must be placed

-       after the <literal>*</literal>, and not before it.

-     </para>

-     <example id="ex-Defensive_Coding-C-Globals-String_Array">

-       <title>Declaring a constant array of constant strings</title>

-       <xi:include href="snippets/C-Globals-String_Array.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       Sometimes, static variables local to functions are used as a

-       replacement for proper memory management.  Unlike non-static

-       local variables, it is possible to return a pointer to static

-       local variables to the caller.  But such variables are

-       well-hidden, but effectively global (just as static variables at

-       file scope). It is difficult to add thread safety afterwards if

-       such interfaces are used.  Merely dropping the

-       <literal>static</literal> keyword in such cases leads to

-       undefined behavior.

-     </para>

-     <para>

-       Another source for static local variables is a desire to reduce

-       stack space usage on embedded platforms, where the stack may

-       span only a few hundred bytes.  If this is the only reason why

-       the <literal>static</literal> keyword is used, it can just be

-       dropped, unless the object is very large (larger than

-       128 kilobytes on 32 bit platforms).  In the latter case, it is

-       recommended to allocate the object using

-       <literal>malloc</literal>, to obtain proper array checking, for

-       the same reasons outlined in <xref

-       linkend="sect-Defensive_Coding-C-Allocators-alloca"/>.

-     </para>

-   </section>

- </section>

en-US/C-Libc.adoc
file added
+287
@@ -0,0 +1,287 @@

+ 

+ :experimental:

+ 

+ include::entities.adoc[]

+ 

+ [[sect-Defensive_Coding-C-Libc]]

+ ==== The C Standard Library

+ 

+ Parts of the C standard library (and the UNIX and GNU extensions)

+ are difficult to use, so you should avoid them.

+ 

+ Please check the applicable documentation before using the

+ recommended replacements. Many of these functions allocate

+ buffers using `malloc` which your code must

+ deallocate explicitly using `free`.

+ 

+ [[sect-Defensive_Coding-C-Absolutely-Banned]]

+ ===== Absolutely Banned Interfaces

+ 

+ The functions listed below must not be used because they are

+ almost always unsafe. Use the indicated replacements instead.

+ 

+ * `gets`

+ ⟶ `fgets`

+ 

+ * `getwd`

+ ⟶ `getcwd`

+ or `get_current_dir_name`

+ 

+ * `readdir_r` ⟶ `readdir`

+ 

+ * `realpath` (with a non-NULL second parameter)

+ ⟶ `realpath` with NULL as the second parameter,

+ or `canonicalize_file_name`

+ 

+ The constants listed below must not be used, either. Instead,

+ code must allocate memory dynamically and use interfaces with

+ length checking.

+ 

+ * `NAME_MAX` (limit not actually enforced by

+ the kernel)

+ 

+ * `PATH_MAX` (limit not actually enforced by

+ the kernel)

+ 

+ * `_PC_NAME_MAX` (This limit, returned by the

+ `pathconf` function, is not enforced by

+ the kernel.)

+ 

+ * `_PC_PATH_MAX` (This limit, returned by the

+ `pathconf` function, is not enforced by

+ the kernel.)

+ 

+ The following structure members must not be used.

+ 

+ * `f_namemax` in `struct

+ statvfs` (limit not actually enforced by the kernel,

+ see `_PC_NAME_MAX` above)

+ 

+ [[sect-Defensive_Coding-C-Avoid]]

+ ===== Functions to Avoid

+ 

+ The following string manipulation functions can be used securely

+ in principle, but their use should be avoided because they are

+ difficult to use correctly. Calls to these functions can be

+ replaced with `asprintf` or

+ `vasprintf`. (For non-GNU targets, these

+ functions are available from Gnulib.) In some cases, the

+ `snprintf` function might be a suitable

+ replacement, see <<sect-Defensive_Coding-C-String-Functions-Length>>.

+ 

+ * `sprintf`

+ 

+ * `strcat`

+ 

+ * `strcpy`

+ 

+ * `vsprintf`

+ 

+ Use the indicated replacements for the functions below.

+ 

+ * `alloca` ⟶

+ `malloc` and `free`

+ (see <<sect-Defensive_Coding-C-Allocators-alloca>>)

+ 

+ * `putenv` ⟶

+ explicit `envp` argument in process creation

+ (see <<sect-Defensive_Coding-Tasks-Processes-environ>>)

+ 

+ * `setenv` ⟶

+ explicit `envp` argument in process creation

+ (see <<sect-Defensive_Coding-Tasks-Processes-environ>>)

+ 

+ * `strdupa` ⟶

+ `strdup` and `free`

+ (see <<sect-Defensive_Coding-C-Allocators-alloca>>)

+ 

+ * `strndupa` ⟶

+ `strndup` and `free`

+ (see <<sect-Defensive_Coding-C-Allocators-alloca>>)

+ 

+ * `system` ⟶

+ `posix_spawn`

+ or `fork`pass:attributes[{blank}]/pass:attributes[{blank}]`execve`pass:attributes[{blank}]/

+ (see <<sect-Defensive_Coding-Tasks-Processes-execve>>)

+ 

+ * `unsetenv` ⟶

+ explicit `envp` argument in process creation

+ (see <<sect-Defensive_Coding-Tasks-Processes-environ>>)

+ 

+ [[sect-Defensive_Coding-C-String-Functions-Length]]

+ ===== String Functions with Explicit Length Arguments

+ 

+ The C run-time library provides string manipulation functions

+ which not just look for NUL characters for string termination,

+ but also honor explicit lengths provided by the caller.

+ However, these functions evolved over a long period of time, and

+ the lengths mean different things depending on the function.

+ 

+ [[sect-Defensive_Coding-C-Libc-snprintf]]

+ ====== `snprintf`

+ 

+ The `snprintf` function provides a way to

+ construct a string in a statically-sized buffer. (If the buffer

+ size is allocated on the heap, consider use

+ `asprintf` instead.)

+ 

+ [source,c]

+ ----

+ include::snippets/C-String-Functions-snprintf.adoc[]

+ 

+ ----

+ 

+ The second argument to the `snprintf` call

+ should always be the size of the buffer in the first argument

+ (which should be a character array). Elaborate pointer and

+ length arithmetic can introduce errors and nullify the

+ security benefits of `snprintf`.

+ 

+ In particular, `snprintf` is not well-suited

+ to constructing a string iteratively, by appending to an

+ existing buffer. `snprintf` returns one of

+ two values, `-1` on errors, or the number of

+ characters which *would have been written to the

+ buffer if the buffer were large enough*. This means

+ that adding the result of `snprintf` to the

+ buffer pointer to skip over the characters just written is

+ incorrect and risky. However, as long as the length argument

+ is not zero, the buffer will remain null-terminated. <<ex-Defensive_Coding-C-String-Functions-snprintf-incremental>>

+ works because `end -current > 0` is a loop

+ invariant. After the loop, the result string is in the

+ `buf` variable.

+ 

+ [[ex-Defensive_Coding-C-String-Functions-snprintf-incremental]]

+ .Repeatedly writing to a buffer using `snprintf`

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/C-String-Functions-snprintf-incremental.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ If you want to avoid the call to `strlen`

+ for performance reasons, you have to check for a negative

+ return value from `snprintf` and also check

+ if the return value is equal to the specified buffer length or

+ larger. Only if neither condition applies, you may advance

+ the pointer to the start of the write buffer by the number

+ return by `snprintf`. However, this

+ optimization is rarely worthwhile.

+ 

+ Note that it is not permitted to use the same buffer both as

+ the destination and as a source argument.

+ 

+ [[sect-Defensive_Coding-C-Libc-vsnprintf]]

+ ====== `vsnprintf` and Format Strings

+ 

+ If you use `vsnprintf` (or

+ `vasprintf` or even

+ `snprintf`) with a format string which is

+ not a constant, but a function argument, it is important to

+ annotate the function with a `format`

+ function attribute, so that GCC can warn about misuse of your

+ function (see <<ex-Defensive_Coding-C-String-Functions-format-Attribute>>).

+ 

+ [[ex-Defensive_Coding-C-String-Functions-format-Attribute]]

+ .The `format` function attribute

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/C-String-Functions-format.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-C-Libc-strncpy]]

+ ====== `strncpy`

+ 

+ The `strncpy` function does not ensure that

+ the target buffer is null-terminated. A common idiom for

+ ensuring NUL termination is:

+ 

+ [source,c]

+ ----

+ include::snippets/C-String-Functions-strncpy.adoc[]

+ 

+ ----

+ 

+ Another approach uses the `strncat`

+ function for this purpose:

+ 

+ [source,c]

+ ----

+ include::snippets/C-String-Functions-strncat-as-strncpy.adoc[]

+ 

+ ----

+ 

+ [[sect-Defensive_Coding-C-Libc-strncat]]

+ ====== `strncat`

+ 

+ The length argument of the `strncat`

+ function specifies the maximum number of characters copied

+ from the source buffer, excluding the terminating NUL

+ character. This means that the required number of bytes in

+ the destination buffer is the length of the original string,

+ plus the length argument in the `strncat`

+ call, plus one. Consequently, this function is rarely

+ appropriate for performing a length-checked string operation,

+ with the notable exception of the `strcpy`

+ emulation described in <<sect-Defensive_Coding-C-Libc-strncpy>>.

+ 

+ To implement a length-checked string append, you can use an

+ approach similar to <<ex-Defensive_Coding-C-String-Functions-snprintf-incremental>>:

+ 

+ [source,c]

+ ----

+ include::snippets/C-String-Functions-strncat-emulation.adoc[]

+ 

+ ----

+ 

+ In many cases, including this one, the string concatenation

+ can be avoided by combining everything into a single format

+ string:

+ 

+ [source,c]

+ ----

+ include::snippets/C-String-Functions-strncat-merged.adoc[]

+ 

+ ----

+ 

+ But you should must not dynamically construct format strings

+ to avoid concatenation because this would prevent GCC from

+ type-checking the argument lists.

+ 

+ It is not possible to use format strings like

+ `"%s%s"` to implement concatenation, unless

+ you use separate buffers. `snprintf` does

+ not support overlapping source and target strings.

+ 

+ ====== `strlcpy` and `strlcat`

+ 

+ Some systems support `strlcpy` and

+ `strlcat` functions which behave this way,

+ but these functions are not part of GNU libc.

+ `strlcpy` is often replaced with

+ `snprintf` with a `"%s"`

+ format string. See <<sect-Defensive_Coding-C-Libc-strncpy>> for a caveat

+ related to the `snprintf` return value.

+ 

+ To emulate `strlcat`, use the approach

+ described in <<sect-Defensive_Coding-C-Libc-strncat>>.

+ 

+ ====== ISO C11 Annex K *pass:attributes[{blank}]`_s` functions

+ 

+ ISO C11 adds another set of length-checking functions, but GNU

+ libc currently does not implement them.

+ 

+ ====== Other `strn*` and `stpn*` functions

+ 

+ GNU libc contains additional functions with different variants

+ of length checking. Consult the documentation before using

+ them to find out what the length actually means.

en-US/C-Libc.xml
file removed
-352
@@ -1,352 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-C-Libc">

-   <title>The C standard library</title>

-   <para>

-     Parts of the C standard library (and the UNIX and GNU extensions)

-     are difficult to use, so you shoud avoid them.

-   </para>

-   <para>

-     Please check the applicable documentation before using the

-     recommended replacements.  Many of these functions allocate

-     buffers using <function>malloc</function> which your code must

-     deallocate explicitly using <function>free</function>.

-   </para>

-   <section id="sect-Defensive_Coding-C-Absolutely-Banned">

-     <title>Absolutely banned interfaces</title>

-     <para>

-       The functions listed below must not be used because they are

-       almost always unsafe.  Use the indicated replacements instead.

-     </para>

-     <itemizedlist>

-       <listitem><para><function>gets</function>

-       ⟶ <function>fgets</function></para></listitem>

-       <listitem><para><function>getwd</function>

-       ⟶ <function>getcwd</function>

-       or <function>get_current_dir_name</function></para></listitem>

-       <listitem>

- 	<para>

- 	  <function>readdir_r</function> ⟶ <function>readdir</function>

- 	  <!-- It is quite complicated to allocate a properly-sized

- 	       buffer for use with readdir_r, and readdir provides

- 	       sufficient thread safety guarantees. -->

- 	  <!-- ??? Add File_System cross-reference -->

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <function>realpath</function> (with a non-NULL second parameter)

- 	  ⟶ <function>realpath</function> with NULL as the second parameter,

- 	  or <function>canonicalize_file_name</function>

- 	  <!-- It is complicated to allocate a properly-sized buffer

- 	       for use with realpath. -->

- 	  <!-- ??? Add File_System cross-reference -->

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       The constants listed below must not be used, either.  Instead,

-       code must allocate memory dynamically and use interfaces with

-       length checking.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  <literal>NAME_MAX</literal> (limit not actually enforced by

- 	  the kernel)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <literal>PATH_MAX</literal> (limit not actually enforced by

- 	  the kernel)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <literal>_PC_NAME_MAX</literal> (This limit, returned by the

- 	  <function>pathconf</function> function, is not enforced by

- 	  the kernel.)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <literal>_PC_PATH_MAX</literal> (This limit, returned by the

- 	  <function>pathconf</function> function, is not enforced by

- 	  the kernel.)

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       The following structure members must not be used.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  <literal>f_namemax</literal> in <literal>struct

- 	  statvfs</literal> (limit not actually enforced by the kernel,

- 	  see <literal>_PC_NAME_MAX</literal> above)

- 	</para>

-       </listitem>

-     </itemizedlist>

-   </section>

-   <section id="sect-Defensive_Coding-C-Avoid">

-     <title>Functions to avoid</title>

-     <para>

-       The following string manipulation functions can be used securely

-       in principle, but their use should be avoided because they are

-       difficult to use correctly.  Calls to these functions can be

-       replaced with <function>asprintf</function> or

-       <function>vasprintf</function>.  (For non-GNU targets, these

-       functions are available from Gnulib.)  In some cases, the

-       <function>snprintf</function> function might be a suitable

-       replacement, see <xref

-       linkend="sect-Defensive_Coding-C-String-Functions-Length"/>.

-     </para>

-     <itemizedlist>

-       <listitem><para><function>sprintf</function></para></listitem>

-       <listitem><para><function>strcat</function></para></listitem>

-       <listitem><para><function>strcpy</function></para></listitem>

-       <listitem><para><function>vsprintf</function></para></listitem>

-     </itemizedlist>

-     <para>

-       Use the indicated replacements for the functions below.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  <function>alloca</function> ⟶

- 	  <function>malloc</function> and <function>free</function>

- 	  (see <xref linkend="sect-Defensive_Coding-C-Allocators-alloca"/>)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <function>putenv</function> ⟶

- 	  explicit <varname>envp</varname> argument in process creation

- 	  (see <xref linkend="sect-Defensive_Coding-Tasks-Processes-environ"/>)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <function>setenv</function> ⟶

- 	  explicit <varname>envp</varname> argument in process creation

- 	  (see <xref linkend="sect-Defensive_Coding-Tasks-Processes-environ"/>)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <function>strdupa</function> ⟶

- 	  <function>strdup</function> and <function>free</function>

- 	  (see <xref linkend="sect-Defensive_Coding-C-Allocators-alloca"/>)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <function>strndupa</function> ⟶

- 	  <function>strndup</function> and <function>free</function>

- 	  (see <xref linkend="sect-Defensive_Coding-C-Allocators-alloca"/>)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <function>system</function> ⟶

- 	  <function>posix_spawn</function>

- 	  or <function>fork</function>/<function>execve</function>/

- 	  (see <xref linkend="sect-Defensive_Coding-Tasks-Processes-execve"/>)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <function>unsetenv</function> ⟶

- 	  explicit <varname>envp</varname> argument in process creation

- 	  (see <xref linkend="sect-Defensive_Coding-Tasks-Processes-environ"/>)

- 	</para>

-       </listitem>

-     </itemizedlist>

-   </section>

-   <section id="sect-Defensive_Coding-C-String-Functions-Length">

-     <title>String Functions With Explicit Length Arguments</title>

-     <para>

-       The C run-time library provides string manipulation functions

-       which not just look for NUL characters for string termination,

-       but also honor explicit lengths provided by the caller.

-       However, these functions evolved over a long period of time, and

-       the lengths mean different things depending on the function.

-     </para>

-     <section id="sect-Defensive_Coding-C-Libc-snprintf">

-       <title><literal>snprintf</literal></title>

-       <para>

- 	The <function>snprintf</function> function provides a way to

- 	construct a string in a statically-sized buffer.  (If the buffer

- 	size is allocated on the heap, consider use

- 	<function>asprintf</function> instead.)

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/C-String-Functions-snprintf.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	The second argument to the <function>snprintf</function> call

- 	should always be the size of the buffer in the first argument

- 	(which should be a character array).  Elaborate pointer and

- 	length arithmetic can introduce errors and nullify the

- 	security benefits of <function>snprintf</function>.

-       </para>

-       <para>

- 	In particular, <literal>snprintf</literal> is not well-suited

- 	to constructing a string iteratively, by appending to an

- 	existing buffer.  <function>snprintf</function> returns one of

- 	two values, <literal>-1</literal> on errors, or the number of

- 	characters which <emphasis>would have been written to the

- 	buffer if the buffer were large enough</emphasis>.  This means

- 	that adding the result of <function>snprintf</function> to the

- 	buffer pointer to skip over the characters just written is

- 	incorrect and risky.  However, as long as the length argument

- 	is not zero, the buffer will remain NUL-terminated. <xref

- 	linkend="ex-Defensive_Coding-C-String-Functions-snprintf-incremental"/>

- 	works because <literal>end -current &gt; 0</literal> is a loop

- 	invariant.  After the loop, the result string is in the

- 	<varname>buf</varname> variable.

-       </para>

-       <example id="ex-Defensive_Coding-C-String-Functions-snprintf-incremental">

- 	<title>Repeatedly writing to a buffer using <function>snprintf</function></title>

- 	<xi:include href="snippets/C-String-Functions-snprintf-incremental.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	If you want to avoid the call to <function>strlen</function>

- 	for performance reasons, you have to check for a negative

- 	return value from <function>snprintf</function> and also check

- 	if the return value is equal to the specified buffer length or

- 	larger.  Only if neither condition applies, you may advance

- 	the pointer to the start of the write buffer by the number

- 	return by <function>snprintf</function>.  However, this

- 	optimization is rarely worthwhile.

-       </para>

-       <para>

- 	Note that it is not permitted to use the same buffer both as

- 	the destination and as a source argument.

-       </para>

-     </section>

-     <section id="sect-Defensive_Coding-C-Libc-vsnprintf">

-       <title><literal>vsnprintf</literal> and format strings</title>

-       <para>

- 	If you use <function>vsnprintf</function> (or

- 	<function>vasprintf</function> or even

- 	<function>snprintf</function>) with a format string which is

- 	not a constant, but a function argument, it is important to

- 	annotate the function with a <literal>format</literal>

- 	function attribute, so that GCC can warn about misuse of your

- 	function (see <xref

- 	linkend="ex-Defensive_Coding-C-String-Functions-format-Attribute"/>).

-       </para>

-       <example id="ex-Defensive_Coding-C-String-Functions-format-Attribute">

- 	<title>The <literal>format</literal> function attribute</title>

- 	<xi:include href="snippets/C-String-Functions-format.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-     </section>

-     <section id="sect-Defensive_Coding-C-Libc-strncpy">

-       <title><function>strncpy</function></title>

-       <para>

- 	The <function>strncpy</function> function does not ensure that

- 	the target buffer is NUL-terminated.  A common idiom for

- 	ensuring NUL termination is:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/C-String-Functions-strncpy.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	Another approach uses the <function>strncat</function>

- 	function for this purpose:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/C-String-Functions-strncat-as-strncpy.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-     </section>

-     <section id="sect-Defensive_Coding-C-Libc-strncat">

-       <title><function>strncat</function></title>

-       <para>

- 	The length argument of the <function>strncat</function>

- 	function specifies the maximum number of characters copied

- 	from the source buffer, excluding the terminating NUL

- 	character.  This means that the required number of bytes in

- 	the destination buffer is the length of the original string,

- 	plus the length argument in the <function>strncat</function>

- 	call, plus one.  Consequently, this function is rarely

- 	appropriate for performing a length-checked string operation,

- 	with the notable exception of the <function>strcpy</function>

- 	emulation described in <xref

- 	linkend="sect-Defensive_Coding-C-Libc-strncpy"/>.

-       </para>

-       <para>

- 	To implement a length-checked string append, you can use an

- 	approach similar to <xref

- 	linkend="ex-Defensive_Coding-C-String-Functions-snprintf-incremental"/>:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/C-String-Functions-strncat-emulation.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	In many cases, including this one, the string concatenation

- 	can be avoided by combining everything into a single format

- 	string:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/C-String-Functions-strncat-merged.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	But you should must not dynamically construct format strings

- 	to avoid concatenation because this would prevent GCC from

- 	type-checking the argument lists.

-       </para>

-       <para>

- 	It is not possible to use format strings like

- 	<literal>"%s%s"</literal> to implement concatenation, unless

- 	you use separate buffers.  <function>snprintf</function> does

- 	not support overlapping source and target strings.

-       </para>

-     </section>

-     <section>

-       <title><function>strlcpy</function> and

-       <function>strlcat</function></title>

-       <para>

- 	Some systems support <function>strlcpy</function> and

- 	<function>strlcat</function> functions which behave this way,

- 	but these functions are not part of GNU libc.

- 	<function>strlcpy</function> is often replaced with

- 	<function>snprintf</function> with a <literal>"%s"</literal>

- 	format string.  See <xref

- 	linkend="sect-Defensive_Coding-C-Libc-strncpy"/> for a caveat

- 	related to the <function>snprintf</function> return value.

-       </para>

-       <para>

- 	To emulate <function>strlcat</function>, use the approach

- 	described in <xref

- 	linkend="sect-Defensive_Coding-C-Libc-strncat"/>.

-       </para>

-     </section>

-     <section>

-       <title>ISO C11 Annex K *<function>_s</function> functions</title>

-       <para>

- 	ISO C11 adds another set of length-checking functions, but GNU

- 	libc currently does not implement them.

-       </para>

-     </section>

-     <section>

-       <title>Other <function>strn</function>* and

-       <function>stpn</function>* functions</title>

-       <para>

- 	GNU libc contains additional functions with different variants

- 	of length checking.  Consult the documentation before using

- 	them to find out what the length actually means.

-       </para>

-     </section>

-   </section>

- </section>

en-US/C-Other.adoc
file added
+53
@@ -0,0 +1,53 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-C-Other]]

+ ==== Other C-related Topics

+ 

+ [[sect-Defensive_Coding-C-Wrapper-Functions]]

+ ===== Wrapper Functions

+ 

+ Some libraries provide wrappers for standard library functions.

+ Common cases include allocation functions such as

+ `xmalloc` which abort the process on

+ allocation failure (instead of returning a

+ `NULL` pointer), or alternatives to relatively

+ recent library additions such as `snprintf`

+ (along with implementations for systems which lack them).

+ 

+ In general, such wrappers are a bad idea, particularly if they

+ are not implemented as inline functions or preprocessor macros.

+ The compiler lacks knowledge of such wrappers outside the

+ translation unit which defines them, which means that some

+ optimizations and security checks are not performed. Adding

+ `__attribute__` annotations to function

+ declarations can remedy this to some extent, but these

+ annotations have to be maintained carefully for feature parity

+ with the standard implementation.

+ 

+ At the minimum, you should apply these attributes:

+ 

+ * If you wrap function which accepts are GCC-recognized format

+ string (for example, a `printf`-style

+ function used for logging), you should add a suitable

+ `format` attribute, as in <<ex-Defensive_Coding-C-String-Functions-format-Attribute>>.

+ 

+ * If you wrap a function which carries a

+ `warn_unused_result` attribute and you

+ propagate its return value, your wrapper should be declared

+ with `warn_unused_result` as well.

+ 

+ * Duplicating the buffer length checks based on the

+ `__builtin_object_size` GCC builtin is

+ desirable if the wrapper processes arrays. (This

+ functionality is used by the

+ `-D_FORTIFY_SOURCE=2` checks to guard

+ against static buffer overflows.) However, designing

+ appropriate interfaces and implementing the checks may not

+ be entirely straightforward.

+ 

+ For other attributes (such as `malloc`),

+ careful analysis and comparison with the compiler documentation

+ is required to check if propagating the attribute is

+ appropriate. Incorrectly applied attributes can result in

+ undesired behavioral changes in the compiled code. 

\ No newline at end of file

en-US/C-Other.xml
file removed
-70
@@ -1,70 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-C-Other">

-   <title>Other C-related topics</title>

-   <section id="sect-Defensive_Coding-C-Wrapper-Functions">

-     <title>Wrapper functions</title>

-     <para>

-       Some libraries provide wrappers for standard library functions.

-       Common cases include allocation functions such as

-       <function>xmalloc</function> which abort the process on

-       allocation failure (instead of returning a

-       <literal>NULL</literal> pointer), or alternatives to relatively

-       recent library additions such as <function>snprintf</function>

-       (along with implementations for systems which lack them).

-     </para>

-     <para>

-       In general, such wrappers are a bad idea, particularly if they

-       are not implemented as inline functions or preprocessor macros.

-       The compiler lacks knowledge of such wrappers outside the

-       translation unit which defines them, which means that some

-       optimizations and security checks are not performed.  Adding

-       <literal>__attribute__</literal> annotations to function

-       declarations can remedy this to some extent, but these

-       annotations have to be maintained carefully for feature parity

-       with the standard implementation.

-     </para>

-     <para>

-       At the minimum, you should apply these attributes:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  If you wrap function which accepts are GCC-recognized format

- 	  string (for example, a <function>printf</function>-style

- 	  function used for logging), you should add a suitable

- 	  <literal>format</literal> attribute, as in <xref

- 	  linkend="ex-Defensive_Coding-C-String-Functions-format-Attribute"/>.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  If you wrap a function which carries a

- 	  <literal>warn_unused_result</literal> attribute and you

- 	  propagate its return value, your wrapper should be declared

- 	  with <literal>warn_unused_result</literal> as well.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Duplicating the buffer length checks based on the

- 	  <function>__builtin_object_size</function> GCC builtin is

- 	  desirable if the wrapper processes arrays.  (This

- 	  functionality is used by the

- 	  <literal>-D_FORTIFY_SOURCE=2</literal> checks to guard

- 	  against static buffer overflows.)  However, designing

- 	  appropriate interfaces and implementing the checks may not

- 	  be entirely straightforward.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       For other attributes (such as <literal>malloc</literal>),

-       careful analysis and comparison with the compiler documentation

-       is required to check if propagating the attribute is

-       appropriate.  Incorrectly applied attributes can result in

-       undesired behavioral changes in the compiled code.

-     </para>

-   </section>

- </section>

en-US/C.adoc
file added
+13
@@ -0,0 +1,13 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-C]]

+ === The C Programming Language

+ 

+ include::C-Language.adoc[]

+ 

+ include::C-Libc.adoc[]

+ 

+ include::C-Allocators.adoc[]

+ 

+ include::C-Other.adoc[] 

\ No newline at end of file

en-US/C.xml
file removed
-12
@@ -1,12 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-C">

- 	<title>The C Programming Language</title>

- 

-     <xi:include href="C-Language.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="C-Libc.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="C-Allocators.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="C-Other.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

- </chapter>

- 

en-US/CXX-Language.adoc
file added
+133
@@ -0,0 +1,133 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-CXX-Language]]

+ ==== The Core Language

+ 

+ C++ includes a large subset of the C language. As far as the C

+ subset is used, the recommendations in <<chap-Defensive_Coding-C>> apply.

+ 

+ ===== Array Allocation with `operator new[]`

+ 

+ For very large values of `n`, an expression

+ like `new T[n]` can return a pointer to a heap

+ region which is too small. In other words, not all array

+ elements are actually backed with heap memory reserved to the

+ array. Current GCC versions generate code that performs a

+ computation of the form `sizeof(T) * size_t(n) +

+ cookie_size`, where `cookie_size` is

+ currently at most 8. This computation can overflow, and GCC

+ versions prior to 4.8 generated code which did not detect this.

+ (Fedora 18 was the first release which fixed this in GCC.)

+ 

+ The `std::vector` template can be used instead

+ an explicit array allocation. (The GCC implementation detects

+ overflow internally.)

+ 

+ If there is no alternative to `operator new[]`

+ and the sources will be compiled with older GCC versions, code

+ which allocates arrays with a variable length must check for

+ overflow manually. For the `new T[n]` example,

+ the size check could be `n || (n > 0 && n >

+ (size_t(-1) - 8) / sizeof(T))`. (See <<sect-Defensive_Coding-C-Arithmetic>>.) If there are

+ additional dimensions (which must be constants according to the

+ {cpp} standard), these should be included as factors in the

+ divisor.

+ 

+ These countermeasures prevent out-of-bounds writes and potential

+ code execution. Very large memory allocations can still lead to

+ a denial of service. <<sect-Defensive_Coding-Tasks-Serialization-Decoders>>

+ contains suggestions for mitigating this problem when processing

+ untrusted data.

+ 

+ See <<sect-Defensive_Coding-C-Allocators-Arrays>>

+ for array allocation advice for C-style memory allocation.

+ 

+ ===== Overloading

+ 

+ Do not overload functions with versions that have different

+ security characteristics. For instance, do not implement a

+ function `strcat` which works on

+ `std::string` arguments. Similarly, do not name

+ methods after such functions.

+ 

+ ===== ABI compatibility and preparing for security updates

+ 

+ A stable binary interface (ABI) is vastly preferred for security

+ updates. Without a stable ABI, all reverse dependencies need

+ recompiling, which can be a lot of work and could even be

+ impossible in some cases. Ideally, a security update only

+ updates a single dynamic shared object, and is picked up

+ automatically after restarting affected processes.

+ 

+ Outside of extremely performance-critical code, you should

+ ensure that a wide range of changes is possible without breaking

+ ABI. Some very basic guidelines are:

+ 

+ * Avoid inline functions.

+ 

+ * Use the pointer-to-implementation idiom.

+ 

+ * Try to avoid templates. Use them if the increased type

+ safety provides a benefit to the programmer.

+ 

+ * Move security-critical code out of templated code, so that

+ it can be patched in a central place if necessary.

+ 

+ The KDE project publishes a document with more extensive

+ guidelines on ABI-preserving changes to {cpp} code, link:++https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B++[Policies/Binary

+ Compatibility Issues With {cpp}]

+ (*d-pointer* refers to the

+ pointer-to-implementation idiom).

+ 

+ [[sect-Defensive_Coding-CXX-Language-CXX11]]

+ ===== {cpp}0X and {cpp}11 Support

+ 

+ GCC offers different language compatibility modes:

+ 

+ * [option]`-std=c++98` for the original 1998 {cpp}

+ standard

+ 

+ * [option]`-std=c++03` for the 1998 standard with the

+ changes from the TR1 technical report

+ 

+ * [option]`-std=c++11` for the 2011 {cpp} standard. This

+ option should not be used.

+ 

+ * [option]`-std=c++0x` for several different versions

+ of {cpp}11 support in development, depending on the GCC

+ version. This option should not be used.

+ 

+ For each of these flags, there are variants which also enable

+ GNU extensions (mostly language features also found in C99 or

+ C11): 

+ 

+ * [option]`-std=gnu++98`

+ * [option]`-std=gnu++03`

+ * [option]`-std=gnu++11`

+ 

+ Again, [option]`-std=gnu++11` should not be used.

+ 

+ If you enable {cpp}11 support, the ABI of the standard {cpp} library

+ `libstdc++` will change in subtle ways.

+ Currently, no {cpp} libraries are compiled in {cpp}11 mode, so if

+ you compile your code in {cpp}11 mode, it will be incompatible

+ with the rest of the system. Unfortunately, this is also the

+ case if you do not use any {cpp}11 features. Currently, there is

+ no safe way to enable {cpp}11 mode (except for freestanding

+ applications).

+ 

+ The meaning of {cpp}0X mode changed from GCC release to GCC

+ release. Earlier versions were still ABI-compatible with {cpp}98

+ mode, but in the most recent versions, switching to {cpp}0X mode

+ activates {cpp}11 support, with its compatibility problems.

+ 

+ Some {cpp}11 features (or approximations thereof) are available

+ with TR1 support, that is, with [option]`-std=c++03` or

+ [option]`-std=gnu++03` and in the

+ `<tr1/*>` header files. This includes

+ `std::tr1::shared_ptr` (from

+ `<tr1/memory>`) and

+ `std::tr1::function` (from

+ `<tr1/functional>`). For other {cpp}11

+ features, the Boost {cpp} library contains replacements.

en-US/CXX-Language.xml
file removed
-188
@@ -1,188 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-CXX-Language">

-   <title>The core language</title>

-   <para>

-     C++ includes a large subset of the C language.  As far as the C

-     subset is used, the recommendations in <xref

-     linkend="chap-Defensive_Coding-C"/> apply.

-   </para>

- 

-   <section>

-     <title>Array allocation with <literal>operator new[]</literal></title>

-     <para>

-       For very large values of <literal>n</literal>, an expression

-       like <literal>new T[n]</literal> can return a pointer to a heap

-       region which is too small.  In other words, not all array

-       elements are actually backed with heap memory reserved to the

-       array.  Current GCC versions generate code that performs a

-       computation of the form <literal>sizeof(T) * size_t(n) +

-       cookie_size</literal>, where <literal>cookie_size</literal> is

-       currently at most 8.  This computation can overflow, and GCC

-       versions prior to 4.8 generated code which did not detect this.

-       (Fedora 18 was the first release which fixed this in GCC.)

-     </para>

-     <para>

-       The <literal>std::vector</literal> template can be used instead

-       an explicit array allocation.  (The GCC implementation detects

-       overflow internally.)

-     </para>

-     <para>

-       If there is no alternative to <literal>operator new[]</literal>

-       and the sources will be compiled with older GCC versions, code

-       which allocates arrays with a variable length must check for

-       overflow manually.  For the <literal>new T[n]</literal> example,

-       the size check could be <literal>n || (n > 0 &amp;&amp; n &gt;

-       (size_t(-1) - 8) / sizeof(T))</literal>.  (See <xref

-       linkend="sect-Defensive_Coding-C-Arithmetic"/>.)  If there are

-       additional dimensions (which must be constants according to the

-       C++ standard), these should be included as factors in the

-       divisor.

-     </para>

-     <para>

-       These countermeasures prevent out-of-bounds writes and potential

-       code execution.  Very large memory allocations can still lead to

-       a denial of service.  <xref

-       linkend="sect-Defensive_Coding-Tasks-Serialization-Decoders"/>

-       contains suggestions for mitigating this problem when processing

-       untrusted data.

-     </para>

-     <para>

-       See <xref linkend="sect-Defensive_Coding-C-Allocators-Arrays"/>

-       for array allocation advice for C-style memory allocation.

-     </para>

-   </section>

- 

-   <section>

-     <title>Overloading</title>

-     <para>

-       Do not overload functions with versions that have different

-       security characteristics.  For instance, do not implement a

-       function <function>strcat</function> which works on

-       <type>std::string</type> arguments.  Similarly, do not name

-       methods after such functions.

-     </para>

-   </section>

-   <section>

-     <title>ABI compatibility and preparing for security updates</title>

-     <para>

-       A stable binary interface (ABI) is vastly preferred for security

-       updates.  Without a stable ABI, all reverse dependencies need

-       recompiling, which can be a lot of work and could even be

-       impossible in some cases.  Ideally, a security update only

-       updates a single dynamic shared object, and is picked up

-       automatically after restarting affected processes.

-     </para>

-     <para>

-       Outside of extremely performance-critical code, you should

-       ensure that a wide range of changes is possible without breaking

-       ABI.  Some very basic guidelines are:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Avoid inline functions.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Use the pointer-to-implementation idiom.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Try to avoid templates.  Use them if the increased type

- 	  safety provides a benefit to the programmer.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Move security-critical code out of templated code, so that

- 	  it can be patched in a central place if necessary.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       The KDE project publishes a document with more extensive

-       guidelines on ABI-preserving changes to C++ code, <ulink

-       url="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++">Policies/Binary

-       Compatibility Issues With C++</ulink>

-       (<emphasis>d-pointer</emphasis> refers to the

-       pointer-to-implementation idiom).

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-CXX-Language-CXX11">

-     <title>C++0X and C++11 support</title>

-     <para>

-       GCC offers different language compatibility modes:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  <option>-std=c++98</option> for the original 1998 C++

- 	  standard

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <option>-std=c++03</option> for the 1998 standard with the

- 	  changes from the TR1 technical report

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <option>-std=c++11</option> for the 2011 C++ standard.  This

- 	  option should not be used.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <option>-std=c++0x</option> for several different versions

- 	  of C++11 support in development, depending on the GCC

- 	  version.  This option should not be used.

- 	  <!-- There were two incompatibilies before GCC 4.7.2

- 	       (std::list and std::pair), but link C++98 and C++11

- 	       code is still unsupported, although it currently has

- 	       some chance of working by accident. -->

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       For each of these flags, there are variants which also enable

-       GNU extensions (mostly language features also found in C99 or

-       C11): <option>-std=gnu++98</option>,

-       <option>-std=gnu++03</option>, <option>-std=gnu++11</option>.

-       Again, <option>-std=gnu++11</option> should not be used.

-     </para>

-     <para>

-       If you enable C++11 support, the ABI of the standard C++ library

-       <literal>libstdc++</literal> will change in subtle ways.

-       Currently, no C++ libraries are compiled in C++11 mode, so if

-       you compile your code in C++11 mode, it will be incompatible

-       with the rest of the system.  Unfortunately, this is also the

-       case if you do not use any C++11 features.  Currently, there is

-       no safe way to enable C++11 mode (except for freestanding

-       applications).

-     </para>

-     <para>

-       The meaning of C++0X mode changed from GCC release to GCC

-       release.  Earlier versions were still ABI-compatible with C++98

-       mode, but in the most recent versions, switching to C++0X mode

-       activates C++11 support, with its compatibility problems.

-     </para>

-     <para>

-       Some C++11 features (or approximations thereof) are available

-       with TR1 support, that is, with <option>-std=c++03</option> or

-       <option>-std=gnu++03</option> and in the

-       <literal>&lt;tr1/*&gt;</literal> header files.  This includes

-       <literal>std::tr1::shared_ptr</literal> (from

-       <literal>&lt;tr1/memory&gt;</literal>) and

-       <literal>std::tr1::function</literal> (from

-       <literal>&lt;tr1/functional&gt;</literal>).  For other C++11

-       features, the Boost C++ library contains replacements.

-     </para>

-   </section>

- </section>

- 

en-US/CXX-Std.adoc
file added
+190
@@ -0,0 +1,190 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-CXX-Std]]

+ ==== The C++ Standard Library

+ 

+ The C++ standard library includes most of its C counterpart

+ by reference, see <<sect-Defensive_Coding-C-Libc>>.

+ 

+ [[sect-Defensive_Coding-CXX-Std-Functions]]

+ ===== Functions That Are Difficult to Use

+ 

+ This section collects functions and function templates which are

+ part of the standard library and are difficult to use.

+ 

+ [[sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators]]

+ ====== Unpaired Iterators

+ 

+ Functions which use output operators or iterators which do not

+ come in pairs (denoting ranges) cannot perform iterator range

+ checking.

+ (See <<sect-Defensive_Coding-CXX-Std-Iterators>>)

+ Function templates which involve output iterators are

+ particularly dangerous:

+ 

+ * `std::copy`

+ 

+ * `std::copy_backward`

+ 

+ * `std::copy_if`

+ 

+ * `std::move` (three-argument variant)

+ 

+ * `std::move_backward`

+ 

+ * `std::partition_copy_if`

+ 

+ * `std::remove_copy`

+ 

+ * `std::remove_copy_if`

+ 

+ * `std::replace_copy`

+ 

+ * `std::replace_copy_if`

+ 

+ * `std::swap_ranges`

+ 

+ * `std::transform`

+ 

+ In addition, `std::copy_n`,

+ `std::fill_n` and

+ `std::generate_n` do not perform iterator

+ checking, either, but there is an explicit count which has to be

+ supplied by the caller, as opposed to an implicit length

+ indicator in the form of a pair of forward iterators.

+ 

+ These output-iterator-expecting functions should only be used

+ with unlimited-range output iterators, such as iterators

+ obtained with the `std::back_inserter`

+ function.

+ 

+ Other functions use single input or forward iterators, which can

+ read beyond the end of the input range if the caller is not careful:

+ 

+ * `std::equal`

+ 

+ * `std::is_permutation`

+ 

+ * `std::mismatch`

+ 

+ [[sect-Defensive_Coding-CXX-Std-String]]

+ ===== String Handling with `std::string`

+ 

+ The `std::string` class provides a convenient

+ way to handle strings. Unlike C strings,

+ `std::string` objects have an explicit length

+ (and can contain embedded NUL characters), and storage for its

+ characters is managed automatically. This section discusses

+ `std::string`, but these observations also

+ apply to other instances of the

+ `std::basic_string` template.

+ 

+ The pointer returned by the `data()` member

+ function does not necessarily point to a NUL-terminated string.

+ To obtain a C-compatible string pointer, use

+ `c_str()` instead, which adds the NUL

+ terminator.

+ 

+ The pointers returned by the `data()` and

+ `c_str()` functions and iterators are only

+ valid until certain events happen. It is required that the

+ exact `std::string` object still exists (even

+ if it was initially created as a copy of another string object).

+ Pointers and iterators are also invalidated when non-const

+ member functions are called, or functions with a non-const

+ reference parameter. The behavior of the GCC implementation

+ deviates from that required by the {cpp} standard if multiple

+ threads are present. In general, only the first call to a

+ non-const member function after a structural modification of the

+ string (such as appending a character) is invalidating, but this

+ also applies to member function such as the non-const version of

+ `begin()`, in violation of the {cpp} standard.

+ 

+ Particular care is necessary when invoking the

+ `c_str()` member function on a temporary

+ object. This is convenient for calling C functions, but the

+ pointer will turn invalid as soon as the temporary object is

+ destroyed, which generally happens when the outermost expression

+ enclosing the expression on which `c_str()`

+ is called completes evaluation. Passing the result of

+ `c_str()` to a function which does not store

+ or otherwise leak that pointer is safe, though.

+ 

+ Like with `std::vector` and

+ `std::array`, subscribing with

+ `operator[]` does not perform bounds checks.

+ Use the `at(size_type)` member function

+ instead. See <<sect-Defensive_Coding-CXX-Std-Subscript>>.

+ Furthermore, accessing the terminating NUL character using

+ `operator[]` is not possible. (In some

+ implementations, the `c_str()` member function

+ writes the NUL character on demand.)

+ 

+ Never write to the pointers returned by

+ `data()` or `c_str()`

+ after casting away `const`. If you need a

+ C-style writable string, use a

+ `std::vector<char>` object and its

+ `data()` member function. In this case, you

+ have to explicitly add the terminating NUL character.

+ 

+ GCC's implementation of `std::string` is

+ currently based on reference counting. It is expected that a

+ future version will remove the reference counting, due to

+ performance and conformance issues. As a result, code that

+ implicitly assumes sharing by holding to pointers or iterators

+ for too long will break, resulting in run-time crashes or worse.

+ On the other hand, non-const iterator-returning functions will

+ no longer give other threads an opportunity for invalidating

+ existing iterators and pointers because iterator invalidation

+ does not depend on sharing of the internal character array

+ object anymore.

+ 

+ [[sect-Defensive_Coding-CXX-Std-Subscript]]

+ ===== Containers and `operator[]`

+ 

+ Many sequence containers similar to `std::vector`

+ provide both `operator[](size_type)` and a

+ member function `at(size_type)`. This applies

+ to `std::vector` itself,

+ `std::array`, `std::string`

+ and other instances of `std::basic_string`.

+ 

+ `operator[](size_type)` is not required by the

+ standard to perform bounds checking (and the implementation in

+ GCC does not). In contrast, `at(size_type)`

+ must perform such a check. Therefore, in code which is not

+ performance-critical, you should prefer

+ `at(size_type)` over

+ `operator[](size_type)`, even though it is

+ slightly more verbose.

+ 

+ The `front()` and `back()`

+ member functions are undefined if a vector object is empty. You

+ can use `vec.at(0)` and

+ `vec.at(vec.size() - 1)` as checked

+ replacements. For an empty vector, `data()` is

+ defined; it returns an arbitrary pointer, but not necessarily

+ the NULL pointer.

+ 

+ [[sect-Defensive_Coding-CXX-Std-Iterators]]

+ ===== Iterators

+ 

+ Iterators do not perform any bounds checking. Therefore, all

+ functions that work on iterators should accept them in pairs,

+ denoting a range, and make sure that iterators are not moved

+ outside that range. For forward iterators and bidirectional

+ iterators, you need to check for equality before moving the

+ first or last iterator in the range. For random-access

+ iterators, you need to compute the difference before adding or

+ subtracting an offset. It is not possible to perform the

+ operation and check for an invalid operator afterwards.

+ 

+ Output iterators cannot be compared for equality. Therefore, it

+ is impossible to write code that detects that it has been

+ supplied an output area that is too small, and their use should

+ be avoided.

+ 

+ These issues make some of the standard library functions

+ difficult to use correctly, see <<sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators>>.

en-US/CXX-Std.xml
file removed
-202
@@ -1,202 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-CXX-Std">

-   <title>The C++ standard library</title>

-   <para>

-     The C++ standard library includes most of its C counterpart

-     by reference, see <xref linkend="sect-Defensive_Coding-C-Libc"/>.

-   </para>

-   <section id="sect-Defensive_Coding-CXX-Std-Functions">

-     <title>Functions that are difficult to use</title>

-     <para>

-       This section collects functions and function templates which are

-       part of the standard library and are difficult to use.

-     </para>

-     <section id="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators">

-       <title>Unpaired iterators</title>

-       <para>

- 	Functions which use output operators or iterators which do not

- 	come in pairs (denoting ranges) cannot perform iterator range

- 	checking.

- 	(See <xref linkend="sect-Defensive_Coding-CXX-Std-Iterators"/>)

- 	Function templates which involve output iterators are

- 	particularly dangerous:

-       </para>

-       <itemizedlist>

- 	<listitem><para><function>std::copy</function></para></listitem>

- 	<listitem><para><function>std::copy_backward</function></para></listitem>

- 	<listitem><para><function>std::copy_if</function></para></listitem>

- 	<listitem><para><function>std::move</function> (three-argument variant)</para></listitem>

- 	<listitem><para><function>std::move_backward</function></para></listitem>

- 	<listitem><para><function>std::partition_copy_if</function></para></listitem>

- 	<listitem><para><function>std::remove_copy</function></para></listitem>

- 	<listitem><para><function>std::remove_copy_if</function></para></listitem>

- 	<listitem><para><function>std::replace_copy</function></para></listitem>

- 	<listitem><para><function>std::replace_copy_if</function></para></listitem>

- 	<listitem><para><function>std::swap_ranges</function></para></listitem>

- 	<listitem><para><function>std::transform</function></para></listitem>

-       </itemizedlist>

-       <para>

- 	In addition, <function>std::copy_n</function>,

- 	<function>std::fill_n</function> and

- 	<function>std::generate_n</function> do not perform iterator

- 	checking, either, but there is an explicit count which has to be

- 	supplied by the caller, as opposed to an implicit length

- 	indicator in the form of a pair of forward iterators.

-       </para>

-       <para>

- 	These output-iterator-expecting functions should only be used

- 	with unlimited-range output iterators, such as iterators

- 	obtained with the <function>std::back_inserter</function>

- 	function.

-       </para>

-       <para>

- 	Other functions use single input or forward iterators, which can

- 	read beyond the end of the input range if the caller is not careful:

-       </para>

-       <itemizedlist>

- 	<listitem><para><function>std::equal</function></para></listitem>

- 	<listitem><para><function>std::is_permutation</function></para></listitem>

- 	<listitem><para><function>std::mismatch</function></para></listitem>

-       </itemizedlist>

-     </section>

-   </section>

-   <section id="sect-Defensive_Coding-CXX-Std-String">

-     <title>String handling with <literal>std::string</literal></title>

-     <para>

-       The <literal>std::string</literal> class provides a convenient

-       way to handle strings.  Unlike C strings,

-       <literal>std::string</literal> objects have an explicit length

-       (and can contain embedded NUL characters), and storage for its

-       characters is managed automatically.  This section discusses

-       <literal>std::string</literal>, but these observations also

-       apply to other instances of the

-       <literal>std::basic_string</literal> template.

-     </para>

-     <para>

-       The pointer returned by the <function>data()</function> member

-       function does not necessarily point to a NUL-terminated string.

-       To obtain a C-compatible string pointer, use

-       <function>c_str()</function> instead, which adds the NUL

-       terminator.

-     </para>

-     <para>

-       The pointers returned by the <function>data()</function> and

-       <function>c_str()</function> functions and iterators are only

-       valid until certain events happen.  It is required that the

-       exact <literal>std::string</literal> object still exists (even

-       if it was initially created as a copy of another string object).

-       Pointers and iterators are also invalidated when non-const

-       member functions are called, or functions with a non-const

-       reference parameter.  The behavior of the GCC implementation

-       deviates from that required by the C++ standard if multiple

-       threads are present.  In general, only the first call to a

-       non-const member function after a structural modification of the

-       string (such as appending a character) is invalidating, but this

-       also applies to member function such as the non-const version of

-       <function>begin()</function>, in violation of the C++ standard.

-     </para>

-     <para>

-       Particular care is necessary when invoking the

-       <function>c_str()</function> member function on a temporary

-       object.  This is convenient for calling C functions, but the

-       pointer will turn invalid as soon as the temporary object is

-       destroyed, which generally happens when the outermost expression

-       enclosing the expression on which <function>c_str()</function>

-       is called completes evaluation.  Passing the result of

-       <function>c_str()</function> to a function which does not store

-       or otherwise leak that pointer is safe, though.

-     </para>

-     <para>

-       Like with <literal>std::vector</literal> and

-       <literal>std::array</literal>, subscribing with

-       <literal>operator[]</literal> does not perform bounds checks.

-       Use the <function>at(size_type)</function> member function

-       instead.  See <xref

-       linkend="sect-Defensive_Coding-CXX-Std-Subscript"/>.

-       Furthermore, accessing the terminating NUL character using

-       <literal>operator[]</literal> is not possible.  (In some

-       implementations, the <literal>c_str()</literal> member function

-       writes the NUL character on demand.)

-     </para>

-     <para>

-       Never write to the pointers returned by

-       <function>data()</function> or <function>c_str()</function>

-       after casting away <literal>const</literal>.  If you need a

-       C-style writable string, use a

-       <literal>std::vector&lt;char&gt;</literal> object and its

-       <function>data()</function> member function.  In this case, you

-       have to explicitly add the terminating NUL character.

-     </para>

-     <para>

-       GCC's implementation of <literal>std::string</literal> is

-       currently based on reference counting.  It is expected that a

-       future version will remove the reference counting, due to

-       performance and conformance issues.  As a result, code that

-       implicitly assumes sharing by holding to pointers or iterators

-       for too long will break, resulting in run-time crashes or worse.

-       On the other hand, non-const iterator-returning functions will

-       no longer give other threads an opportunity for invalidating

-       existing iterators and pointers because iterator invalidation

-       does not depend on sharing of the internal character array

-       object anymore.

-     </para>

-   </section>

-   <section id="sect-Defensive_Coding-CXX-Std-Subscript">

-     <title>Containers and <literal>operator[]</literal></title>

-     <para>

-       Many sequence containers similar to <literal>std::vector</literal>

-       provide both <literal>operator[](size_type)</literal> and a

-       member function <literal>at(size_type)</literal>.  This applies

-       to <literal>std::vector</literal> itself,

-       <literal>std::array</literal>, <literal>std::string</literal>

-       and other instances of <literal>std::basic_string</literal>.

-     </para>

-     <para>

-       <literal>operator[](size_type)</literal> is not required by the

-       standard to perform bounds checking (and the implementation in

-       GCC does not).  In contrast, <literal>at(size_type)</literal>

-       must perform such a check.  Therefore, in code which is not

-       performance-critical, you should prefer

-       <literal>at(size_type)</literal> over

-       <literal>operator[](size_type)</literal>, even though it is

-       slightly more verbose.

-     </para>

-     <para>

-       The <literal>front()</literal> and <literal>back()</literal>

-       member functions are undefined if a vector object is empty.  You

-       can use <literal>vec.at(0)</literal> and

-       <literal>vec.at(vec.size() - 1)</literal> as checked

-       replacements.  For an empty vector, <literal>data()</literal> is

-       defined; it returns an arbitrary pointer, but not necessarily

-       the NULL pointer.

-     </para>

-   </section>

-   <section id="sect-Defensive_Coding-CXX-Std-Iterators">

-     <title>Iterators</title>

-     <para>

-       Iterators do not perform any bounds checking.  Therefore, all

-       functions that work on iterators should accept them in pairs,

-       denoting a range, and make sure that iterators are not moved

-       outside that range.  For forward iterators and bidirectional

-       iterators, you need to check for equality before moving the

-       first or last iterator in the range.  For random-access

-       iterators, you need to compute the difference before adding or

-       subtracting an offset.  It is not possible to perform the

-       operation and check for an invalid operator afterwards.

-     </para>

-     <para>

-       Output iterators cannot be compared for equality.  Therefore, it

-       is impossible to write code that detects that it has been

-       supplied an output area that is too small, and their use should

-       be avoided.

-     </para>

-     <para>

-       These issues make some of the standard library functions

-       difficult to use correctly, see <xref

-       linkend="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"/>.

-     </para>

-   </section>

- </section>

- 

en-US/CXX.adoc
file added
+9
@@ -0,0 +1,9 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-CXX]]

+ === The C++ Programming Language

+ 

+ include::CXX-Language.adoc[]

+ 

+ include::CXX-Std.adoc[] 

\ No newline at end of file

en-US/CXX.xml
file removed
-10
@@ -1,10 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-CXX">

-   <title>The C++ Programming Language</title>

- 

-   <xi:include href="CXX-Language.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-   <xi:include href="CXX-Std.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

- </chapter>

- 

en-US/Common_Content/Legal_Notice.adoc
file added
+23
@@ -0,0 +1,23 @@

+ 

+ :experimental:

+ include::../entities.adoc[]

+ 

+ Copyright  {YEAR} {HOLDER}.

+ 

+ The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at link:++http://creativecommons.org/licenses/by-sa/3.0/++[]. The original authors of this document, and Red Hat, designate the Fedora Project as the "Attribution Party" for purposes of CC-BY-SA. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.

+ 

+ Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.

+ 

+ Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, MetaMatrix, Fedora, the Infinity Logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.

+ 

+ For guidelines on the permitted uses of the Fedora trademarks, refer to link:++https://fedoraproject.org/wiki/Legal:Trademark_guidelines++[].

+ 

+ *Linux* is the registered trademark of Linus Torvalds in the United States and other countries.

+ 

+ *Java* is a registered trademark of Oracle and/or its affiliates.

+ 

+ *XFS* is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.

+ 

+ *MySQL* is a registered trademark of MySQL AB in the United States, the European Union and other countries.

+ 

+ All other trademarks are the property of their respective owners. 

\ No newline at end of file

en-US/Common_Content/images/title_logo.svg
file added
+61
@@ -0,0 +1,61 @@

+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>

+ <!-- Created with Inkscape (http://www.inkscape.org/) -->

+ 

+ <svg

+    xmlns:svg="http://www.w3.org/2000/svg"

+    xmlns="http://www.w3.org/2000/svg"

+    version="1.0"

+    width="220"

+    height="70"

+    id="svg6180">

+   <defs

+      id="defs6182" />

+   <g

+      transform="translate(-266.55899,-345.34488)"

+      id="layer1">

+     <path

+        d="m 316.7736,397.581 c 0,0 0,0 -20.53889,0 0.3327,4.45245 3.92157,7.77609 8.70715,7.77609 3.38983,0 6.31456,-1.39616 8.64094,-3.65507 0.46553,-0.46679 0.99726,-0.59962 1.59519,-0.59962 0.79781,0 1.59561,0.39932 2.12692,1.06388 0.3327,0.46553 0.53216,0.99726 0.53216,1.52857 0,0.73118 -0.3327,1.52857 -0.93106,2.12734 -2.7919,2.99052 -7.51086,4.98503 -12.16403,4.98503 -8.44149,0 -15.22074,-6.77967 -15.22074,-15.22158 0,-8.44149 6.58022,-15.22074 15.02171,-15.22074 8.37529,0 14.62323,6.51317 14.62323,15.08749 0,1.26418 -1.12924,2.12861 -2.39258,2.12861 z m -12.23065,-11.76512 c -4.45329,0 -7.51085,2.92473 -8.17499,7.17731 10.03626,0 16.35083,0 16.35083,0 -0.59836,-4.05355 -3.78874,-7.17731 -8.17584,-7.17731 z"

+        id="path11"

+        style="fill:#3c6eb4" />

+     <path

+        d="m 375.46344,410.80807 c -8.44106,0 -15.22074,-6.77968 -15.22074,-15.22159 0,-8.44149 6.77968,-15.22074 15.22074,-15.22074 8.44234,0 15.22159,6.77925 15.22159,15.22074 -4.2e-4,8.44149 -6.77968,15.22159 -15.22159,15.22159 z m 0,-24.65992 c -5.31688,0 -8.77377,4.25427 -8.77377,9.43833 0,5.18364 3.45689,9.43833 8.77377,9.43833 5.31731,0 8.77504,-4.25469 8.77504,-9.43833 -4.2e-4,-5.18406 -3.45773,-9.43833 -8.77504,-9.43833 z"

+        id="path13"

+        style="fill:#3c6eb4" />

+     <path

+        d="m 412.66183,380.36574 c -4.45963,0 -7.40966,1.319 -10.01391,4.62956 l -0.24036,-1.53995 0,0 c -0.20198,-1.60743 -1.57326,-2.84926 -3.23382,-2.84926 -1.80139,0 -3.26206,1.459 -3.26206,3.26081 0,0.003 0,0.005 0,0.008 l 0,0 0,0.003 0,0 0,23.40712 c 0,1.79464 1.46194,3.25743 3.257,3.25743 1.79465,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-12.56209 c 0,-5.71621 4.98502,-8.57432 10.23613,-8.57432 1.59519,0 2.85726,-1.32953 2.85726,-2.92515 0,-1.59561 -1.26207,-2.85726 -2.85768,-2.85726 z"

+        id="path15"

+        style="fill:#3c6eb4" />

+     <path

+        d="m 447.02614,395.58648 c 0.0666,-8.17541 -5.78326,-15.22074 -15.222,-15.22074 -8.44192,0 -15.28779,6.77925 -15.28779,15.22074 0,8.44191 6.64684,15.22159 14.68985,15.22159 4.01434,0 7.62682,-2.06621 9.23846,-4.22518 l 0.79359,2.01434 0,0 c 0.42589,1.13177 1.5176,1.93717 2.7978,1.93717 1.65001,0 2.98756,-1.33671 2.99009,-2.98545 l 0,0 0,-7.80687 0,0 0,-4.1556 z m -15.222,9.43833 c -5.31773,0 -8.77419,-4.25469 -8.77419,-9.43833 0,-5.18406 3.45604,-9.43833 8.77419,-9.43833 5.3173,0 8.77419,4.25427 8.77419,9.43833 0,5.18364 -3.45689,9.43833 -8.77419,9.43833 z"

+        id="path17"

+        style="fill:#3c6eb4" />

+     <path

+        d="m 355.01479,368.3337 c 0,-1.7938 -1.46194,-3.18997 -3.25659,-3.18997 -1.79422,0 -3.25743,1.39659 -3.25743,3.18997 l 0,17.1499 c -1.66097,-3.05756 -5.25026,-5.11786 -9.50495,-5.11786 -8.64052,0 -14.42336,6.51318 -14.42336,15.22074 0,8.70757 5.98229,15.22159 14.42336,15.22159 3.76555,0 7.03057,-1.55429 8.98587,-4.25554 l 0.72317,1.83428 c 0.44782,1.25912 1.64917,2.16024 3.06051,2.16024 1.78621,0 3.24984,-1.45435 3.24984,-3.24815 0,-0.005 0,-0.009 0,-0.0139 l 0,0 0,-38.95128 -4.2e-4,0 z m -15.22116,36.69111 c -5.31731,0 -8.70715,-4.25469 -8.70715,-9.43833 0,-5.18406 3.38984,-9.43833 8.70715,-9.43833 5.31773,0 8.70714,4.0544 8.70714,9.43833 0,5.38309 -3.38941,9.43833 -8.70714,9.43833 z"

+        id="path19"

+        style="fill:#3c6eb4" />

+     <path

+        d="m 287.21553,365.34023 c -0.59414,-0.0877 -1.19966,-0.13198 -1.80097,-0.13198 -6.73118,0 -12.20746,5.4767 -12.20746,12.20788 l 0,3.8132 -3.98903,0 c -1.46237,0 -2.65908,1.19671 -2.65908,2.65781 0,1.46321 1.19671,2.93738 2.65908,2.93738 l 3.98819,0 0,20.46004 c 0,1.79464 1.46236,3.25743 3.25658,3.25743 1.79507,0 3.25744,-1.46279 3.25744,-3.25743 l 0,-20.46004 4.40986,0 c 1.46194,0 2.65823,-1.47417 2.65823,-2.93738 0,-1.46152 -1.19629,-2.65823 -2.65823,-2.65823 l -4.40733,0 0,-3.8132 c 0,-3.13852 2.55323,-6.11469 5.69175,-6.11469 0.28294,0 0.56757,0.0211 0.84672,0.062 1.78031,0.26355 3.4358,-0.54269 3.70019,-2.32342 0.2627,-1.77904 -0.96606,-3.43538 -2.74594,-3.69935 z"

+        id="path21"

+        style="fill:#3c6eb4" />

+     <path

+        d="m 482.01243,363.57426 c 0,-10.06788 -8.16108,-18.22938 -18.22897,-18.22938 -10.06282,0 -18.22179,8.15475 -18.22854,18.21631 l -4.2e-4,-4.2e-4 0,14.1071 4.2e-4,4.2e-4 c 0.005,2.28463 1.85832,4.13409 4.14463,4.13409 0.007,0 0.0127,-8.4e-4 0.0194,-8.4e-4 l 0.001,8.4e-4 14.07083,0 0,0 c 10.06409,-0.004 18.22138,-8.16276 18.22138,-18.22812 z"

+        id="path25"

+        style="fill:#294172" />

+     <path

+        d="m 469.13577,349.66577 c -4.72528,0 -8.55576,3.83049 -8.55576,8.55577 0,0.002 0,0.004 0,0.006 l 0,4.52836 -4.51444,0 c -8.5e-4,0 -8.5e-4,0 -0.001,0 -4.72528,0 -8.55576,3.81193 -8.55576,8.53678 0,4.72528 3.83048,8.55577 8.55576,8.55577 4.72486,0 8.55534,-3.83049 8.55534,-8.55577 0,-0.002 0,-0.004 0,-0.006 l 0,-4.54733 4.51444,0 c 8.5e-4,0 0.001,0 0.002,0 4.72486,0 8.55534,-3.79296 8.55534,-8.51781 0,-4.72528 -3.83048,-8.55577 -8.55534,-8.55577 z m -8.55576,21.63483 c -0.004,2.48998 -2.02446,4.50811 -4.51571,4.50811 -2.49378,0 -4.53426,-2.02193 -4.53426,-4.5157 0,-2.49421 2.04048,-4.55366 4.53426,-4.55366 0.002,0 0.004,4.2e-4 0.006,4.2e-4 l 3.86971,0 c 0.001,0 0.002,-4.2e-4 0.003,-4.2e-4 0.35209,0 0.63799,0.28505 0.63799,0.63715 0,4.2e-4 -4.2e-4,8.4e-4 -4.2e-4,0.001 l 0,3.92284 -4.2e-4,0 z m 8.55534,-8.5448 c -0.001,0 -0.003,0 -0.004,0 l -3.87223,0 c -8.4e-4,0 -0.002,0 -0.002,0 -0.35252,0 -0.63757,-0.28506 -0.63757,-0.63758 l 0,-4.2e-4 0,-3.90343 c 0.004,-2.49083 2.02446,-4.50854 4.51571,-4.50854 2.49378,0 4.53468,2.02193 4.53468,4.51613 4.2e-4,2.49336 -2.04048,4.53384 -4.53426,4.53384 z"

+        id="path29"

+        style="fill:#3c6eb4" />

+     <path

+        d="m 460.58001,362.7558 0,-4.52836 c 0,-0.002 0,-0.004 0,-0.006 0,-4.72528 3.83048,-8.55577 8.55576,-8.55577 0.71685,0 1.22623,0.0805 1.88952,0.25469 0.96774,0.25385 1.75796,1.04618 1.75838,1.96922 4.2e-4,1.11575 -0.80919,1.92621 -2.0194,1.92621 -0.57642,0 -0.78473,-0.11048 -1.62892,-0.11048 -2.49125,0 -4.51149,2.01771 -4.51571,4.50854 l 0,3.90385 0,4.2e-4 c 0,0.35252 0.28505,0.63758 0.63757,0.63758 4.3e-4,0 0.001,0 0.002,0 l 2.96521,0 c 1.10521,0 1.99747,0.88467 1.99832,1.99283 0,1.10816 -0.89353,1.99114 -1.99832,1.99114 l -3.60489,0 0,4.54733 c 0,0.002 0,0.004 0,0.006 0,4.72485 -3.83048,8.55534 -8.55534,8.55534 -0.71684,0 -1.22623,-0.0805 -1.88952,-0.25469 -0.96774,-0.25343 -1.75838,-1.04618 -1.7588,-1.9688 0,-1.11575 0.80919,-1.92663 2.01982,-1.92663 0.576,0 0.78473,0.11048 1.6285,0.11048 2.49125,0 4.51191,-2.01771 4.51613,-4.50811 0,0 0,-3.92368 0,-3.9241 0,-0.35168 -0.2859,-0.63673 -0.63799,-0.63673 -4.3e-4,0 -8.5e-4,0 -0.002,0 l -2.96521,-4.2e-4 c -1.10521,0 -1.99831,-0.88214 -1.99831,-1.9903 -4.3e-4,-1.11533 0.90238,-1.99367 2.01939,-1.99367 l 3.58339,0 0,0 z"

+        id="path31"

+        style="fill:#ffffff" />

+     <path

+        d="m 477.41661,378.55292 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"

+        id="text6223"

+        style="fill:#294172;enable-background:new" />

+   </g>

+   <path

+      d="m 181.98344,61.675273 2.81558,0 0,0.37898 -1.18152,0 0,2.94935 -0.45254,0 0,-2.94935 -1.18152,0 0,-0.37898 m 3.26144,0 0.67101,0 0.84937,2.26496 0.85381,-2.26496 0.67102,0 0,3.32833 -0.43917,0 0,-2.9226 -0.85828,2.28279 -0.45255,0 -0.85827,-2.28279 0,2.9226 -0.43694,0 0,-3.32833"

+      id="path2391"

+      style="fill:#294172;enable-background:new" />

+ </svg>

en-US/Defensive_Coding.ent
file removed
-2
@@ -1,2 +0,0 @@

- <!ENTITY YEAR "2012-2014">

- <!ENTITY HOLDER "Red Hat, Inc">

en-US/Defensive_Coding.xml
file removed
-32
@@ -1,32 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

- <book>

-   <xi:include href="Book_Info.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-   <part>

-     <title>Programming Languages</title>

-     <xi:include href="C.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="CXX.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Java.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Python.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Shell.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Go.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Vala.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-   </part>

-   <part>

-     <title>Specific Programming Tasks</title>

-     <xi:include href="Tasks-Library_Design.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Tasks-Descriptors.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Tasks-File_System.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Tasks-Temporary_Files.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Tasks-Processes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Tasks-Serialization.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Tasks-Cryptography.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Tasks-Packaging.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-   </part>

-   <part>

-     <title>Implementing Security Features</title>

-     <xi:include href="Features-Authentication.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-     <xi:include href="Features-TLS.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-   </part>

-     <xi:include href="Revision_History.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

- </book>

en-US/Features-Authentication.adoc
file added
+151
@@ -0,0 +1,151 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Authentication]]

+ === Authentication and Authorization

+ 

+ [[sect-Defensive_Coding-Authentication-Server]]

+ ==== Authenticating Servers

+ 

+ When connecting to a server, a client has to make sure that it

+ is actually talking to the server it expects. There are two

+ different aspects, securing the network path, and making sure

+ that the expected user runs the process on the target host.

+ There are several ways to ensure that:

+ 

+ * The server uses a TLS certificate which is valid according

+ to the web browser public key infrastructure, and the client

+ verifies the certificate and the host name.

+ 

+ * The server uses a TLS certificate which is expected by the

+ client (perhaps it is stored in a configuration file read by

+ the client). In this case, no host name checking is

+ required.

+ 

+ * On Linux, UNIX domain sockets (of the

+ `PF_UNIX` protocol family, sometimes called

+ `PF_LOCAL`) are restricted by file system

+ permissions. If the server socket path is not

+ world-writable, the server identity cannot be spoofed by

+ local users.

+ 

+ * Port numbers less than 1024 (*trusted

+ ports*) can only be used by

+ `root`, so if a UDP or TCP server is

+ running on the local host and it uses a trusted port, its

+ identity is assured. (Not all operating systems enforce the

+ trusted ports concept, and the network might not be trusted,

+ so it is only useful on the local system.)

+ 

+ TLS (<<chap-Defensive_Coding-TLS>>) is the

+ recommended way for securing connections over untrusted

+ networks.

+ 

+ If the server port number is 1024 is higher, a local user can

+ impersonate the process by binding to this socket, perhaps after

+ crashing the real server by exploiting a denial-of-service

+ vulnerability.

+ 

+ [[sect-Defensive_Coding-Authentication-Host_based]]

+ ==== Host-based Authentication

+ 

+ Host-based authentication uses access control lists (ACLs) to

+ accept or deny requests from clients. This authentication

+ method comes in two flavors: IP-based (or, more generally,

+ address-based) and name-based (with the name coming from DNS or

+ `/etc/hosts`). IP-based ACLs often use

+ prefix notation to extend access to entire subnets. Name-based

+ ACLs sometimes use wildcards for adding groups of hosts (from

+ entire DNS subtrees). (In the SSH context, host-based

+ authentication means something completely different and is not

+ covered in this section.)

+ 

+ Host-based authentication trust the network and may not offer

+ sufficient granularity, so it has to be considered a weak form

+ of authentication. On the other hand, IP-based authentication

+ can be made extremely robust and can be applied very early in

+ input processing, so it offers an opportunity for significantly

+ reducing the number of potential attackers for many services.

+ 

+ The names returned by `gethostbyaddr` and

+ `getnameinfo` functions cannot be trusted.

+ (DNS PTR records can be set to arbitrary values, not just names

+ belong to the address owner.) If these names are used for ACL

+ matching, a forward lookup using

+ `gethostbyaddr` or

+ `getaddrinfo` has to be performed. The name

+ is only valid if the original address is found among the results

+ of the forward lookup (*double-reverse

+ lookup*).

+ 

+ An empty ACL should deny all access (deny-by-default). If empty

+ ACLs permits all access, configuring any access list must switch

+ to deny-by-default for all unconfigured protocols, in both

+ name-based and address-based variants.

+ 

+ Similarly, if an address or name is not matched by the list, it

+ should be denied. However, many implementations behave

+ differently, so the actual behavior must be documented properly.

+ 

+ IPv6 addresses can embed IPv4 addresses. There is no

+ universally correct way to deal with this ambiguity. The

+ behavior of the ACL implementation should be documented.

+ 

+ [[sect-Defensive_Coding-Authentication-UNIX_Domain]]

+ ==== UNIX Domain Socket Authentication

+ 

+ UNIX domain sockets (with address family

+ `AF_UNIX` or `AF_LOCAL`) are

+ restricted to the local host and offer a special authentication

+ mechanism: credentials passing.

+ 

+ Nowadays, most systems support the

+ `SO_PEERCRED` (Linux) or

+ `LOCAL_PEERCRED` (FreeBSD) socket options, or

+ the `getpeereid` (other BSDs, OS X).

+ These interfaces provide direct access to the (effective) user

+ ID on the other end of a domain socket connect, without

+ cooperation from the other end.

+ 

+ Historically, credentials passing was implemented using

+ ancillary data in the `sendmsg` and

+ `recvmsg` functions. On some systems, only

+ credentials data that the peer has explicitly sent can be

+ received, and the kernel checks the data for correctness on the

+ sending side. This means that both peers need to deal with

+ ancillary data. Compared to that, the modern interfaces are

+ easier to use. Both sets of interfaces vary considerably among

+ UNIX-like systems, unfortunately.

+ 

+ If you want to authenticate based on supplementary groups, you

+ should obtain the user ID using one of these methods, and look

+ up the list of supplementary groups using

+ `getpwuid` (or

+ `getpwuid_r`) and

+ `getgrouplist`. Using the PID and

+ information from `/proc/PID/status` is prone

+ to race conditions and insecure.

+ 

+ [[sect-Defensive_Coding-Authentication-Netlink]]

+ ==== `AF_NETLINK` Authentication of Origin

+ 

+ Netlink messages are used as a high-performance data transfer

+ mechanism between the kernel and the user space. Traditionally,

+ they are used to exchange information related to the network

+ stack, such as routing table entries.

+ 

+ When processing Netlink messages from the kernel, it is

+ important to check that these messages actually originate from

+ the kernel, by checking that the port ID (or PID) field

+ `nl_pid` in the `sockaddr_nl`

+ structure is `0`. (This structure can be

+ obtained using `recvfrom` or

+ `recvmsg`, it is different from the

+ `nlmsghdr` structure.) The kernel does not

+ prevent other processes from sending unicast Netlink messages,

+ but the `nl_pid` field in the sender's socket

+ address will be non-zero in such cases.

+ 

+ Applications should not use `AF_NETLINK`

+ sockets as an IPC mechanism among processes, but prefer UNIX

+ domain sockets for this tasks. 

\ No newline at end of file

en-US/Features-Authentication.xml
file removed
-189
@@ -1,189 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Authentication">

-   <title>Authentication and Authorization</title>

- 

-   <section id="sect-Defensive_Coding-Authentication-Server">

-     <title>Authenticating servers</title>

-     <para>

-       When connecting to a server, a client has to make sure that it

-       is actually talking to the server it expects.  There are two

-       different aspects, securing the network path, and making sure

-       that the expected user runs the process on the target host.

-       There are several ways to ensure that:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  The server uses a TLS certificate which is valid according

- 	  to the web browser public key infrastructure, and the client

- 	  verifies the certificate and the host name.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The server uses a TLS certificate which is expectedby the

- 	  client (perhaps it is stored in a configuration file read by

- 	  the client).  In this case, no host name checking is

- 	  required.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  On Linux, UNIX domain sockets (of the

- 	  <literal>PF_UNIX</literal> protocol family, sometimes called

- 	  <literal>PF_LOCAL</literal>) are restricted by file system

- 	  permissions.  If the server socket path is not

- 	  world-writable, the server identity cannot be spoofed by

- 	  local users.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Port numbers less than 1024 (<emphasis>trusted

- 	  ports</emphasis>) can only be used by

- 	  <literal>root</literal>, so if a UDP or TCP server is

- 	  running on the local host and it uses a trusted port, its

- 	  identity is assured.  (Not all operating systems enforce the

- 	  trusted ports concept, and the network might not be trusted,

- 	  so it is only useful on the local system.)

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       TLS (<xref linkend="chap-Defensive_Coding-TLS"/>) is the

-       recommended way for securing connections over untrusted

-       networks.

-     </para>

-     <para>

-       If the server port number is 1024 is higher, a local user can

-       impersonate the process by binding to this socket, perhaps after

-       crashing the real server by exploiting a denial-of-service

-       vulnerability.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Authentication-Host_based">

-     <title>Host-based authentication</title>

-     <para>

-       Host-based authentication uses access control lists (ACLs) to

-       accept or deny requests from clients.  Thsis authentication

-       method comes in two flavors: IP-based (or, more generally,

-       address-based) and name-based (with the name coming from DNS or

-       <filename>/etc/hosts</filename>).  IP-based ACLs often use

-       prefix notation to extend access to entire subnets.  Name-based

-       ACLs sometimes use wildcards for adding groups of hosts (from

-       entire DNS subtrees).  (In the SSH context, host-based

-       authentication means something completely different and is not

-       covered in this section.)

-     </para>

-     <para>

-       Host-based authentication trust the network and may not offer

-       sufficient granularity, so it has to be considered a weak form

-       of authentication.  On the other hand, IP-based authentication

-       can be made extremely robust and can be applied very early in

-       input processing, so it offers an opportunity for significantly

-       reducing the number of potential attackers for many services.

-     </para>

-     <para>

-       The names returned by <function>gethostbyaddr</function> and

-       <function>getnameinfo</function> functions cannot be trusted.

-       (DNS PTR records can be set to arbitrary values, not just names

-       belong to the address owner.)  If these names are used for ACL

-       matching, a forward lookup using

-       <function>gethostbyaddr</function> or

-       <function>getaddrinfo</function> has to be performed.  The name

-       is only valid if the original address is found among the results

-       of the forward lookup (<emphasis>double-reverse

-       lookup</emphasis>).

-     </para>

-     <para>

-       An empty ACL should deny all access (deny-by-default).  If empty

-       ACLs permits all access, configuring any access list must switch

-       to deny-by-default for all unconfigured protocols, in both

-       name-based and address-based variants.

-     </para>

-     <para>

-       Similarly, if an address or name is not matched by the list, it

-       should be denied.  However, many implementations behave

-       differently, so the actual behavior must be documented properly.

-     </para>

-     <para>

-       IPv6 addresses can embed IPv4 addresses.  There is no

-       universally correct way to deal with this ambiguity.  The

-       behavior of the ACL implementation should be documented.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Authentication-UNIX_Domain">

-     <title>UNIX domain socket authentication</title>

-     <para>

-       UNIX domain sockets (with address family

-       <literal>AF_UNIX</literal> or <literal>AF_LOCAL</literal>) are

-       restricted to the local host and offer a special authentication

-       mechanism: credentials passing.

-     </para>

-     <para>

-       Nowadays, most systems support the

-       <literal>SO_PEERCRED</literal> (Linux) or

-       <literal>LOCAL_PEERCRED</literal> (FreeBSD) socket options, or

-       the <function>getpeereid</function> (other BSDs, MacOS X).

-       These interfaces provide direct access to the (effective) user

-       ID on the other end of a domain socket connect, without

-       cooperation from the other end.

-     </para>

-     <para>

-       Historically, credentials passing was implemented using

-       ancillary data in the <function>sendmsg</function> and

-       <function>recvmsg</function> functions.  On some systems, only

-       credentials data that the peer has explicitly sent can be

-       received, and the kernel checks the data for correctness on the

-       sending side.  This means that both peers need to deal with

-       ancillary data.  Compared to that, the modern interfaces are

-       easier to use.  Both sets of interfaces vary considerably among

-       UNIX-like systems, unfortunately.

-     </para>

-     <para>

-       If you want to authenticate based on supplementary groups, you

-       should obtain the user ID using one of these methods, and look

-       up the list of supplementary groups using

-       <function>getpwuid</function> (or

-       <function>getpwuid_r</function>) and

-       <function>getgrouplist</function>.  Using the PID and

-       information from <filename>/proc/PID/status</filename> is prone

-       to race conditions and insecure.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Authentication-Netlink">

-     <title><literal>AF_NETLINK</literal> authentication of origin</title>

-     <!-- ??? kernel change may make this obsolete:

-          https://bugzilla.redhat.com/show_bug.cgi?id=851968 -->

-     <para>

-       Netlink messages are used as a high-performance data transfer

-       mechanism between the kernel and the userspace.  Traditionally,

-       they are used to exchange information related to the network

-       statck, such as routing table entries.

-     </para>

-     <para>

-       When processing Netlink messages from the kernel, it is

-       important to check that these messages actually originate from

-       the kernel, by checking that the port ID (or PID) field

-       <literal>nl_pid</literal> in the <literal>sockaddr_nl</literal>

-       structure is <literal>0</literal>.  (This structure can be

-       obtained using <function>recvfrom</function> or

-       <function>recvmsg</function>, it is different from the

-       <literal>nlmsghdr</literal> structure.)  The kernel does not

-       prevent other processes from sending unicast Netlink messages,

-       but the <literal>nl_pid</literal> field in the sender's socket

-       address will be non-zero in such cases.

-     </para>

-     <para>

-       Applications should not use <literal>AF_NETLINK</literal>

-       sockets as an IPC mechanism among processes, but prefer UNIX

-       domain sockets for this tasks.

-     </para>

-   </section>

- </chapter>

- 

en-US/Features-HSM.adoc
file added
+179
@@ -0,0 +1,179 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-HSM]]

+ === Hardware Security Modules and Smart Cards

+ 

+ Hardware Security Modules (HSMs) are specialized hardware intended

+ to protect private keys on server systems. They store internally

+ the private keys (e.g., RSA keys), and provide access to operations

+ with the keys without exposing the keys. That access, is provided using

+ a standardized API, which across Fedora is PKCS#11.

+ 

+ Smart cards are small cards with a micro processor, often combined with a

+ USB reader resembling a USB stick. They are very similar in nature with

+ HSMs as they can also be used to protect private keys and are almost

+ universally accessed via the PKCS#11 API. The main distinguishers from HSMs

+ is their inferior performance and often, the available hardware protection mechanisms.

+ 

+ Typically a smart card or HSM relies on a shared library to provide functionality.

+ This shared library follows the PKCS#11 API and thus is often referred to as 

+ a PKCS#11 module. In Fedora the `opensc`

+ shared module (`opensc-pkcs11.so`) can be used for the majority

+ of smart cards available in the market. By convention these modules are located

+ at `/usr/lib64/pkcs11`. They can be used directly, or via

+ a higher level library.

+ 

+ All the major crypto libraries (NSS, GnuTLS and OpenSSL in Fedora) support

+ hardware security modules and smart cards, by providing wrappers over the

+ PKCS#11 API. However, the level of support varies, as well as the ease of

+ use of such modules and its integration to the overall library API.

+ 

+ * The PKCS#11 API does provide an API to access HSMs or smart cards, but

+ does not provide any method of discovering which HSMs or smart cards are

+ available in the system. In Fedora and modules are registered via link:++https://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html++[p11-kit

+ configuration files], stored at `/etc/pkcs11/modules/`. For applications using

+ `engine_pkcs11` or GnuTLS the registered modules are

+ available without further configuration. Other applications will have to load

+ the `p11-kit-proxy.so` module.

+ 

+ * Most crypto libraries support the link:++https://tools.ietf.org/html/rfc7512++[PKCS#11 URLs scheme]

+ to identify objects stored in an HSM, however that support is not yet universal.

+ Some support transparent usage of PKCS#11 objects, e.g., specifying

+ a PKCS#11 object instead of a file, while others require to use

+ specialized APIs for such objects.

+ 

+ * Objects stored in an HSM or smart card can be protected with a PIN. As such,

+ libraries typically require to set a PIN handling function for accessing private keys,

+ or the PIN can be passed along with a PKCS#11 URL and the pin-value parameter.

+ 

+ * Obtaining a Hardware Security Module, or including it on a continuous integration

+ testing is not always feasible. For testing purposes smart cards supported by the OpenSC

+ project can be used, as well as software modules like `softhsm` which

+ provides a tool to setup a software HSM, and a PKCS#11 library.

+ 

+ * The PKCS#11 API requires applications that use fork to reinitialize the used PKCS#11

+ modules. This is an uncommon requirement, which has led to several bugs across

+ applications in Fedora which used PKCS#11 directly. To make things more complicated

+ software PKCS#11 module like `softhsm` do not require this re-initialization

+ leading to applications working against software modules but failing with hardware

+ modules or smart cards. The wrapper PKCS#11 APIs provided by NSS, GnuTLS and

+ engine_pkcs11 (OpenSSL) handle the reinitialization after fork requirement transparently.

+ 

+ [[sect-Defensive_Coding-HSM-OpenSSL]]

+ ==== OpenSSL HSM Support

+ 

+ OpenSSL does not have native support for PKCS#11. It can

+ provide PKCS#11 support through the OpenSC's project 

+ `pkcs11` engine (formerly known as `engine_pkcs11`).

+ As such software intended to use HSMs, must utilize that engine.

+ 

+ Engine `pkcs11` supports loading stored objects via PKCS#11 URLs.

+ If no PKCS#11 module is specified the engine will use the system-wide registered

+ modules via `p11-kit-proxy.so`.

+ 

+ The following example demonstrates the initialization of the pkcs11 engine

+ and its usage to sign data.

+ 

+ [[ex-Defensive_Coding-HSM-OpenSSL]]

+ .Signing data with HSM and OpenSSL

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-HSM-OpenSSL.adoc[]

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-HSM-GNUTLS]]

+ ==== GnuTLS HSM Support

+ 

+ GnuTLS supports PKCS#11 natively. Most of the API functions

+ accepting certificate files, can also accept PKCS#11 URLs, thus

+ requiring minor or no modifications to applications in order

+ to support HSMs. In most cases applications must be modified

+ to install a PIN callback function.

+ 

+ The following example demonstrates the initialization of the pkcs11 engine

+ and its usage to sign data.

+ 

+ [[ex-Defensive_Coding-HSM-GNUTLS]]

+ .Signing data with HSM and GnuTLS

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-HSM-GNUTLS.adoc[]

+ ----

+ 

+ ====

+ 

+ The PIN callback function can be either set globally as in

+ the example above or locally by utilizing functions such as `gnutls_privkey_set_pin_function`.

+ An example PIN callback function is shown below.

+ 

+ [[ex-Defensive_Coding-HSM-GNUTLS-PIN]]

+ .An example PIN callback with GNUTLS

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-HSM-GNUTLS-PIN.adoc[]

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-HSM-NSS]]

+ ==== NSS HSM Support

+ 

+ NSS supports PKCS#11 natively. In fact all NSS crypto operations,

+ including built-in operations, go through PKCS #11 modules. NSS provides

+ its own software PKCS #11 module called softoken. NSS automatically

+ loads any PKCS #11 module specified in its module database, which can

+ be manipulated with the modutil command. NSS uses the PKCS #11 module

+ that contains the requested keys to do the crypto operations. As long as

+ the application opens an NSS database and properly sets a pin callback. If

+ it runs with native NSS, it should be able to use HSMs that provide PKCS #11

+ modules. Modules can also be loaded programatically, though this is less common.

+ 

+ The following example demonstrates a typical NSS application for signing.

+ 

+ [[ex-Defensive_Coding-HSM-NSS]]

+ .Signing data with HSM and NSS

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-HSM-NSS.adoc[]

+ ----

+ 

+ ====

+ 

+ To use the example above with an HSM or smart card you will need to do the following.

+ 

+ [source,bash]

+ ----

+ 

+ # add your HSM or token library to an NSS database (in the sample code the database is

+ # located in the current directory'.')

+ $ modutil -add "My HSM" -libfile ${path_to_pkcs11_file} -dbdir .

+ # Find the token name on your HSM

+ $ modutil -list -dbdir .

+ # find the cert on your token

+ $ certutil -L -h ${token_name} -d .

+ # pass the cert to your signing program

+ $ NSS_Sign_Example "${token_name}:${cert_name}"

+       

+ ----

+ 

+ [[ex-Defensive_Coding-HSM-NSS-PIN]]

+ .An example PIN callback with NSS

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-HSM-NSS-PIN.adoc[]

+ ----

+ 

+ ====

en-US/Features-TLS.adoc
file added
+944
@@ -0,0 +1,944 @@

+ 

+ :experimental:

+ include::entities.adoc[]

+ 

+ [[chap-Defensive_Coding-TLS]]

+ === Transport Layer Security (TLS)

+ 

+ Transport Layer Security (TLS, formerly Secure Sockets

+ Layer/SSL) is the recommended way to to protect integrity and

+ confidentiality while data is transferred over an untrusted

+ network connection, and to identify the endpoint. At this

+ chapter we describe the available libraries in Fedora as well

+ as known pitfalls, and safe ways to write applications with them.

+ 

+ When using any library, in addition to this guide, it is recommended to consult the

+ library' documentation.

+ 

+ * link:++https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS++[NSS documentation]

+ 

+ * link:++http://www.gnutls.org/manual/++[GnuTLS documentation]

+ 

+ * link:++https://www.openssl.org/docs/++[OpenSSL documentation]

+ 

+ * link:++https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html++[OpenJDK documentation]

+ 

+ [[sect-Defensive_Coding-TLS-Pitfalls]]

+ ==== Common Pitfalls

+ 

+ TLS implementations are difficult to use, and most of them lack

+ a clean API design. The following sections contain

+ implementation-specific advice, and some generic pitfalls are

+ mentioned below.

+ 

+ * Most TLS implementations have questionable default TLS

+ cipher suites. Most of them enable anonymous Diffie-Hellman

+ key exchange (but we generally want servers to authenticate

+ themselves). Many do not disable ciphers which are subject

+ to brute-force attacks because of restricted key lengths.

+ Some even disable all variants of AES in the default

+ configuration.

+ +

+ When overriding the cipher suite defaults, it is recommended

+ to disable all cipher suites which are not present on a

+ whitelist, instead of simply enabling a list of cipher

+ suites. This way, if an algorithm is disabled by default in

+ the TLS implementation in a future security update, the

+ application will not re-enable it.

+ 

+ * The name which is used in certificate validation must match

+ the name provided by the user or configuration file. No host

+ name canonicalization or IP address lookup must be performed.

+ 

+ * The TLS handshake has very poor performance if the TCP Nagle

+ algorithm is active. You should switch on the

+ `TCP_NODELAY` socket option (at least for the

+ duration of the handshake), or use the Linux-specific

+ `TCP_CORK` option.

+ +

+ [[ex-Defensive_Coding-TLS-Nagle]]

+ .Deactivating the TCP Nagle algorithm

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Nagle.adoc[]		      

+ ----

+ 

+ ====

+ 

+ * Implementing proper session resumption decreases handshake

+ overhead considerably. This is important if the upper-layer

+ protocol uses short-lived connections (like most application

+ of HTTPS).

+ 

+ * Both client and server should work towards an orderly

+ connection shutdown, that is send

+ `close_notify` alerts and respond to them.

+ This is especially important if the upper-layer protocol

+ does not provide means to detect connection truncation (like

+ some uses of HTTP).

+ 

+ * When implementing a server using event-driven programming,

+ it is important to handle the TLS handshake properly because

+ it includes multiple network round-trips which can block

+ when an ordinary TCP `accept` would not.

+ Otherwise, a client which fails to complete the TLS

+ handshake for some reason will prevent the server from

+ handling input from other clients.

+ 

+ * Unlike regular file descriptors, TLS connections cannot be

+ passed between processes. Some TLS implementations add

+ additional restrictions, and TLS connections generally

+ cannot be used across `fork` function

+ calls (see <<sect-Defensive_Coding-Tasks-Processes-Fork-Parallel>>).

+ 

+ [[sect-Defensive_Coding-TLS-OpenSSL]]

+ ===== OpenSSL Pitfalls

+ 

+ Some OpenSSL function use *tri-state return

+ values*. Correct error checking is extremely

+ important. Several functions return `int`

+ values with the following meaning:

+ 

+ * The value `1` indicates success (for

+ example, a successful signature verification).

+ 

+ * The value `0` indicates semantic

+ failure (for example, a signature verification which was

+ unsuccessful because the signing certificate was

+ self-signed).

+ 

+ * The value `-1` indicates a low-level

+ error in the system, such as failure to allocate memory

+ using `malloc`.

+ 

+ Treating such tri-state return values as booleans can lead

+ to security vulnerabilities. Note that some OpenSSL

+ functions return boolean results or yet another set of

+ status indicators. Each function needs to be checked

+ individually.

+ 

+ Recovering precise error information is difficult.

+ <<ex-Defensive_Coding-TLS-OpenSSL-Errors>>

+ shows how to obtain a more precise error code after a function

+ call on an `SSL` object has failed. However,

+ there are still cases where no detailed error information is

+ available (e.g., if `SSL_shutdown` fails

+ due to a connection teardown by the other end).

+ 

+ [[ex-Defensive_Coding-TLS-OpenSSL-Errors]]

+ .Obtaining OpenSSL error codes

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-OpenSSL-Errors.adoc[]

+ ----

+ 

+ ====

+ 

+ The `OPENSSL_config` function is

+ documented to never fail. In reality, it can terminate the

+ entire process if there is a failure accessing the

+ configuration file. An error message is written to standard

+ error, but which might not be visible if the function is

+ called from a daemon process.

+ 

+ OpenSSL contains two separate ASN.1 DER decoders. One set

+ of decoders operate on BIO handles (the input/output stream

+ abstraction provided by OpenSSL); their decoder function

+ names start with `d2i_` and end in

+ `_fp` or `_bio` (e.g.,

+ `d2i_X509_fp` or

+ `d2i_X509_bio`). These decoders must not

+ be used for parsing data from untrusted sources; instead,

+ the variants without the `_fp` and

+ `_bio` (e.g.,

+ `d2i_X509`) shall be used. The BIO

+ variants have received considerably less testing and are not

+ very robust.

+ 

+ For the same reason, the OpenSSL command line tools (such as

+ [command]`openssl x509`) are generally generally less

+ robust than the actual library code. They use the BIO

+ functions internally, and not the more robust variants.

+ 

+ The command line tools do not always indicate failure in the

+ exit status of the [application]*openssl* process.

+ For instance, a verification failure in [command]`openssl

+ verify` result in an exit status of zero.

+ 

+ OpenSSL command-line commands, such as [command]`openssl

+ genrsa`, do not ensure that physical entropy is used

+ for key generation—they obtain entropy from

+ `/dev/urandom` and other sources, but not

+ from `/dev/random`. This can result in

+ weak keys if the system lacks a proper entropy source (e.g., a

+ virtual machine with solid state storage). Depending on local

+ policies, keys generated by these OpenSSL tools should not be

+ used in high-value, critical functions.

+ 

+ The OpenSSL server and client applications ([command]`openssl

+ s_client` and [command]`openssl s_server`)

+ are debugging tools and should *never* be

+ used as generic clients. For instance, the

+ [application]*s_client* tool reacts in a

+ surprising way to lines starting with `R` and

+ `Q`.

+ 

+ OpenSSL allows application code to access private key

+ material over documented interfaces. This can significantly

+ increase the part of the code base which has to undergo

+ security certification.

+ 

+ [[sect-Defensive_Coding-TLS-Pitfalls-GnuTLS]]

+ ===== GnuTLS Pitfalls

+ 

+ Older versions of GnuTLS had several peculiarities described

+ in previous versions of this guide; as of GnuTLS 3.3.10, these 

+ issues are no longer applicable.

+ 

+ [[sect-Defensive_Coding-TLS-Pitfalls-OpenJDK]]

+ ===== OpenJDK Pitfalls

+ 

+ The Java cryptographic framework is highly modular. As a

+ result, when you request an object implementing some

+ cryptographic functionality, you cannot be completely sure

+ that you end up with the well-tested, reviewed implementation

+ in OpenJDK.

+ 

+ OpenJDK (in the source code as published by Oracle) and other

+ implementations of the Java platform require that the system

+ administrator has installed so-called *unlimited

+ strength jurisdiction policy files*. Without this

+ step, it is not possible to use the secure algorithms which

+ offer sufficient cryptographic strength. Most downstream

+ redistributors of OpenJDK remove this requirement.

+ 

+ Some versions of OpenJDK use `/dev/random`

+ as the randomness source for nonces and other random data

+ which is needed for TLS operation, but does not actually

+ require physical randomness. As a result, TLS applications

+ can block, waiting for more bits to become available in

+ `/dev/random`.

+ 

+ [[sect-Defensive_Coding-TLS-Pitfalls-NSS]]

+ ===== NSS Pitfalls

+ 

+ NSS was not designed to be used by other libraries which can

+ be linked into applications without modifying them. There is

+ a lot of global state. There does not seem to be a way to

+ perform required NSS initialization without race conditions.

+ 

+ If the NSPR descriptor is in an unexpected state, the

+ `SSL_ForceHandshake` function can succeed,

+ but no TLS handshake takes place, the peer is not

+ authenticated, and subsequent data is exchanged in the clear.

+ 

+ NSS disables itself if it detects that the process underwent a

+ `fork` after the library has been

+ initialized. This behavior is required by the PKCS#11 API

+ specification.

+ 

+ [[sect-Defensive_Coding-TLS-Client]]

+ ==== TLS Clients

+ 

+ Secure use of TLS in a client generally involves all of the

+ following steps. (Individual instructions for specific TLS

+ implementations follow in the next sections.)

+ 

+ * The client must configure the TLS library to use a set of

+ trusted root certificates. These certificates are provided

+ by the system in various formats and files. These are documented in `update-ca-trust`

+ man page in Fedora. Portable applications should not hard-code

+ any paths; they should rely on APIs which set the default

+ for the system trust store.

+ 

+ * The client selects sufficiently strong cryptographic

+ primitives and disables insecure ones (such as no-op

+ encryption). Compression support and SSL version 3 or lower must be

+ disabled (including the SSLv2-compatible handshake).

+ 

+ * The client initiates the TLS connection. The Server Name

+ Indication extension should be used if supported by the

+ TLS implementation. Before switching to the encrypted

+ connection state, the contents of all input and output

+ buffers must be discarded.

+ 

+ * The client needs to validate the peer certificate provided

+ by the server, that is, the client must check that there

+ is a cryptographically protected chain from a trusted root

+ certificate to the peer certificate. (Depending on the

+ TLS implementation, a TLS handshake can succeed even if

+ the certificate cannot be validated.)

+ 

+ * The client must check that the configured or user-provided

+ server name matches the peer certificate provided by the

+ server.

+ 

+ It is safe to provide users detailed diagnostics on

+ certificate validation failures. Other causes of handshake

+ failures and, generally speaking, any details on other errors

+ reported by the TLS implementation (particularly exception

+ tracebacks), must not be divulged in ways that make them

+ accessible to potential attackers. Otherwise, it is possible

+ to create decryption oracles.

+ 

+ [IMPORTANT]

+ ====

+ 

+ Depending on the application, revocation checking (against

+ certificate revocations lists or via OCSP) and session

+ resumption are important aspects of production-quality

+ client. These aspects are not yet covered.

+ 

+ ====

+ 

+ ===== Implementation TLS Clients With OpenSSL

+ 

+ In the following code, the error handling is only exploratory.

+ Proper error handling is required for production use,

+ especially in libraries.

+ 

+ The OpenSSL library needs explicit initialization (see <<ex-Defensive_Coding-TLS-OpenSSL-Init>>).

+ 

+ [[ex-Defensive_Coding-TLS-OpenSSL-Init]]

+ .OpenSSL library initialization

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-OpenSSL-Init.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ After that, a context object has to be created, which acts as

+ a factory for connection objects (<<ex-Defensive_Coding-TLS-Client-OpenSSL-CTX>>). We

+ use an explicit cipher list so that we do not pick up any

+ strange ciphers when OpenSSL is upgraded. The actual version

+ requested in the client hello depends on additional

+ restrictions in the OpenSSL library. If possible, you should

+ follow the example code and use the default list of trusted

+ root certificate authorities provided by the system because

+ you would have to maintain your own set otherwise, which can

+ be cumbersome.

+ 

+ [[ex-Defensive_Coding-TLS-Client-OpenSSL-CTX]]

+ .OpenSSL client context creation

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-OpenSSL-CTX.adoc[]

+ ----

+ 

+ ====

+ 

+ A single context object can be used to create multiple

+ connection objects. It is safe to use the same

+ `SSL_CTX` object for creating connections

+ concurrently from multiple threads, provided that the

+ `SSL_CTX` object is not modified (e.g.,

+ callbacks must not be changed).

+ 

+ After creating the TCP socket and disabling the Nagle

+ algorithm (per <<ex-Defensive_Coding-TLS-Nagle>>), the actual

+ connection object needs to be created, as show in <<ex-Defensive_Coding-TLS-Client-OpenSSL-CTX>>. If

+ the handshake started by `SSL_connect`

+ fails, the `ssl_print_error_and_exit`

+ function from <<ex-Defensive_Coding-TLS-OpenSSL-Errors>> is called.

+ 

+ The `certificate_validity_override`

+ function provides an opportunity to override the validity of

+ the certificate in case the OpenSSL check fails. If such

+ functionality is not required, the call can be removed,

+ otherwise, the application developer has to implement it.

+ 

+ The host name passed to the functions

+ `SSL_set_tlsext_host_name` and

+ `X509_check_host` must be the name that was

+ passed to `getaddrinfo` or a similar name

+ resolution function. No host name canonicalization must be

+ performed. The `X509_check_host` function

+ used in the final step for host name matching is currently

+ only implemented in OpenSSL 1.1, which is not released yet.

+ In case host name matching fails, the function

+ `certificate_host_name_override` is called.

+ This function should check user-specific certificate store, to

+ allow a connection even if the host name does not match the

+ certificate. This function has to be provided by the

+ application developer. Note that the override must be keyed

+ by both the certificate *and* the host

+ name.

+ 

+ [[ex-Defensive_Coding-TLS-Client-OpenSSL-Connect]]

+ .Creating a client connection using OpenSSL

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-OpenSSL-Connect.adoc[]

+ ----

+ 

+ ====

+ 

+ The connection object can be used for sending and receiving

+ data, as in <<ex-Defensive_Coding-TLS-OpenSSL-Connection-Use>>.

+ It is also possible to create a `BIO` object

+ and use the `SSL` object as the underlying

+ transport, using `BIO_set_ssl`.

+ 

+ [[ex-Defensive_Coding-TLS-OpenSSL-Connection-Use]]

+ .Using an OpenSSL connection to send and receive data

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-OpenSSL-Connection-Use.adoc[]

+ ----

+ 

+ ====

+ 

+ When it is time to close the connection, the

+ `SSL_shutdown` function needs to be called

+ twice for an orderly, synchronous connection termination

+ (<<ex-Defensive_Coding-TLS-OpenSSL-Connection-Close>>).

+ This exchanges `close_notify` alerts with the

+ server. The additional logic is required to deal with an

+ unexpected `close_notify` from the server.

+ Note that is necessary to explicitly close the underlying

+ socket after the connection object has been freed.

+ 

+ [[ex-Defensive_Coding-TLS-OpenSSL-Connection-Close]]

+ .Closing an OpenSSL connection in an orderly fashion

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-OpenSSL-Connection-Close.adoc[]

+ ----

+ 

+ ====

+ 

+ <<ex-Defensive_Coding-TLS-OpenSSL-Context-Close>> shows how

+ to deallocate the context object when it is no longer needed

+ because no further TLS connections will be established.

+ 

+ [[ex-Defensive_Coding-TLS-OpenSSL-Context-Close]]

+ .Closing an OpenSSL connection in an orderly fashion

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-OpenSSL-Context-Close.adoc[]

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-TLS-Client-GnuTLS]]

+ ===== Implementation TLS Clients With GnuTLS

+ 

+ This section describes how to implement a TLS client with full

+ certificate validation (but without certificate revocation

+ checking). Note that the error handling in is only

+ exploratory and needs to be replaced before production use.

+ 

+ Before setting up TLS connections, a credentials objects has

+ to be allocated and initialized with the set of trusted root

+ CAs (<<ex-Defensive_Coding-TLS-Client-GNUTLS-Credentials>>).

+ 

+ [[ex-Defensive_Coding-TLS-Client-GNUTLS-Credentials]]

+ .Initializing a GnuTLS credentials structure

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-GNUTLS-Credentials.adoc[]

+ ----

+ 

+ ====

+ 

+ After the last TLS connection has been closed, this credentials

+ object should be freed:

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-GNUTLS-Credentials-Close.adoc[]

+ ----

+ 

+ During its lifetime, the credentials object can be used to

+ initialize TLS session objects from multiple threads, provided

+ that it is not changed.

+ 

+ Once the TCP connection has been established, the Nagle

+ algorithm should be disabled (see <<ex-Defensive_Coding-TLS-Nagle>>). After that, the

+ socket can be associated with a new GnuTLS session object.

+ The previously allocated credentials object provides the set

+ of root CAs. Then the TLS handshake must be initiated. 

+ This is shown in <<ex-Defensive_Coding-TLS-Client-GNUTLS-Connect>>.

+ 

+ [[ex-Defensive_Coding-TLS-Client-GNUTLS-Connect]]

+ .Establishing a TLS client connection using GnuTLS

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-GNUTLS-Connect.adoc[]

+ ----

+ 

+ ====

+ 

+ After the handshake has been completed, the server certificate

+ needs to be verified against the server's hostname (<<ex-Defensive_Coding-TLS-Client-GNUTLS-Verify>>). In

+ the example, the user-defined

+ `certificate_validity_override` function is

+ called if the verification fails, so that a separate,

+ user-specific trust store can be checked. This function call

+ can be omitted if the functionality is not needed.

+ 

+ [[ex-Defensive_Coding-TLS-Client-GNUTLS-Verify]]

+ .Verifying a server certificate using GnuTLS

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-GNUTLS-Verify.adoc[]

+ ----

+ 

+ ====

+ 

+ An established TLS session can be used for sending and

+ receiving data, as in <<ex-Defensive_Coding-TLS-GNUTLS-Use>>.

+ 

+ [[ex-Defensive_Coding-TLS-GNUTLS-Use]]

+ .Using a GnuTLS session

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-GNUTLS-Use.adoc[]

+ ----

+ 

+ ====

+ 

+ In order to shut down a connection in an orderly manner, you

+ should call the `gnutls_bye` function.

+ Finally, the session object can be deallocated using

+ `gnutls_deinit` (see <<ex-Defensive_Coding-TLS-GNUTLS-Disconnect>>).

+ 

+ [[ex-Defensive_Coding-TLS-GNUTLS-Disconnect]]

+ .Closing a GnuTLS session in an orderly fashion

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-GNUTLS-Disconnect.adoc[]

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-TLS-Client-OpenJDK]]

+ ===== Implementing TLS Clients With OpenJDK

+ 

+ The examples below use the following cryptographic-related

+ classes:

+ 

+ [source,java]

+ ----

+ include::snippets/Features-TLS-Client-OpenJDK-Import.adoc[]

+ 		    

+ ----

+ 

+ If compatibility with OpenJDK 6 is required, it is necessary

+ to use the internal class

+ `sun.security.util.HostnameChecker`. (The

+ public OpenJDK API does not provide any support for dissecting

+ the subject distinguished name of an X.509 certificate, so a

+ custom-written DER parser is needed—or we have to use an

+ internal class, which we do below.) In OpenJDK 7, the

+ `setEndpointIdentificationAlgorithm` method

+ was added to the

+ `javax.net.ssl.SSLParameters` class,

+ providing an official way to implement host name checking.

+ 

+ TLS connections are established using an

+ `SSLContext` instance. With a properly

+ configured OpenJDK installation, the

+ `SunJSSE` provider uses the system-wide set

+ of trusted root certificate authorities, so no further

+ configuration is necessary. For backwards compatibility with

+ OpenJDK{nbsp}6, the `TLSv1` provider has to

+ be supported as a fall-back option. This is shown in <<ex-Defensive_Coding-TLS-Client-OpenJDK-Context>>.

+ 

+ [[ex-Defensive_Coding-TLS-Client-OpenJDK-Context]]

+ .Setting up an `SSLContext` for OpenJDK TLS	clients

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Features-TLS-Client-OpenJDK-Context.adoc[]

+ ----

+ 

+ ====

+ 

+ In addition to the context, a TLS parameter object will be

+ needed which adjusts the cipher suites and protocols (<<ex-Defensive_Coding-TLS-OpenJDK-Parameters>>). Like

+ the context, these parameters can be reused for multiple TLS

+ connections.

+ 

+ [[ex-Defensive_Coding-TLS-OpenJDK-Parameters]]

+ .Setting up `SSLParameters` for TLS use	with OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Features-TLS-OpenJDK-Parameters.adoc[]

+ ----

+ 

+ ====

+ 

+ As initialized above, the parameter object does not yet

+ require host name checking. This has to be enabled

+ separately, and this is only supported by OpenJDK 7 and later:

+ 

+ [source,java]

+ ----

+ include::snippets/Features-TLS-Client-OpenJDK-Hostname.adoc[]

+ ----

+ 

+ All application protocols can use the

+ `"HTTPS"` algorithm. (The algorithms have

+ minor differences with regard to wildcard handling, which

+ should not matter in practice.)

+ 

+ <<ex-Defensive_Coding-TLS-Client-OpenJDK-Connect>>

+ shows how to establish the connection. Before the handshake

+ is initialized, the protocol and cipher configuration has to

+ be performed, by applying the parameter object

+ `params`. (After this point, changes to

+ `params` will not affect this TLS socket.)

+ As mentioned initially, host name checking requires using an

+ internal API on OpenJDK 6.

+ 

+ [[ex-Defensive_Coding-TLS-Client-OpenJDK-Connect]]

+ .Establishing a TLS connection with OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Features-TLS-Client-OpenJDK-Connect.adoc[]

+ ----

+ 

+ ====

+ 

+ Starting with OpenJDK 7, the last lines can be omitted,

+ provided that host name verification has been enabled by

+ calling the

+ `setEndpointIdentificationAlgorithm` method

+ on the `params` object (before it was applied

+ to the socket).

+ 

+ The TLS socket can be used as a regular socket, as shown in

+ <<ex-Defensive_Coding-TLS-Client-OpenJDK-Use>>.

+ 

+ [[ex-Defensive_Coding-TLS-Client-OpenJDK-Use]]

+ .Using a TLS client socket in OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Features-TLS-Client-OpenJDK-Use.adoc[]

+ ----

+ 

+ ====

+ 

+ ====== Overriding server certificate validation with OpenJDK 6

+ 

+ Overriding certificate validation requires a custom trust

+ manager. With OpenJDK 6, the trust manager lacks

+ information about the TLS session, and to which server the

+ connection is made. Certificate overrides have to be tied

+ to specific servers (host names). Consequently, different

+ `TrustManager` and

+ `SSLContext` objects have to be used for

+ different servers.

+ 

+ In the trust manager shown in <<ex-Defensive_Coding-TLS-Client-MyTrustManager>>,

+ the server certificate is identified by its SHA-256 hash.

+ 

+ [[ex-Defensive_Coding-TLS-Client-MyTrustManager]]

+ .A customer trust manager for OpenJDK TLS clients

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Features-TLS-Client-OpenJDK-MyTrustManager.adoc[]

+ ----

+ 

+ ====

+ 

+ This trust manager has to be passed to the

+ `init` method of the

+ `SSLContext` object, as show in <<ex-Defensive_Coding-TLS-Client-Context_For_Cert>>.

+ 

+ [[ex-Defensive_Coding-TLS-Client-Context_For_Cert]]

+ .Using a custom TLS trust manager with OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Features-TLS-Client-OpenJDK-Context_For_Cert.adoc[]

+ ----

+ 

+ ====

+ 

+ When certificate overrides are in place, host name

+ verification should not be performed because there is no

+ security requirement that the host name in the certificate

+ matches the host name used to establish the connection (and

+ it often will not). However, without host name

+ verification, it is not possible to perform transparent

+ fallback to certification validation using the system

+ certificate store.

+ 

+ The approach described above works with OpenJDK 6 and later

+ versions. Starting with OpenJDK 7, it is possible to use a

+ custom subclass of the

+ `javax.net.ssl.X509ExtendedTrustManager`

+ class. The OpenJDK TLS implementation will call the new

+ methods, passing along TLS session information. This can be

+ used to implement certificate overrides as a fallback (if

+ certificate or host name verification fails), and a trust

+ manager object can be used for multiple servers because the

+ server address is available to the trust manager.

+ 

+ [[sect-Defensive_Coding-TLS-Client-NSS]]

+ ===== Implementing TLS Clients With NSS

+ 

+ The following code shows how to implement a simple TLS client

+ using NSS. These instructions apply to NSS version 3.14 and

+ later. Versions before 3.14 need different initialization

+ code.

+ 

+ Keep in mind that the error handling needs to be improved

+ before the code can be used in production.

+ 

+ Using NSS needs several header files, as shown in 

+ <<ex-Defensive_Coding-TLS-NSS-Includes>>.

+ 

+ [[ex-Defensive_Coding-TLS-NSS-Includes]]

+ .Include files for NSS

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-NSS-Includes.adoc[]

+ ----

+ 

+ ====

+ 

+ Initializing the NSS library is shown in <<ex-Defensive_Coding-TLS-NSS-Init>>. This

+ initialization procedure overrides global state. We only call

+ `NSS_SetDomesticPolicy` if there are no

+ strong ciphers available, assuming that it has already been

+ called otherwise. This avoids overriding the process-wide

+ cipher suite policy unnecessarily.

+ 

+ The simplest way to configured the trusted root certificates

+ involves loading the `libnssckbi.so` NSS

+ module with a call to the

+ `SECMOD_LoadUserModule` function. The root

+ certificates are compiled into this module. (The PEM module

+ for NSS, `libnsspem.so`, offers a way to

+ load trusted CA certificates from a file.)

+ 

+ [[ex-Defensive_Coding-TLS-NSS-Init]]

+ .Initializing the NSS library

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-NSS-Init.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ Some of the effects of the initialization can be reverted with

+ the following function calls:

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-NSS-Close.adoc[]

+ ----

+ 

+ After NSS has been initialized, the TLS connection can be

+ created (<<ex-Defensive_Coding-TLS-Client-NSS-Connect>>). The

+ internal `PR_ImportTCPSocket` function is

+ used to turn the POSIX file descriptor

+ `sockfd` into an NSPR file descriptor. (This

+ function is de-facto part of the NSS public ABI, so it will

+ not go away.) Creating the TLS-capable file descriptor

+ requires a *model* descriptor, which is

+ configured with the desired set of protocols. The model

+ descriptor is not needed anymore after TLS support has been

+ activated for the existing connection descriptor.

+ 

+ The call to `SSL_BadCertHook` can be

+ omitted if no mechanism to override certificate verification

+ is needed. The `bad_certificate` function

+ must check both the host name specified for the connection and

+ the certificate before granting the override.

+ 

+ Triggering the actual handshake requires three function calls,

+ `SSL_ResetHandshake`,

+ `SSL_SetURL`, and

+ `SSL_ForceHandshake`. (If

+ `SSL_ResetHandshake` is omitted,

+ `SSL_ForceHandshake` will succeed, but the

+ data will not be encrypted.) During the handshake, the

+ certificate is verified and matched against the host name.

+ 

+ [[ex-Defensive_Coding-TLS-Client-NSS-Connect]]

+ .Creating a TLS connection with NSS

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-NSS-Connect.adoc[]

+ ----

+ 

+ ====

+ 

+ After the connection has been established, <<ex-Defensive_Coding-TLS-NSS-Use>> shows how to use

+ the NSPR descriptor to communicate with the server.

+ 

+ [[ex-Defensive_Coding-TLS-NSS-Use]]

+ .Using NSS for sending and receiving data

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-NSS-Use.adoc[]

+ ----

+ 

+ ====

+ 

+ <<ex-Defensive_Coding-TLS-Client-NSS-Close>>

+ shows how to close the connection.

+ 

+ [[ex-Defensive_Coding-TLS-Client-NSS-Close]]

+ .Closing NSS client connections

+ ====

+ 

+ [source,c]

+ ----

+ include::snippets/Features-TLS-Client-NSS-Close.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-TLS-Client-Python]]

+ ===== Implementing TLS Clients With Python

+ 

+ The Python distribution provides a TLS implementation in the

+ `ssl` module (actually a wrapper around

+ OpenSSL). The exported interface is somewhat restricted, so

+ that the client code shown below does not fully implement the

+ recommendations in <<sect-Defensive_Coding-TLS-OpenSSL>>.

+ 

+ [IMPORTANT]

+ ====

+ 

+ Currently, most Python function which accept

+ `https://` URLs or otherwise implement

+ HTTPS support do not perform certificate validation at all.

+ (For example, this is true for the `httplib`

+ and `xmlrpclib` modules.) If you use

+ HTTPS, you should not use the built-in HTTP clients. The

+ `Curl` class in the `curl`

+ module, as provided by the `python-pycurl`

+ package implements proper certificate validation.

+ 

+ ====

+ 

+ The `ssl` module currently does not perform

+ host name checking on the server certificate. <<ex-Defensive_Coding-TLS-Client-Python-check_host_name>>

+ shows how to implement certificate matching, using the parsed

+ certificate returned by `getpeercert`.

+ 

+ [[ex-Defensive_Coding-TLS-Client-Python-check_host_name]]

+ .Implementing TLS host name checking Python (without wildcard support)

+ ====

+ 

+ [source,python]

+ ----

+ include::snippets/Features-TLS-Client-Python-check_host_name.adoc[]

+ ----

+ 

+ ====

+ 

+ To turn a regular, connected TCP socket into a TLS-enabled

+ socket, use the `ssl.wrap_socket` function.

+ The function call in <<ex-Defensive_Coding-TLS-Client-Python-Connect>>

+ provides additional arguments to override questionable

+ defaults in OpenSSL and in the Python module.

+ 

+ * `ciphers="HIGH:-aNULL:-eNULL:-PSK:RC4-SHA:RC4-MD5"`

+ selects relatively strong cipher suites with

+ certificate-based authentication. (The call to

+ `check_host_name` function provides 

+ additional protection against anonymous cipher suites.)

+ 

+ * `ssl_version=ssl.PROTOCOL_TLSv1` disables

+ SSL 2.0 support. By default, the `ssl`

+ module sends an SSL 2.0 client hello, which is rejected by

+ some servers. Ideally, we would request OpenSSL to

+ negotiated the most recent TLS version supported by the

+ server and the client, but the Python module does not

+ allow this.

+ 

+ * `cert_reqs=ssl.CERT_REQUIRED` turns on

+ certificate validation.

+ 

+ * `ca_certs='/etc/ssl/certs/ca-bundle.crt'`

+ initializes the certificate store with a set of trusted

+ root CAs. Unfortunately, it is necessary to hard-code

+ this path into applications because the default path in

+ OpenSSL is not available through the Python

+ `ssl` module.

+ 

+ The `ssl` module (and OpenSSL) perform

+ certificate validation, but the certificate must be compared

+ manually against the host name, by calling the

+ `check_host_name` defined above.

+ 

+ [[ex-Defensive_Coding-TLS-Client-Python-Connect]]

+ .Establishing a TLS client connection with Python

+ ====

+ 

+ [source,python]

+ ----

+ include::snippets/Features-TLS-Client-Python-Connect.adoc[]

+ ----

+ 

+ ====

+ 

+ After the connection has been established, the TLS socket can

+ be used like a regular socket:

+ 

+ [source,python]

+ ----

+ include::snippets/Features-TLS-Python-Use.adoc[]

+ ----

+ 

+ Closing the TLS socket is straightforward as well:

+ 

+ [source,python]

+ ----

+ include::snippets/Features-TLS-Python-Close.adoc[]

+ ----

en-US/Features-TLS.xml
file removed
-1013
@@ -1,1013 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-TLS">

-   <title>Transport Layer Security</title>

-   <para>

-     Transport Layer Security (TLS, formerly Secure Sockets

-     Layer/SSL) is the recommended way to to protect integrity and

-     confidentiality while data is transferred over an untrusted

-     network connection, and to identify the endpoint.

-   </para>

-   <section id="sect-Defensive_Coding-TLS-Pitfalls">

-     <title>Common Pitfalls</title>

-     <para>

-       TLS implementations are difficult to use, and most of them lack

-       a clean API design.  The following sections contain

-       implementation-specific advice, and some generic pitfalls are

-       mentioned below.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Most TLS implementations have questionable default TLS

- 	  cipher suites.  Most of them enable anonymous Diffie-Hellman

- 	  key exchange (but we generally want servers to authenticate

- 	  themselves).  Many do not disable ciphers which are subject

- 	  to brute-force attacks because of restricted key lengths.

- 	  Some even disable all variants of AES in the default

- 	  configuration.

- 	</para>

- 	<para>

- 	  When overriding the cipher suite defaults, it is recommended

- 	  to disable all cipher suites which are not present on a

- 	  whitelist, instead of simply enabling a list of cipher

- 	  suites.  This way, if an algorithm is disabled by default in

- 	  the TLS implementation in a future security update, the

- 	  application will not re-enable it.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The name which is used in certificate validation must match

- 	  the name provided by the user or configuration file.  No host

- 	  name canonicalization or IP address lookup must be performed.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The TLS handshake has very poor performance if the TCP Nagle

- 	  algorithm is active.  You should switch on the

- 	  <literal>TCP_NODELAY</literal> socket option (at least for the

- 	  duration of the handshake), or use the Linux-specific

- 	  <literal>TCP_CORK</literal> option.

- 	</para>

- 	<example id="ex-Defensive_Coding-TLS-Nagle">

- 	  <title>Deactivating the TCP Nagle algorithm</title>

- 	  <xi:include href="snippets/Features-TLS-Nagle.xml"

- 		      xmlns:xi="http://www.w3.org/2001/XInclude" />

- 	</example>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Implementing proper session resumption decreases handshake

- 	  overhead considerably.  This is important if the upper-layer

- 	  protocol uses short-lived connections (like most application

- 	  of HTTPS).

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Both client and server should work towards an orderly

- 	  connection shutdown, that is send

- 	  <literal>close_notify</literal> alerts and respond to them.

- 	  This is especially important if the upper-layer protocol

- 	  does not provide means to detect connection truncation (like

- 	  some uses of HTTP).

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  When implementing a server using event-driven programming,

- 	  it is important to handle the TLS handshake properly because

- 	  it includes multiple network round-trips which can block

- 	  when an ordinary TCP <function>accept</function> would not.

- 	  Otherwise, a client which fails to complete the TLS

- 	  handshake for some reason will prevent the server from

- 	  handling input from other clients.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Unlike regular file descriptors, TLS connections cannot be

- 	  passed between processes.  Some TLS implementations add

- 	  additional restrictions, and TLS connections generally

- 	  cannot be used across <function>fork</function> function

- 	  calls (see <xref

- 	  linkend="sect-Defensive_Coding-Tasks-Processes-Fork-Parallel"/>).

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <section id="sect-Defensive_Coding-TLS-OpenSSL">

-       <title>OpenSSL Pitfalls</title>

-       <para>

- 	Some OpenSSL function use <emphasis>tri-state return

- 	values</emphasis>.  Correct error checking is extremely

- 	important.  Several functions return <literal>int</literal>

- 	values with the following meaning:

-       </para>

-       <itemizedlist>

- 	<listitem>

- 	  <para>

- 	    The value <literal>1</literal> indicates success (for

- 	    example, a successful signature verification).

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The value <literal>0</literal> indicates semantic

- 	    failure (for example, a signature verification which was

- 	    unsuccessful because the signing certificate was

- 	    self-signed).

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The value <literal>-1</literal> indicates a low-level

- 	    error in the system, such as failure to allocate memory

- 	    using <function>malloc</function>.

- 	  </para>

- 	</listitem>

-       </itemizedlist>

-       <para>

- 	Treating such tri-state return values as booleans can lead

- 	to security vulnerabilities.  Note that some OpenSSL

- 	functions return boolean results or yet another set of

- 	status indicators.  Each function needs to be checked

- 	individually.

-       </para>

-       <para>

- 	Recovering precise error information is difficult.

- 	<xref linkend="ex-Defensive_Coding-TLS-OpenSSL-Errors"/>

- 	shows how to obtain a more precise error code after a function

- 	call on an <literal>SSL</literal> object has failed.  However,

- 	there are still cases where no detailed error information is

- 	available (e.g., if <function>SSL_shutdown</function> fails

- 	due to a connection teardown by the other end).

-       </para>

-       <example id="ex-Defensive_Coding-TLS-OpenSSL-Errors">

- 	<title>Obtaining OpenSSL error codes</title>

- 	<xi:include href="snippets/Features-TLS-OpenSSL-Errors.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	The <function>OPENSSL_config</function> function is

- 	documented to never fail.  In reality, it can terminate the

- 	entire process if there is a failure accessing the

- 	configuration file.  An error message is written to standard

- 	error, but which might not be visible if the function is

- 	called from a daemon process.

-       </para>

-       <para>

- 	OpenSSL contains two separate ASN.1 DER decoders.  One set

- 	of decoders operate on BIO handles (the input/output stream

- 	abstraction provided by OpenSSL); their decoder function

- 	names start with <literal>d2i_</literal> and end in

- 	<literal>_fp</literal> or <literal>_bio</literal> (e.g.,

- 	<function>d2i_X509_fp</function> or

- 	<function>d2i_X509_bio</function>).  These decoders must not

- 	be used for parsing data from untrusted sources; instead,

- 	the variants without the <literal>_fp</literal> and

- 	<literal>_bio</literal> (e.g.,

- 	<function>d2i_X509</function>) shall be used.  The BIO

- 	variants have received considerably less testing and are not

- 	very robust.

-       </para>

-       <para>

- 	For the same reason, the OpenSSL command line tools (such as

- 	<command>openssl x509</command>) are generally generally less

- 	robust than the actual library code.  They use the BIO

- 	functions internally, and not the more robust variants.

-       </para>

-       <para>

- 	The command line tools do not always indicate failure in the

- 	exit status of the <application>openssl</application> process.

- 	For instance, a verification failure in <command>openssl

- 	verify</command> result in an exit status of zero.

-       </para>

-       <para>

- 	OpenSSL command-line commands, such as <command>openssl

- 	genrsa</command>, do not ensure that physical entropy is used

- 	for key generation—they obtain entropy from

- 	<filename>/dev/urandom</filename> and other sources, but not

- 	from <filename>/dev/random</filename>.  This can result in

- 	weak keys if the system lacks a proper entropy source (e.g., a

- 	virtual machine with solid state storage).  Depending on local

- 	policies, keys generated by these OpenSSL tools should not be

- 	used in high-value, critical functions.

-       </para>

-       <para>

- 	The OpenSSL server and client applications (<command>openssl

- 	s_client</command> and <command>openssl s_server</command>)

- 	are debugging tools and should <emphasis>never</emphasis> be

- 	used as generic clients.  For instance, the

- 	<application>s_client</application> tool reacts in a

- 	surprisign way to lines starting with <literal>R</literal> and

- 	<literal>Q</literal>.

-       </para>

-       <para>

- 	OpenSSL allows application code to access private key

- 	material over documented interfaces.  This can significantly

- 	increase the part of the code base which has to undergo

- 	security certification.

-       </para>

-     </section>

-     <section id="sect-Defensive_Coding-TLS-Pitfalls-GNUTLS">

-       <title>GNUTLS Pitfalls</title>

-       <para>

- 	Older versions of GNUTLS had several peculiarities.  As of

- 	GNUTLS 3.3.10, they have been addressed, so these are only a

- 	concern for applications which have to run with older GNUTLS

- 	versions.

-       </para>

-       <itemizedlist>

- 	<listitem>

- 	  <para>

- 	    The dynamic shared object provided by GNTULS links to

- 	    <filename>libpthread.so.0</filename>.  Loading the

- 	    threading library too late causes problems, so the main

- 	    program should be linked with <literal>-lpthread</literal>

- 	    as well.  As a result, it can be difficult to use GNUTLS

- 	    in a plugin which is loaded with the

- 	    <function>dlopen</function> function.  Another side effect

- 	    is that applications which merely link against GNUTLS

- 	    (even without actually using it) may incur a substantial

- 	    overhead because other libraries automatically switch to

- 	    thread-safe algorithms.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The <function>gnutls_global_init</function> function must

- 	    be called before using any functionality provided by the

- 	    library.  This function is not thread-safe, so external

- 	    locking is required, but it is not clear which lock should

- 	    be used.  Omitting the synchronization does not just lead

- 	    to a memory leak, as it is suggested in the GNUTLS

- 	    documentation, but to undefined behavior because there is

- 	    no barrier that would enforce memory ordering.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The <function>gnutls_global_deinit</function> function

- 	    does not actually deallocate all resources allocated by

- 	    <function>gnutls_global_init</function>.  It is currently

- 	    not thread-safe.  Therefore, it is best to avoid calling

- 	    it altogether.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The X.509 implementation in GNUTLS is rather lenient.  For

- 	    example, it is possible to create and process X.509

- 	    version&nbsp;1 certificates which carry extensions.  These

- 	    certificates are (correctly) rejected by other

- 	    implementations.

- 	  </para>

- 	</listitem>

-       </itemizedlist>

-     </section>

-     <section id="sect-Defensive_Coding-TLS-Pitfalls-OpenJDK">

-       <title>OpenJDK Pitfalls</title>

-       <para>

- 	The Java cryptographic framework is highly modular.  As a

- 	result, when you request an object implementing some

- 	cryptographic functionality, you cannot be completely sure

- 	that you end up with the well-tested, reviewed implementation

- 	in OpenJDK.

-       </para>

-       <para>

- 	OpenJDK (in the source code as published by Oracle) and other

- 	implementations of the Java platform require that the system

- 	administrator has installed so-called <emphasis>unlimited

- 	strength jurisdiction policy files</emphasis>.  Without this

- 	step, it is not possible to use the secure algorithms which

- 	offer sufficient cryptographic strength.  Most downstream

- 	redistributors of OpenJDK remove this requirement.

-       </para>

-       <para>

- 	Some versions of OpenJDK use <filename>/dev/random</filename>

- 	as the randomness source for nonces and other random data

- 	which is needed for TLS operation, but does not actually

- 	require physical randomness.  As a result, TLS applications

- 	can block, waiting for more bits to become available in

- 	<filename>/dev/random</filename>.

-       </para>

-     </section>

-     <section id="sect-Defensive_Coding-TLS-Pitfalls-NSS">

-       <title>NSS Pitfalls</title>

-       <para>

- 	NSS was not designed to be used by other libraries which can

- 	be linked into applications without modifying them.  There is

- 	a lot of global state.  There does not seem to be a way to

- 	perform required NSS initialization without race conditions.

-       </para>

-       <para>

- 	If the NSPR descriptor is in an unexpected state, the

- 	<function>SSL_ForceHandshake</function> function can succeed,

- 	but no TLS handshake takes place, the peer is not

- 	authenticated, and subsequent data is exchanged in the clear.

-       </para>

-       <para>

- 	NSS disables itself if it detects that the process underwent a

- 	<function>fork</function> after the library has been

- 	initialized.  This behavior is required by the PKCS#11 API

- 	specification.

-       </para>

-     </section>

-   </section>

-   <section id="sect-Defensive_Coding-TLS-Client">

-     <title>TLS Clients</title>

-     <para>

-       Secure use of TLS in a client generally involves all of the

-       following steps.  (Individual instructions for specific TLS

-       implementations follow in the next sections.)

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  The client must configure the TLS library to use a set of

- 	  trusted root certificates.  These certificates are provided

- 	  by the system in <filename

- 	  class="directory">/etc/ssl/certs</filename> or files derived

- 	  from it.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The client selects sufficiently strong cryptographic

- 	  primitives and disables insecure ones (such as no-op

- 	  encryption). Compression and SSL version 2 support must be

- 	  disabled (including the SSLv2-compatible handshake).

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The client initiates the TLS connection.  The Server Name

- 	  Indication extension should be used if supported by the

- 	  TLS implementation.  Before switching to the encrypted

- 	  connection state, the contents of all input and output

- 	  buffers must be discarded.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The client needs to validate the peer certificate provided

- 	  by the server, that is, the client must check that there

- 	  is a cryptographically protected chain from a trusted root

- 	  certificate to the peer certificate.  (Depending on the

- 	  TLS implementation, a TLS handshake can succeed even if

- 	  the certificate cannot be validated.)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The client must check that the configured or user-provided

- 	  server name matches the peer certificate provided by the

- 	  server.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       It is safe to provide users detailed diagnostics on

-       certificate validation failures.  Other causes of handshake

-       failures and, generally speaking, any details on other errors

-       reported by the TLS implementation (particularly exception

-       tracebacks), must not be divulged in ways that make them

-       accessible to potential attackers.  Otherwise, it is possible

-       to create decryption oracles.

-     </para>

-       <important>

- 	<para>

- 	  Depending on the application, revocation checking (against

- 	  certificate revocations lists or via OCSP) and session

- 	  resumption are important aspects of production-quality

- 	  client.  These aspects are not yet covered.

- 	</para>

-       </important>

-     <section>

-       <title>Implementation TLS Clients With OpenSSL</title>

-       <para>

- 	In the following code, the error handling is only exploratory.

- 	Proper error handling is required for production use,

- 	especially in libraries.

- 	<!-- FIXME: Cross-reference event-driven I/O section when it

- 	     exists and mention that this is really quite complex to

- 	     implement.  -->

-       </para>

-       <para>

- 	The OpenSSL library needs explicit initialization (see <xref

- 	linkend="ex-Defensive_Coding-TLS-OpenSSL-Init"/>).

-       </para>

-       <example id="ex-Defensive_Coding-TLS-OpenSSL-Init">

- 	<title>OpenSSL library initialization</title>

- 	<xi:include href="snippets/Features-TLS-Client-OpenSSL-Init.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	After that, a context object has to be created, which acts as

- 	a factory for connection objects (<xref

- 	linkend="ex-Defensive_Coding-TLS-Client-OpenSSL-CTX"/>).  We

- 	use an explicit cipher list so that we do not pick up any

- 	strange ciphers when OpenSSL is upgraded.  The actual version

- 	requested in the client hello depends on additional

- 	restrictions in the OpenSSL library.  If possible, you should

- 	follow the example code and use the default list of trusted

- 	root certificate authorities provided by the system because

- 	you would have to maintain your own set otherwise, which can

- 	be cumbersome.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-OpenSSL-CTX">

- 	<title>OpenSSL client context creation</title>

- 	<xi:include href="snippets/Features-TLS-Client-OpenSSL-CTX.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	A single context object can be used to create multiple

- 	connection objects.  It is safe to use the same

- 	<literal>SSL_CTX</literal> object for creating connections

- 	concurrently from multiple threads, provided that the

- 	<literal>SSL_CTX</literal> object is not modified (e.g.,

- 	callbacks must not be changed).

-       </para>

-       <para>

- 	After creating the TCP socket and disabling the Nagle

- 	algorithm (per <xref

- 	linkend="ex-Defensive_Coding-TLS-Nagle"/>), the actual

- 	connection object needs to be created, as show in <xref

- 	linkend="ex-Defensive_Coding-TLS-Client-OpenSSL-CTX"/>.  If

- 	the handshake started by <function>SSL_connect</function>

- 	fails, the <function>ssl_print_error_and_exit</function>

- 	function from <xref

- 	linkend="ex-Defensive_Coding-TLS-OpenSSL-Errors"/> is called.

-       </para>

-       <para>

- 	The <function>certificate_validity_override</function>

- 	function provides an opportunity to override the validity of

- 	the certificate in case the OpenSSL check fails.  If such

- 	functionality is not required, the call can be removed,

- 	otherwise, the application developer has to implement it.

-       </para>

-       <para>

- 	The host name passed to the functions

- 	<function>SSL_set_tlsext_host_name</function> and

- 	<function>X509_check_host</function> must be the name that was

- 	passed to <function>getaddrinfo</function> or a similar name

- 	resolution function.  No host name canonicalization must be

- 	performed.  The <function>X509_check_host</function> function

- 	used in the final step for host name matching is currently

- 	only implemented in OpenSSL 1.1, which is not released yet.

- 	In case host name matching fails, the function

- 	<function>certificate_host_name_override</function> is called.

- 	This function should check user-specific certificate store, to

- 	allow a connection even if the host name does not match the

- 	certificate.  This function has to be provided by the

- 	application developer.  Note that the override must be keyed

- 	by both the certificate <emphasis>and</emphasis> the host

- 	name.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-OpenSSL-Connect">

- 	<title>Creating a client connection using OpenSSL</title>

- 	<xi:include href="snippets/Features-TLS-Client-OpenSSL-Connect.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	The connection object can be used for sending and receiving

- 	data, as in <xref

- 	linkend="ex-Defensive_Coding-TLS-OpenSSL-Connection-Use"/>.

- 	It is also possible to create a <literal>BIO</literal> object

- 	and use the <literal>SSL</literal> object as the underlying

- 	transport, using <function>BIO_set_ssl</function>.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-OpenSSL-Connection-Use">

- 	<title>Using an OpenSSL connection to send and receive data</title>

- 	<xi:include href="snippets/Features-TLS-Client-OpenSSL-Connection-Use.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	When it is time to close the connection, the

- 	<function>SSL_shutdown</function> function needs to be called

- 	twice for an orderly, synchronous connection termination

- 	(<xref

- 	linkend="ex-Defensive_Coding-TLS-OpenSSL-Connection-Close"/>).

- 	This exchanges <literal>close_notify</literal> alerts with the

- 	server.  The additional logic is required to deal with an

- 	unexpected <literal>close_notify</literal> from the server.

- 	Note that is necessary to explicitly close the underlying

- 	socket after the connection object has been freed.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-OpenSSL-Connection-Close">

- 	<title>Closing an OpenSSL connection in an orderly fashion</title>

- 	<xi:include href="snippets/Features-TLS-OpenSSL-Connection-Close.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	<xref linkend="ex-Defensive_Coding-TLS-OpenSSL-Context-Close"/> shows how

- 	to deallocate the context object when it is no longer needed

- 	because no further TLS connections will be established.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-OpenSSL-Context-Close">

- 	<title>Closing an OpenSSL connection in an orderly fashion</title>

- 	<xi:include href="snippets/Features-TLS-OpenSSL-Context-Close.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-     </section>

-     <section id="sect-Defensive_Coding-TLS-Client-GNUTLS">

-       <title>Implementation TLS Clients With GNUTLS</title>

-       <para>

- 	This section describes how to implement a TLS client with full

- 	certificate validation (but without certificate revocation

- 	checking).  Note that the error handling in is only

- 	exploratory and needs to be replaced before production use.

-       </para>

-       <para>

- 	The GNUTLS library needs explicit initialization:

-       </para>

-       <informalexample id="ex-Defensive_Coding-TLS-GNUTLS-Init">

- 	<xi:include href="snippets/Features-TLS-GNUTLS-Init.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	Failing to do so can result in obscure failures in Base64

- 	decoding.  See <xref

- 	linkend="sect-Defensive_Coding-TLS-Pitfalls-GNUTLS"/> for

- 	additional aspects of initialization.

-       </para>

-       <para>

- 	Before setting up TLS connections, a credentials objects has

- 	to be allocated and initialized with the set of trusted root

- 	CAs (<xref

- 	linkend="ex-Defensive_Coding-TLS-Client-GNUTLS-Credentials"/>).

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-GNUTLS-Credentials">

- 	<title>Initializing a GNUTLS credentials structure</title>

- 	<xi:include href="snippets/Features-TLS-Client-GNUTLS-Credentials.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	After the last TLS connection has been closed, this credentials

- 	object should be freed:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/Features-TLS-GNUTLS-Credentials-Close.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	During its lifetime, the credentials object can be used to

- 	initialize TLS session objects from multiple threads, provided

- 	that it is not changed.

-       </para>

-       <para>

- 	Once the TCP connection has been established, the Nagle

- 	algorithm should be disabled (see <xref

- 	linkend="ex-Defensive_Coding-TLS-Nagle"/>).  After that, the

- 	socket can be associated with a new GNUTLS session object.

- 	The previously allocated credentials object provides the set

- 	of root CAs.  The <literal>NORMAL</literal> set of cipher

- 	suites and protocols provides a reasonable default. Then the

- 	TLS handshake must be initiated.  This is shown in <xref

- 	linkend="ex-Defensive_Coding-TLS-Client-GNUTLS-Connect"/>.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-GNUTLS-Connect">

- 	<title>Establishing a TLS client connection using GNUTLS</title>

- 	<xi:include href="snippets/Features-TLS-Client-GNUTLS-Connect.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	After the handshake has been completed, the server certificate

- 	needs to be verified (<xref

- 	linkend="ex-Defensive_Coding-TLS-Client-GNUTLS-Verify"/>).  In

- 	the example, the user-defined

- 	<function>certificate_validity_override</function> function is

- 	called if the verification fails, so that a separate,

- 	user-specific trust store can be checked.  This function call

- 	can be omitted if the functionality is not needed.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-GNUTLS-Verify">

- 	<title>Verifying a server certificate using GNUTLS</title>

- 	<xi:include href="snippets/Features-TLS-Client-GNUTLS-Verify.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	In the next step (<xref

- 	linkend="ex-Defensive_Coding-TLS-Client-GNUTLS-Match"/>, the

- 	certificate must be matched against the host name (note the

- 	unusual return value from

- 	<function>gnutls_x509_crt_check_hostname</function>).  Again,

- 	an override function

- 	<function>certificate_host_name_override</function> is called.

- 	Note that the override must be keyed to the certificate

- 	<emphasis>and</emphasis> the host name.  The function call can

- 	be omitted if the override is not needed.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-GNUTLS-Match">

- 	<title>Matching the server host name and certificate in a

- 	GNUTLS client</title>

- 	<xi:include href="snippets/Features-TLS-Client-GNUTLS-Match.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	In newer GNUTLS versions, certificate checking and host name

- 	validation can be combined using the

- 	<function>gnutls_certificate_verify_peers3</function> function.

-       </para>

-       <para>

- 	An established TLS session can be used for sending and

- 	receiving data, as in <xref

- 	linkend="ex-Defensive_Coding-TLS-GNUTLS-Use"/>.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-GNUTLS-Use">

- 	<title>Using a GNUTLS session</title>

- 	<xi:include href="snippets/Features-TLS-GNUTLS-Use.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	In order to shut down a connection in an orderly manner, you

- 	should call the <function>gnutls_bye</function> function.

- 	Finally, the session object can be deallocated using

- 	<function>gnutls_deinit</function> (see <xref

- 	linkend="ex-Defensive_Coding-TLS-GNUTLS-Disconnect"/>).

-       </para>

-       <example id="ex-Defensive_Coding-TLS-GNUTLS-Disconnect">

- 	<title>Using a GNUTLS session</title>

- 	<xi:include href="snippets/Features-TLS-GNUTLS-Disconnect.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-     </section>

-     <section id="sect-Defensive_Coding-TLS-Client-OpenJDK">

-       <title>Implementing TLS Clients With OpenJDK</title>

-       <para>

- 	The examples below use the following cryptographic-related

- 	classes:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/Features-TLS-Client-OpenJDK-Import.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	If compatibility with OpenJDK 6 is required, it is necessary

- 	to use the internal class

- 	<literal>sun.security.util.HostnameChecker</literal>.  (The

- 	public OpenJDK API does not provide any support for dissecting

- 	the subject distinguished name of an X.509 certificate, so a

- 	custom-written DER parser is needed—or we have to use an

- 	internal class, which we do below.)  In OpenJDK 7, the

- 	<function>setEndpointIdentificationAlgorithm</function> method

- 	was added to the

- 	<literal>javax.net.ssl.SSLParameters</literal> class,

- 	providing an official way to implement host name checking.

-       </para>

-       <para>

- 	TLS connections are established using an

- 	<literal>SSLContext</literal> instance.  With a properly

- 	configured OpenJDK installation, the

- 	<literal>SunJSSE</literal> provider uses the system-wide set

- 	of trusted root certificate authorities, so no further

- 	configuration is necessary.  For backwards compatibility with

- 	OpenJDK&nbsp;6, the <literal>TLSv1</literal> provider has to

- 	be supported as a fall-back option.  This is shown in <xref

- 	linkend="ex-Defensive_Coding-TLS-Client-OpenJDK-Context"/>.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-OpenJDK-Context">

- 	<title>Setting up an <literal>SSLContext</literal> for OpenJDK TLS

- 	clients</title>

- 	<xi:include href="snippets/Features-TLS-Client-OpenJDK-Context.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	In addition to the context, a TLS parameter object will be

- 	needed which adjusts the cipher suites and protocols (<xref

- 	linkend="ex-Defensive_Coding-TLS-OpenJDK-Parameters"/>).  Like

- 	the context, these parameters can be reused for multiple TLS

- 	connections.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-OpenJDK-Parameters">

- 	<title>Setting up <literal>SSLParameters</literal> for TLS use

- 	with OpenJDK</title>

- 	<xi:include href="snippets/Features-TLS-OpenJDK-Parameters.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	As initialized above, the parameter object does not yet

- 	require host name checking.  This has to be enabled

- 	separately, and this is only supported by OpenJDK 7 and later:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/Features-TLS-Client-OpenJDK-Hostname.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	All application protocols can use the

- 	<literal>"HTTPS"</literal> algorithm.  (The algorithms have

- 	minor differences with regard to wildcard handling, which

- 	should not matter in practice.)

-       </para>

-       <para>

- 	<xref linkend="ex-Defensive_Coding-TLS-Client-OpenJDK-Connect"/>

- 	shows how to establish the connection.  Before the handshake

- 	is initialized, the protocol and cipher configuration has to

- 	be performed, by applying the parameter object

- 	<literal>params</literal>.  (After this point, changes to

- 	<literal>params</literal> will not affect this TLS socket.)

- 	As mentioned initially, host name checking requires using an

- 	internal API on OpenJDK 6.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-OpenJDK-Connect">

- 	<title>Establishing a TLS connection with OpenJDK</title>

- 	<xi:include href="snippets/Features-TLS-Client-OpenJDK-Connect.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	Starting with OpenJDK 7, the last lines can be omitted,

- 	provided that host name verification has been enabled by

- 	calling the

- 	<function>setEndpointIdentificationAlgorithm</function> method

- 	on the <literal>params</literal> object (before it was applied

- 	to the socket).

-       </para>

-       <para>

- 	The TLS socket can be used as a regular socket, as shown in

- 	<xref linkend="ex-Defensive_Coding-TLS-Client-OpenJDK-Use"/>.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-OpenJDK-Use">

- 	<title>Using a TLS client socket in OpenJDK</title>

- 	<xi:include href="snippets/Features-TLS-Client-OpenJDK-Use.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <section>

- 	<title>Overriding server certificate validation with OpenJDK 6</title>

- 	<para>

- 	  Overriding certificate validation requires a custom trust

- 	  manager.  With OpenJDK 6, the trust manager lacks

- 	  information about the TLS session, and to which server the

- 	  connection is made.  Certificate overrides have to be tied

- 	  to specific servers (host names).  Consequently, different

- 	  <literal>TrustManager</literal> and

- 	  <literal>SSLContext</literal> objects have to be used for

- 	  different servers.

- 	</para>

- 	<para>

- 	  In the trust manager shown in <xref

- 	  linkend="ex-Defensive_Coding-TLS-Client-MyTrustManager"/>,

- 	  the server certificate is identified by its SHA-256 hash.

- 	</para>

- 	<example id="ex-Defensive_Coding-TLS-Client-MyTrustManager">

- 	  <title>A customer trust manager for OpenJDK TLS clients</title>

- 	  <xi:include href="snippets/Features-TLS-Client-OpenJDK-MyTrustManager.xml"

- 		      xmlns:xi="http://www.w3.org/2001/XInclude" />

- 	</example>

- 	<para>

- 	  This trust manager has to be passed to the

- 	  <literal>init</literal> method of the

- 	  <literal>SSLContext</literal> object, as show in <xref

- 	  linkend="ex-Defensive_Coding-TLS-Client-Context_For_Cert"/>.

- 	</para>

- 	<example id="ex-Defensive_Coding-TLS-Client-Context_For_Cert">

- 	  <title>Using a custom TLS trust manager with OpenJDK</title>

- 	  <xi:include href="snippets/Features-TLS-Client-OpenJDK-Context_For_Cert.xml"

- 		      xmlns:xi="http://www.w3.org/2001/XInclude" />

- 	</example>

- 	<para>

- 	  When certificate overrides are in place, host name

- 	  verification should not be performed because there is no

- 	  security requirement that the host name in the certificate

- 	  matches the host name used to establish the connection (and

- 	  it often will not).  However, without host name

- 	  verification, it is not possible to perform transparent

- 	  fallback to certification validation using the system

- 	  certificate store.

- 	</para>

- 	<para>

- 	  The approach described above works with OpenJDK 6 and later

- 	  versions.  Starting with OpenJDK 7, it is possible to use a

- 	  custom subclass of the

- 	  <literal>javax.net.ssl.X509ExtendedTrustManager</literal>

- 	  class.  The OpenJDK TLS implementation will call the new

- 	  methods, passing along TLS session information.  This can be

- 	  used to implement certificate overrides as a fallback (if

- 	  certificate or host name verification fails), and a trust

- 	  manager object can be used for multiple servers because the

- 	  server address is available to the trust manager.

- 	</para>

-       </section>

-     </section>

-     <section id="sect-Defensive_Coding-TLS-Client-NSS">

-       <title>Implementing TLS Clients With NSS</title>

-       <para>

- 	The following code shows how to implement a simple TLS client

- 	using NSS.  These instructions apply to NSS version 3.14 and

- 	later.  Versions before 3.14 need different initialization

- 	code.

- 	</para>

- 	<para>

- 	  Keep in mind that the error handling needs to be improved

- 	  before the code can be used in production.

-       </para>

-       <para>

- 	Using NSS needs several header files, as shown in 

- 	<xref linkend="ex-Defensive_Coding-TLS-NSS-Includes"/>.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-NSS-Includes">

- 	<title>Include files for NSS</title>

- 	<xi:include href="snippets/Features-TLS-NSS-Includes.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	Initializing the NSS library is shown in <xref

- 	linkend="ex-Defensive_Coding-TLS-NSS-Init"/>.  This

- 	initialization procedure overrides global state.  We only call

- 	<function>NSS_SetDomesticPolicy</function> if there are no

- 	strong ciphers available, assuming that it has already been

- 	called otherwise.  This avoids overriding the process-wide

- 	cipher suite policy unnecessarily.

-       </para>

-       <para>

- 	The simplest way to configured the trusted root certificates

- 	involves loading the <filename>libnssckbi.so</filename> NSS

- 	module with a call to the

- 	<function>SECMOD_LoadUserModule</function> function.  The root

- 	certificates are compiled into this module.  (The PEM module

- 	for NSS, <filename>libnsspem.so</filename>, offers a way to

- 	load trusted CA certificates from a file.)

-       </para>

-       <example id="ex-Defensive_Coding-TLS-NSS-Init">

- 	<title>Initializing the NSS library</title>

- 	<xi:include href="snippets/Features-TLS-NSS-Init.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	Some of the effects of the initialization can be reverted with

- 	the following function calls:

-       </para>

-       <informalexample id="ex-Defensive_Coding-TLS-NSS-Close">

- 	<xi:include href="snippets/Features-TLS-NSS-Close.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	After NSS has been initialized, the TLS connection can be

- 	created (<xref

- 	linkend="ex-Defensive_Coding-TLS-Client-NSS-Connect"/>).  The

- 	internal <function>PR_ImportTCPSocket</function> function is

- 	used to turn the POSIX file descriptor

- 	<literal>sockfd</literal> into an NSPR file descriptor.  (This

- 	function is de-facto part of the NSS public ABI, so it will

- 	not go away.)  Creating the TLS-capable file descriptor

- 	requires a <emphasis>model</emphasis> descriptor, which is

- 	configured with the desired set of protocols.  The model

- 	descriptor is not needed anymore after TLS support has been

- 	activated for the existing connection descriptor.

-       </para>

-       <para>

- 	The call to <function>SSL_BadCertHook</function> can be

- 	omitted if no mechanism to override certificate verification

- 	is needed.  The <literal>bad_certificate</literal> function

- 	must check both the host name specified for the connection and

- 	the certificate before granting the override.

-       </para>

-       <para>

- 	Triggering the actual handshake requires three function calls,

- 	<function>SSL_ResetHandshake</function>,

- 	<function>SSL_SetURL</function>, and

- 	<function>SSL_ForceHandshake</function>.  (If

- 	<function>SSL_ResetHandshake</function> is omitted,

- 	<function>SSL_ForceHandshake</function> will succeed, but the

- 	data will not be encrypted.)  During the handshake, the

- 	certificate is verified and matched against the host name.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-NSS-Connect">

- 	<title>Creating a TLS connection with NSS</title>

- 	<xi:include href="snippets/Features-TLS-Client-NSS-Connect.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	After the connection has been established, <xref

- 	linkend="ex-Defensive_Coding-TLS-NSS-Use"/> shows how to use

- 	the NSPR descriptor to communicate with the server.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-NSS-Use">

- 	<title>Using NSS for sending and receiving data</title>

- 	<xi:include href="snippets/Features-TLS-NSS-Use.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	<xref linkend="ex-Defensive_Coding-TLS-Client-NSS-Close"/>

- 	shows how to close the connection.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-NSS-Close">

- 	<title>Closing NSS client connections</title>

- 	<xi:include href="snippets/Features-TLS-Client-NSS-Close.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-     </section>

-     <section id="sect-Defensive_Coding-TLS-Client-Python">

-       <title>Implementing TLS Clients With Python</title>

-       <para>

- 	The Python distribution provides a TLS implementation in the

- 	<literal>ssl</literal> module (actually a wrapper around

- 	OpenSSL).  The exported interface is somewhat restricted, so

- 	that the client code shown below does not fully implement the

- 	recommendations in <xref

- 	linkend="sect-Defensive_Coding-TLS-OpenSSL"/>.

-       </para>

-       <important>

- 	<para>

- 	  Currently, most Python function which accept

- 	  <literal>https://</literal> URLs or otherwise implement

- 	  HTTPS support do not perform certificate validation at all.

- 	  (For example, this is true for the <literal>httplib</literal>

- 	  and <literal>xmlrpclib</literal> modules.)  If you use

- 	  HTTPS, you should not use the built-in HTTP clients.  The

- 	  <literal>Curl</literal> class in the <literal>curl</literal>

- 	  module, as provided by the <literal>python-pycurl</literal>

- 	  package implements proper certificate validation.

- 	</para>

-       </important>

-       <para>

- 	The <literal>ssl</literal> module currently does not perform

- 	host name checking on the server certificate.  <xref

- 	linkend="ex-Defensive_Coding-TLS-Client-Python-check_host_name"/>

- 	shows how to implement certificate matching, using the parsed

- 	certificate returned by <function>getpeercert</function>.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-Python-check_host_name">

- 	<title>Implementing TLS host name checking Python (without

- 	wildcard support)</title>

- 	<xi:include href="snippets/Features-TLS-Client-Python-check_host_name.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	To turn a regular, connected TCP socket into a TLS-enabled

- 	socket, use the <function>ssl.wrap_socket</function> function.

- 	The function call in <xref

- 	linkend="ex-Defensive_Coding-TLS-Client-Python-Connect"/>

- 	provides additional arguments to override questionable

- 	defaults in OpenSSL and in the Python module.

-       </para>

-       <itemizedlist>

- 	<listitem>

- 	  <para>

- 	    <literal>ciphers="HIGH:-aNULL:-eNULL:-PSK:RC4-SHA:RC4-MD5"</literal>

- 	    selects relatively strong cipher suites with

- 	    certificate-based authentication.  (The call to

- 	    <function>check_host_name</function> function provides 

- 	    additional protection against anonymous cipher suites.)

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    <literal>ssl_version=ssl.PROTOCOL_TLSv1</literal> disables

- 	    SSL 2.0 support.  By default, the <literal>ssl</literal>

- 	    module sends an SSL 2.0 client hello, which is rejected by

- 	    some servers.  Ideally, we would request OpenSSL to

- 	    negotiated the most recent TLS version supported by the

- 	    server and the client, but the Python module does not

- 	    allow this.

- 	  </para>

- 	</listitem>

- 	<listitem>

-           <para>

- 	    <literal>cert_reqs=ssl.CERT_REQUIRED</literal> turns on

- 	    certificate validation.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    <literal>ca_certs='/etc/ssl/certs/ca-bundle.crt'</literal>

- 	    initializes the certificate store with a set of trusted

- 	    root CAs.  Unfortunately, it is necessary to hard-code

- 	    this path into applications because the default path in

- 	    OpenSSL is not available through the Python

- 	    <literal>ssl</literal> module.

- 	  </para>

- 	</listitem>

-       </itemizedlist>

-       <para>

- 	The <literal>ssl</literal> module (and OpenSSL) perform

- 	certificate validation, but the certificate must be compared

- 	manually against the host name, by calling the

- 	<function>check_host_name</function> defined above.

-       </para>

-       <example id="ex-Defensive_Coding-TLS-Client-Python-Connect">

- 	<title>Establishing a TLS client connection with Python</title>

- 	<xi:include href="snippets/Features-TLS-Client-Python-Connect.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	After the connection has been established, the TLS socket can

- 	be used like a regular socket:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/Features-TLS-Python-Use.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-       <para>

- 	Closing the TLS socket is straightforward as well:

-       </para>

-       <informalexample>

- 	<xi:include href="snippets/Features-TLS-Python-Close.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </informalexample>

-     </section>

-   </section>

- </chapter>

en-US/Go.adoc
file added
+110
@@ -0,0 +1,110 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Go]]

+ === The Go Programming Language

+ 

+ This chapter contains language-specific recommendations for Go.

+ 

+ [[chap-Defensive_Coding-Go-Memory_Safety]]

+ ==== Memory Safety

+ 

+ Go provides memory safety, but only if the program is not executed

+ in parallel (that is, `GOMAXPROCS` is not larger than

+ `1`). The reason is that interface values and

+ slices consist of multiple words are not updated atomically.

+ Another thread of execution can observe an inconsistent pairing

+ between type information and stored value (for interfaces) or

+ pointer and length (for slices), and such inconsistency can lead

+ to a memory safety violation.

+ 

+ Code which does not run in parallel and does not use the

+ `unsafe` package (or other packages which expose

+ unsafe constructs) is memory-safe. For example, invalid casts and

+ out-of-range subscripting cause panics at run time.

+ 

+ Keep in mind that finalization can introduce parallelism because

+ finalizers are executed concurrently, potentially interleaved with

+ the rest of the program.

+ 

+ [[chap-Defensive_Coding-Go-Error_Handling]]

+ ==== Error Handling

+ 

+ Only a few common operations (such as pointer dereference, integer

+ division, array subscripting) trigger exceptions in Go, called

+ *panics*. Most interfaces in the standard

+ library use a separate return value of type

+ `error` to signal error.

+ 

+ Not checking error return values can lead to incorrect operation

+ and data loss (especially in the case of writes, using interfaces

+ such as `io.Writer`).

+ 

+ The correct way to check error return values depends on the

+ function or method being called. In the majority of cases, the

+ first step after calling a function should be an error check

+ against the `nil` value, handling any encountered

+ error. See <<ex-Defensive_Coding-Go-Error_Handling-Regular>> for

+ details.

+ 

+ [[ex-Defensive_Coding-Go-Error_Handling-Regular]]

+ .Regular error handling in Go

+ ====

+ 

+ [source,go]

+ ----

+ include::snippets/Go-Error_Handling-Regular.adoc[]

+ 		

+ ----

+ 

+ ====

+ 

+ However, with `io.Reader`,

+ `io.ReaderAt` and related interfaces, it is

+ necessary to check for a non-zero number of read bytes first, as

+ shown in <<ex-Defensive_Coding-Go-Error_Handling-IO>>. If this

+ pattern is not followed, data loss may occur. This is due to the

+ fact that the `io.Reader` interface permits

+ returning both data and an error at the same time.

+ 

+ [[ex-Defensive_Coding-Go-Error_Handling-IO]]

+ .Read error handling in Go

+ ====

+ 

+ [source,go]

+ ----

+ include::snippets/Go-Error_Handling-IO.adoc[]

+ 		

+ ----

+ 

+ ====

+ 

+ [[chap-Defensive_Coding-Go-Garbage_Collector]]

+ ==== Garbage Collector

+ 

+ Older Go releases (before Go 1.3) use a conservative garbage

+ collector without blacklisting. This means that data blobs can

+ cause retention of unrelated data structures because the data is

+ conservatively interpreted as pointers. This phenomenon can be

+ triggered accidentally on 32-bit architectures and is more likely

+ to occur if the heap grows larger. On 64-bit architectures, it

+ may be possible to trigger it deliberately—it is unlikely to occur

+ spontaneously.

+ 

+ [[chap-Defensive_Coding-Go-Marshaling]]

+ ==== Marshaling and Unmarshaling

+ 

+ Several packages in the `encoding` hierarchy

+ provide support for serialization and deserialization. The usual

+ caveats apply (see

+ <<chap-Defensive_Coding-Tasks-Serialization>>).

+ 

+ As an additional precaution, the `Unmarshal`

+ and `Decode` functions should only be used with

+ fresh values in the `interface{}` argument. This

+ is due to the way defaults for missing values are implemented:

+ During deserialization, missing value do not result in an error,

+ but the original value is preserved. Using a fresh value (with

+ suitable default values if necessary) ensures that data from a

+ previous deserialization operation does not leak into the current

+ one. This is especially relevant when structs are deserialized.

en-US/Go.xml
file removed
-110
@@ -1,110 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Go">

- <title>The Go Programming Language</title>

- <para>

-   This chapter contains language-specific recommendations for Go.

- </para>

- <section id="chap-Defensive_Coding-Go-Memory_Safety">

-   <title>Memory safety</title>

-   <para>

-     Go provides memory safety, but only if the program is not executed

-     in parallel (that is, <envar>GOMAXPROCS</envar> is not larger than

-     <literal>1</literal>).  The reason is that interface values and

-     slices consist of multiple words are not updated atomically.

-     Another thread of execution can observe an inconsistent pairing

-     between type information and stored value (for interfaces) or

-     pointer and length (for slices), and such inconsistency can lead

-     to a memory safety violation.

-   </para>

-   <para>

-     Code which does not run in parallel and does not use the

-     <literal>unsafe</literal> package (or other packages which expose

-     unsafe constructs) is memory-safe.  For example, invalid casts and

-     out-of-range subscripting cause panics at run time.

-   </para>

-   <para>

-     Keep in mind that finalization can introduce parallelism because

-     finalizers are executed concurrently, potentially interleaved with

-     the rest of the program.

-   </para>

- </section>

- <section id="chap-Defensive_Coding-Go-Error_Handling">

-   <title>Error handling</title>

-   <para>

-     Only a few common operations (such as pointer dereference, integer

-     division, array subscripting) trigger exceptions in Go, called

-     <emphasis>panics</emphasis>.  Most interfaces in the standard

-     library use a separate return value of type

-     <literal>error</literal> to signal error.

-   </para>

-   <para>

-     Not checking error return values can lead to incorrect operation

-     and data loss (especially in the case of writes, using interfaces

-     such as <literal>io.Writer</literal>).

-   </para>

-   <para>

-     The correct way to check error return values depends on the

-     function or method being called.  In the majority of cases, the

-     first step after calling a function should be an error check

-     against the <literal>nil</literal> value, handling any encountered

-     error.  See <xref

-     linkend="ex-Defensive_Coding-Go-Error_Handling-Regular"/> for

-     details.

-   </para>

-   <example id="ex-Defensive_Coding-Go-Error_Handling-Regular">

-     <title>Regular error handling in Go</title>

-     <xi:include href="snippets/Go-Error_Handling-Regular.xml"

- 		xmlns:xi="http://www.w3.org/2001/XInclude" />

-   </example>

-   <para>

-     However, with <literal>io.Reader</literal>,

-     <literal>io.ReaderAt</literal> and related interfaces, it is

-     necessary to check for a non-zero number of read bytes first, as

-     shown in <xref

-     linkend="ex-Defensive_Coding-Go-Error_Handling-IO"/>.  If this

-     pattern is not followed, data loss may occur.  This is due to the

-     fact that the <literal>io.Reader</literal> interface permits

-     returning both data and an error at the same time.

-   </para>

-   <example id="ex-Defensive_Coding-Go-Error_Handling-IO">

-     <title>Read error handling in Go</title>

-     <xi:include href="snippets/Go-Error_Handling-IO.xml"

- 		xmlns:xi="http://www.w3.org/2001/XInclude" />

-   </example>

- </section>

- <section id="chap-Defensive_Coding-Go-Garbage_Collector">

-   <title>Garbage Collector</title>

-   <para>

-     Older Go releases (before Go 1.3) use a conservative garbage

-     collector without blacklisting.  This means that data blobs can

-     cause retention of unrelated data structures because the data is

-     conservatively interpreted as pointers.  This phenomenon can be

-     triggered accidentally on 32-bit architectures and is more likely

-     to occur if the heap grows larger.  On 64-bit architectures, it

-     may be possible to trigger it deliberately—it is unlikely to occur

-     spontaneously.

-   </para>

- </section>

- <section id="chap-Defensive_Coding-Go-Marshaling">

-   <title>Marshaling and unmarshaling</title>

-   <para>

-     Several packages in the <literal>encoding</literal> hierarchy

-     provide support for serialization and deserialization.  The usual

-     caveats apply (see

-     <xref linkend="chap-Defensive_Coding-Tasks-Serialization"/>).

-   </para>

-   <para>

-     As an additional precaution, the <function>Unmarshal</function>

-     and <function>Decode</function> functions should only be used with

-     fresh values in the <literal>interface{}</literal> argument.  This

-     is due to the way defaults for missing values are implemented:

-     During deserialization, missing value do not result in an error,

-     but the original value is preserved.  Using a fresh value (with

-     suitable default values if necessary) ensures that data from a

-     previous deserialization operation does not leak into the current

-     one.  This is especially relevant when structs are deserialized.

-   </para>

- </section>

- </chapter>

en-US/Java-Language.adoc
file added
+252
@@ -0,0 +1,252 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-Java-Language]]

+ ==== The Core Language

+ 

+ Implementations of the Java programming language provide strong

+ memory safety, even in the presence of data races in concurrent

+ code. This prevents a large range of security vulnerabilities

+ from occurring, unless certain low-level features are used; see

+ <<sect-Defensive_Coding-Java-LowLevel>>.

+ 

+ [[sect-Defensive_Coding-Java-Language-ReadArray]]

+ ===== Increasing Robustness when Reading Arrays

+ 

+ External data formats often include arrays, and the data is

+ stored as an integer indicating the number of array elements,

+ followed by this number of elements in the file or protocol data

+ unit. This length specified can be much larger than what is

+ actually available in the data source.

+ 

+ To avoid allocating extremely large amounts of data, you can

+ allocate a small array initially and grow it as you read more

+ data, implementing an exponential growth policy. See the

+ `readBytes(InputStream, int)` function in

+ <<ex-Defensive_Coding-Java-Language-ReadArray>>.

+ 

+ [[ex-Defensive_Coding-Java-Language-ReadArray]]

+ .Incrementally reading a byte array

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Java-Language-ReadArray.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ When reading data into arrays, hash maps or hash sets, use the

+ default constructor and do not specify a size hint. You can

+ simply add the elements to the collection as you read them.

+ 

+ [[sect-Defensive_Coding-Java-Language-Resources]]

+ ===== Resource Management

+ 

+ Unlike C++, Java does not offer destructors which can deallocate

+ resources in a predictable fashion. All resource management has

+ to be manual, at the usage site. (Finalizers are generally not

+ usable for resource management, especially in high-performance

+ code; see <<sect-Defensive_Coding-Java-Language-Finalizers>>.)

+ 

+ The first option is the

+ `try`-`finally` construct, as

+ shown in <<ex-Defensive_Coding-Java-Language-Finally>>.

+ The code in the `finally` block should be as short as

+ possible and should not throw any exceptions.

+ 

+ [[ex-Defensive_Coding-Java-Language-Finally]]

+ .Resource management with a `try`-`finally` block

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Java-Finally.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ Note that the resource allocation happens

+ *outside* the `try` block,

+ and that there is no `null` check in the

+ `finally` block. (Both are common artifacts

+ stemming from IDE code templates.)

+ 

+ If the resource object is created freshly and implements the

+ `java.lang.AutoCloseable` interface, the code

+ in <<ex-Defensive_Coding-Java-Language-TryWithResource>> can be

+ used instead. The Java compiler will automatically insert the

+ `close()` method call in a synthetic

+ `finally` block.

+ 

+ [[ex-Defensive_Coding-Java-Language-TryWithResource]]

+ .Resource management using the `try`-with-resource construct

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Java-TryWithResource.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ To be compatible with the `try`-with-resource

+ construct, new classes should name the resource deallocation

+ method `close()`, and implement the

+ `AutoCloseable` interface (the latter breaking

+ backwards compatibility with Java 6). However, using the

+ `try`-with-resource construct with objects that

+ are not freshly allocated is at best awkward, and an explicit

+ `finally` block is usually the better approach.

+ 

+ In general, it is best to design the programming interface in

+ such a way that resource deallocation methods like

+ `close()` cannot throw any (checked or

+ unchecked) exceptions, but this should not be a reason to ignore

+ any actual error conditions.

+ 

+ [[sect-Defensive_Coding-Java-Language-Finalizers]]

+ ===== Finalizers

+ 

+ Finalizers can be used a last-resort approach to free resources

+ which would otherwise leak. Finalization is unpredictable,

+ costly, and there can be a considerable delay between the last

+ reference to an object going away and the execution of the

+ finalizer. Generally, manual resource management is required;

+ see <<sect-Defensive_Coding-Java-Language-Resources>>.

+ 

+ Finalizers should be very short and should only deallocate

+ native or other external resources held directly by the object

+ being finalized. In general, they must use synchronization:

+ Finalization necessarily happens on a separate thread because it is

+ inherently concurrent. There can be multiple finalization

+ threads, and despite each object being finalized at most once,

+ the finalizer must not assume that it has exclusive access to

+ the object being finalized (in the `this`

+ pointer).

+ 

+ Finalizers should not deallocate resources held by other

+ objects, especially if those objects have finalizers on their

+ own. In particular, it is a very bad idea to define a finalizer

+ just to invoke the resource deallocation method of another object,

+ or overwrite some pointer fields.

+ 

+ Finalizers are not guaranteed to run at all. For instance, the

+ virtual machine (or the machine underneath) might crash,

+ preventing their execution.

+ 

+ Objects with finalizers are garbage-collected much later than

+ objects without them, so using finalizers to zero out key

+ material (to reduce its undecrypted lifetime in memory) may have

+ the opposite effect, keeping objects around for much longer and

+ prevent them from being overwritten in the normal course of

+ program execution.

+ 

+ For the same reason, code which allocates objects with

+ finalizers at a high rate will eventually fail (likely with a

+ `java.lang.OutOfMemoryError` exception) because

+ the virtual machine has finite resources for keeping track of

+ objects pending finalization. To deal with that, it may be

+ necessary to recycle objects with finalizers.

+ 

+ The remarks in this section apply to finalizers which are

+ implemented by overriding the `finalize()`

+ method, and to custom finalization using reference queues.

+ 

+ [[sect-Defensive_Coding-Java-Language-Exceptions]]

+ ===== Recovering from Exceptions and Errors

+ 

+ Java exceptions come in three kinds, all ultimately deriving

+ from `java.lang.Throwable`:

+ 

+ * *Run-time exceptions* do not have to be

+ declared explicitly and can be explicitly thrown from any

+ code, by calling code which throws them, or by triggering an

+ error condition at run time, like division by zero, or an

+ attempt at an out-of-bounds array access. These exceptions

+ derive from from the

+ `java.lang.RuntimeException` class (perhaps

+ indirectly).

+ 

+ * *Checked exceptions* have to be declared

+ explicitly by functions that throw or propagate them. They

+ are similar to run-time exceptions in other regards, except

+ that there is no language construct to throw them (except

+ the `throw` statement itself). Checked

+ exceptions are only present at the Java language level and

+ are only enforced at compile time. At run time, the virtual

+ machine does not know about them and permits throwing

+ exceptions from any code. Checked exceptions must derive

+ (perhaps indirectly) from the

+ `java.lang.Exception` class, but not from

+ `java.lang.RuntimeException`.

+ 

+ * *Errors* are exceptions which typically

+ reflect serious error conditions. They can be thrown at any

+ point in the program, and do not have to be declared (unlike

+ checked exceptions). In general, it is not possible to

+ recover from such errors; more on that below, in <<sect-Defensive_Coding-Java-Language-Exceptions-Errors>>.

+ Error classes derive (perhaps indirectly) from

+ `java.lang.Error`, or from

+ `java.lang.Throwable`, but not from

+ `java.lang.Exception`.

+ 

+ The general expection is that run-time errors are avoided by

+ careful programming (e.g., not dividing by zero). Checked

+ exception are expected to be caught as they happen (e.g., when

+ an input file is unexpectedly missing). Errors are impossible

+ to predict and can happen at any point and reflect that

+ something went wrong beyond all expectations.

+ 

+ [[sect-Defensive_Coding-Java-Language-Exceptions-Errors]]

+ ====== The Difficulty of Catching Errors

+ 

+ Errors (that is, exceptions which do not (indirectly) derive

+ from `java.lang.Exception`), have the

+ peculiar property that catching them is problematic. There

+ are several reasons for this:

+ 

+ * The error reflects a failed consistenty check, for example,

+ `java.lang.AssertionError`.

+ 

+ * The error can happen at any point, resulting in

+ inconsistencies due to half-updated objects. Examples are

+ `java.lang.ThreadDeath`,

+ `java.lang.OutOfMemoryError` and

+ `java.lang.StackOverflowError`.

+ 

+ * The error indicates that virtual machine failed to provide

+ some semantic guarantees by the Java programming language.

+ `java.lang.ExceptionInInitializerError`

+ is an example—it can leave behind a half-initialized

+ class.

+ 

+ In general, if an error is thrown, the virtual machine should

+ be restarted as soon as possible because it is in an

+ inconsistent state. Continuing running as before can have

+ unexpected consequences. However, there are legitimate

+ reasons for catching errors because not doing so leads to even

+ greater problems.

+ 

+ Code should be written in a way that avoids triggering errors.

+ See <<sect-Defensive_Coding-Java-Language-ReadArray>>

+ for an example.

+ 

+ It is usually necessary to log errors. Otherwise, no trace of

+ the problem might be left anywhere, making it very difficult

+ to diagnose realted failures. Consequently, if you catch

+ `java.lang.Exception` to log and suppress all

+ unexpected exceptions (for example, in a request dispatching

+ loop), you should consider switching to

+ `java.lang.Throwable` instead, to also cover

+ errors.

+ 

+ The other reason mainly applies to such request dispatching

+ loops: If you do not catch errors, the loop stops looping,

+ resulting in a denial of service.

+ 

+ However, if possible, catching errors should be coupled with a

+ way to signal the requirement of a virtual machine restart.

en-US/Java-Language.xml
file removed
-291
@@ -1,291 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-Java-Language">

-   <title>The core language</title>

-   <para>

-     Implementations of the Java programming language provide strong

-     memory safety, even in the presence of data races in concurrent

-     code.  This prevents a large range of security vulnerabilities

-     from occurring, unless certain low-level features are used; see

-     <xref linkend="sect-Defensive_Coding-Java-LowLevel"/>.

-   </para>

- 

-   <section id="sect-Defensive_Coding-Java-Language-ReadArray">

-     <title>Inceasing robustness when reading arrays</title>

-     <para>

-       External data formats often include arrays, and the data is

-       stored as an integer indicating the number of array elements,

-       followed by this number of elements in the file or protocol data

-       unit.  This length specified can be much larger than what is

-       actually available in the data source.

-     </para>

-     <para>

-       To avoid allocating extremely large amounts of data, you can

-       allocate a small array initially and grow it as you read more

-       data, implementing an exponential growth policy.  See the

-       <function>readBytes(InputStream, int)</function> function in

-       <xref linkend="ex-Defensive_Coding-Java-Language-ReadArray"/>.

-     </para>

-     <example id="ex-Defensive_Coding-Java-Language-ReadArray">

-       <title>Incrementally reading a byte array</title>

-       <xi:include href="snippets/Java-Language-ReadArray.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       When reading data into arrays, hash maps or hash sets, use the

-       default constructor and do not specify a size hint.  You can

-       simply add the elements to the collection as you read them.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Java-Language-Resources">

-     <title>Resource management</title>

-     <para>

-       Unlike C++, Java does not offer destructors which can deallocate

-       resources in a predictable fashion.  All resource management has

-       to be manual, at the usage site.  (Finalizers are generally not

-       usable for resource management, especially in high-performance

-       code; see <xref

-       linkend="sect-Defensive_Coding-Java-Language-Finalizers"/>.)

-     </para>

-     <para>

-       The first option is the

-       <literal>try</literal>-<literal>finally</literal> construct, as

-       shown in <xref linkend="ex-Defensive_Coding-Java-Language-Finally"/>.

-       The code in the <literal>finally</literal> block should be as short as

-       possible and should not throw any exceptions.

-     </para>

-     <example id="ex-Defensive_Coding-Java-Language-Finally">

-       <title>Resource management with a

-       <literal>try</literal>-<literal>finally</literal> block</title>

-       <xi:include href="snippets/Java-Finally.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       Note that the resource allocation happens

-       <emphasis>outside</emphasis> the <literal>try</literal> block,

-       and that there is no <literal>null</literal> check in the

-       <literal>finally</literal> block.  (Both are common artifacts

-       stemming from IDE code templates.)

-     </para>

-     <para>

-       If the resource object is created freshly and implements the

-       <literal>java.lang.AutoCloseable</literal> interface, the code

-       in <xref

-       linkend="ex-Defensive_Coding-Java-Language-TryWithResource"/> can be

-       used instead.  The Java compiler will automatically insert the

-       <function>close()</function> method call in a synthetic

-       <literal>finally</literal> block.

-     </para>

-     <example id="ex-Defensive_Coding-Java-Language-TryWithResource">

-       <title>Resource management using the

-       <literal>try</literal>-with-resource construct</title>

-       <xi:include href="snippets/Java-TryWithResource.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       To be compatible with the <literal>try</literal>-with-resource

-       construct, new classes should name the resource deallocation

-       method <function>close()</function>, and implement the

-       <literal>AutoCloseable</literal> interface (the latter breaking

-       backwards compatibility with Java 6).  However, using the

-       <literal>try</literal>-with-resource construct with objects that

-       are not freshly allocated is at best awkward, and an explicit

-       <literal>finally</literal> block is usually the better approach.

-     </para>

-     <para>

-       In general, it is best to design the programming interface in

-       such a way that resource deallocation methods like

-       <function>close()</function> cannot throw any (checked or

-       unchecked) exceptions, but this should not be a reason to ignore

-       any actual error conditions.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Java-Language-Finalizers">

-     <title>Finalizers</title>

-     <para>

-       Finalizers can be used a last-resort approach to free resources

-       which would otherwise leak.  Finalization is unpredictable,

-       costly, and there can be a considerable delay between the last

-       reference to an object going away and the execution of the

-       finalizer.  Generally, manual resource management is required;

-       see <xref linkend="sect-Defensive_Coding-Java-Language-Resources"/>.

-     </para>

-     <para>

-       Finalizers should be very short and should only deallocate

-       native or other external resources held directly by the object

-       being finalized.  In general, they must use synchronization:

-       Finalization necessarily happens on a separate thread because it is

-       inherently concurrent.  There can be multiple finalization

-       threads, and despite each object being finalized at most once,

-       the finalizer must not assume that it has exclusive access to

-       the object being finalized (in the <literal>this</literal>

-       pointer).

-     </para>

-     <para>

-       Finalizers should not deallocate resources held by other

-       objects, especially if those objects have finalizers on their

-       own.  In particular, it is a very bad idea to define a finalizer

-       just to invoke the resource deallocation method of another object,

-       or overwrite some pointer fields.

-     </para>

-     <para>

-       Finalizers are not guaranteed to run at all.  For instance, the

-       virtual machine (or the machine underneath) might crash,

-       preventing their execution.

-     </para>

-     <para>

-       Objects with finalizers are garbage-collected much later than

-       objects without them, so using finalizers to zero out key

-       material (to reduce its undecrypted lifetime in memory) may have

-       the opposite effect, keeping objects around for much longer and

-       prevent them from being overwritten in the normal course of

-       program execution.

-     </para>

-     <para>

-       For the same reason, code which allocates objects with

-       finalizers at a high rate will eventually fail (likely with a

-       <literal>java.lang.OutOfMemoryError</literal> exception) because

-       the virtual machine has finite resources for keeping track of

-       objects pending finalization.  To deal with that, it may be

-       necessary to recycle objects with finalizers.

-     </para>

-     <para>

-       The remarks in this section apply to finalizers which are

-       implemented by overriding the <function>finalize()</function>

-       method, and to custom finalization using reference queues.

-     </para>

-   </section>

-   

-   <section id="sect-Defensive_Coding-Java-Language-Exceptions">

-     <title>Recovering from exceptions and errors</title>

-     <para>

-       Java exceptions come in three kinds, all ultimately deriving

-       from <literal>java.lang.Throwable</literal>:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  <emphasis>Run-time exceptions</emphasis> do not have to be

- 	  declared explicitly and can be explicitly thrown from any

- 	  code, by calling code which throws them, or by triggering an

- 	  error condition at run time, like division by zero, or an

- 	  attempt at an out-of-bounds array access.  These exceptions

- 	  derive from from the

- 	  <literal>java.lang.RuntimeException</literal> class (perhaps

- 	  indirectly).

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <emphasis>Checked exceptions</emphasis> have to be declared

- 	  explicitly by functions that throw or propagate them.  They

- 	  are similar to run-time exceptions in other regards, except

- 	  that there is no language construct to throw them (except

- 	  the <literal>throw</literal> statement itself).  Checked

- 	  exceptions are only present at the Java language level and

- 	  are only enforced at compile time.  At run time, the virtual

- 	  machine does not know about them and permits throwing

- 	  exceptions from any code.  Checked exceptions must derive

- 	  (perhaps indirectly) from the

- 	  <literal>java.lang.Exception</literal> class, but not from 

- 	  <literal>java.lang.RuntimeException</literal>.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <emphasis>Errors</emphasis> are exceptions which typically

- 	  reflect serious error conditions.  They can be thrown at any

- 	  point in the program, and do not have to be declared (unlike

- 	  checked exceptions).  In general, it is not possible to

- 	  recover from such errors; more on that below, in <xref

- 	  linkend="sect-Defensive_Coding-Java-Language-Exceptions-Errors"/>.

- 	  Error classes derive (perhaps indirectly) from

- 	  <literal>java.lang.Error</literal>, or from

- 	  <literal>java.lang.Throwable</literal>, but not from

- 	  <literal>java.lang.Exception</literal>.

- 	</para>

-       </listitem>

-     </itemizedlist>

- 

-     <para>

-       The general expection is that run-time errors are avoided by

-       careful programming (e.g., not dividing by zero).  Checked

-       exception are expected to be caught as they happen (e.g., when

-       an input file is unexpectedly missing).  Errors are impossible

-       to predict and can happen at any point and reflect that

-       something went wrong beyond all expectations.

-     </para>

- 

-     <section id="sect-Defensive_Coding-Java-Language-Exceptions-Errors">

-       <title>The difficulty of catching errors</title>

-       <para>

- 	Errors (that is, exceptions which do not (indirectly) derive

- 	from <literal>java.lang.Exception</literal>), have the

- 	peculiar property that catching them is problematic.  There

- 	are several reasons for this:

-       </para>

-       <itemizedlist>

- 	<listitem>

- 	  <para>

- 	    The error reflects a failed consistenty check, for example,

- 	    <literal>java.lang.AssertionError</literal>.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The error can happen at any point, resulting in

- 	    inconsistencies due to half-updated objects.  Examples are

- 	    <literal>java.lang.ThreadDeath</literal>,

- 	    <literal>java.lang.OutOfMemoryError</literal> and

- 	    <literal>java.lang.StackOverflowError</literal>.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The error indicates that virtual machine failed to provide

- 	    some semantic guarantees by the Java programming language.

- 	    <literal>java.lang.ExceptionInInitializerError</literal>

- 	    is an example—it can leave behind a half-initialized

- 	    class.

- 	  </para>

- 	</listitem>

-       </itemizedlist>

-       <para>

- 	In general, if an error is thrown, the virtual machine should

- 	be restarted as soon as possible because it is in an

- 	inconsistent state.  Continuing running as before can have

- 	unexpected consequences.  However, there are legitimate

- 	reasons for catching errors because not doing so leads to even

- 	greater problems.

-       </para>

-       <para>

- 	Code should be written in a way that avoids triggering errors.

- 	See <xref linkend="sect-Defensive_Coding-Java-Language-ReadArray"/>

- 	for an example.

-       </para>

-       <para>

- 	It is usually necessary to log errors.  Otherwise, no trace of

- 	the problem might be left anywhere, making it very difficult

- 	to diagnose realted failures.  Consequently, if you catch

- 	<literal>java.lang.Exception</literal> to log and suppress all

- 	unexpected exceptions (for example, in a request dispatching

- 	loop), you should consider switching to

- 	<literal>java.lang.Throwable</literal> instead, to also cover

- 	errors.

-       </para>

-       <para>

- 	The other reason mainly applies to such request dispatching

- 	loops: If you do not catch errors, the loop stops looping,

- 	resulting in a denial of service.

-       </para>

-       <para>

- 	However, if possible, catching errors should be coupled with a

- 	way to signal the requirement of a virtual machine restart.

-       </para>

-     </section>

-   </section>

- </section>

- 

en-US/Java-LowLevel.adoc
file added
+141
@@ -0,0 +1,141 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-Java-LowLevel]]

+ ==== Low-level Features of the Virtual Machine

+ 

+ [[sect-Defensive_Coding-Java-Reflection]]

+ ===== Reflection and Private Parts

+ 

+ The `setAccessible(boolean)` method of the

+ `java.lang.reflect.AccessibleObject` class

+ allows a program to disable language-defined access rules for

+ specific constructors, methods, or fields. Once the access

+ checks are disabled, any code can use the

+ `java.lang.reflect.Constructor`,

+ `java.lang.reflect.Method`, or

+ `java.lang.reflect.Field` object to access the

+ underlying Java entity, without further permission checks. This

+ breaks encapsulation and can undermine the stability of the

+ virtual machine. (In contrast, without using the

+ `setAccessible(boolean)` method, this should

+ not happen because all the language-defined checks still apply.)

+ 

+ This feature should be avoided if possible.

+ 

+ [[sect-Defensive_Coding-Java-JNI]]

+ ===== Java Native Interface (JNI)

+ 

+ The Java Native Interface allows calling from Java code

+ functions specifically written for this purpose, usually in C or

+ C++.

+ 

+ The transition between the Java world and the C world is not

+ fully type-checked, and the C code can easily break the Java

+ virtual machine semantics. Therefore, extra care is needed when

+ using this functionality.

+ 

+ To provide a moderate amount of type safety, it is recommended

+ to recreate the class-specific header file using

+ [application]*javah* during the build process,

+ include it in the implementation, and use the

+ [option]`-Wmissing-declarations` option.

+ 

+ Ideally, the required data is directly passed to static JNI

+ methods and returned from them, and the code and the C side does

+ not have to deal with accessing Java fields (or even methods).

+ 

+ When using `GetPrimitiveArrayCritical` or

+ `GetStringCritical`, make sure that you only

+ perform very little processing between the get and release

+ operations. Do not access the file system or the network, and

+ not perform locking, because that might introduce blocking.

+ When processing large strings or arrays, consider splitting the

+ computation into multiple sub-chunks, so that you do not prevent

+ the JVM from reaching a safepoint for extended periods of time.

+ 

+ If necessary, you can use the Java `long` type

+ to store a C pointer in a field of a Java class. On the C side,

+ when casting between the `jlong` value and the

+ pointer on the C side,

+ 

+ You should not try to perform pointer arithmetic on the Java

+ side (that is, you should treat pointer-carrying

+ `long` values as opaque). When passing a slice

+ of an array to the native code, follow the Java convention and

+ pass it as the base array, the integer offset of the start of

+ the slice, and the integer length of the slice. On the native

+ side, check the offset/length combination against the actual

+ array length, and use the offset to compute the pointer to the

+ beginning of the array.

+ 

+ [[ex-Defensive_Coding-Java-JNI-Pointers]]

+ .Array length checking in JNI code

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Java-JNI-Pointers.adoc[]

+ 		  

+ ----

+ 

+ ====

+ 

+ In any case, classes referring to native resources must be

+ declared `final`, and must not be serializeable

+ or cloneable. Initialization and mutation of the state used by

+ the native side must be controlled carefully. Otherwise, it

+ might be possible to create an object with inconsistent native

+ state which results in a crash (or worse) when used (or perhaps

+ only finalized) later. If you need both Java inheritance and

+ native resources, you should consider moving the native state to

+ a separate class, and only keep a reference to objects of that

+ class. This way, cloning and serialization issues can be

+ avoided in most cases.

+ 

+ If there are native resources associated with an object, the

+ class should have an explicit resource deallocation method

+ (<<sect-Defensive_Coding-Java-Language-Resources>>) and a

+ finalizer (<<sect-Defensive_Coding-Java-Language-Finalizers>>) as a

+ last resort. The need for finalization means that a minimum

+ amount of synchronization is needed. Code on the native side

+ should check that the object is not in a closed/freed state.

+ 

+ Many JNI functions create local references. By default, these

+ persist until the JNI-implemented method returns. If you create

+ many such references (e.g., in a loop), you may have to free

+ them using `DeleteLocalRef`, or start using

+ `PushLocalFrame` and

+ `PopLocalFrame`. Global references must be

+ deallocated with `DeleteGlobalRef`, otherwise

+ there will be a memory leak, just as with

+ `malloc` and `free`.

+ 

+ When throwing exceptions using `Throw` or

+ `ThrowNew`, be aware that these functions

+ return regularly. You have to return control manually to the

+ JVM.

+ 

+ Technically, the `JNIEnv` pointer is not

+ necessarily constant during the lifetime of your JNI module.

+ Storing it in a global variable is therefore incorrect.

+ Particularly if you are dealing with callbacks, you may have to

+ store the pointer in a thread-local variable (defined with

+ `__thread`). It is, however, best to avoid the

+ complexity of calling back into Java code.

+ 

+ Keep in mind that C/C++ and Java are different languages,

+ despite very similar syntax for expressions. The Java memory

+ model is much more strict than the C or C++ memory models, and

+ native code needs more synchronization, usually using JVM

+ facilities or POSIX threads mutexes. Integer overflow in Java

+ is defined, but in C/C++ it is not (for the

+ `jint` and `jlong` types).

+ 

+ [[sect-Defensive_Coding-Java-MiscUnsafe]]

+ ===== `sun.misc.Unsafe`

+ 

+ The `sun.misc.Unsafe` class is unportable and

+ contains many functions explicitly designed to break Java memory

+ safety (for performance and debugging). If possible, avoid

+ using this class.

en-US/Java-LowLevel.xml
file removed
-157
@@ -1,157 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-Java-LowLevel">

-   <title>Low-level features of the virtual machine</title>

- 

-   <section id="sect-Defensive_Coding-Java-Reflection">

-     <title><literal>Reflection and private parts</literal></title>

-     <para>

-       The <function>setAccessible(boolean)</function> method of the

-       <literal>java.lang.reflect.AccessibleObject</literal> class

-       allows a program to disable language-defined access rules for

-       specific constructors, methods, or fields.  Once the access

-       checks are disabled, any code can use the

-       <literal>java.lang.reflect.Constructor</literal>,

-       <literal>java.lang.reflect.Method</literal>, or

-       <literal>java.lang.reflect.Field</literal> object to access the

-       underlying Java entity, without further permission checks.  This

-       breaks encapsulation and can undermine the stability of the

-       virtual machine.  (In contrast, without using the

-       <function>setAccessible(boolean)</function> method, this should

-       not happen because all the language-defined checks still apply.)

-     </para>

-     <para>

-       This feature should be avoided if possible.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Java-JNI">

-     <title>Java Native Interface (JNI)</title>

-     <para>

-       The Java Native Interface allows calling from Java code

-       functions specifically written for this purpose, usually in C or

-       C++.

-     </para>

-     <para>

-       The transition between the Java world and the C world is not

-       fully type-checked, and the C code can easily break the Java

-       virtual machine semantics.  Therefore, extra care is needed when

-       using this functionality.

-     </para>

-     <para>

-       To provide a moderate amount of type safety, it is recommended

-       to recreate the class-specific header file using

-       <application>javah</application> during the build process,

-       include it in the implementation, and use the

-       <option>-Wmissing-declarations</option> option.

-     </para>

-     <para>

-       Ideally, the required data is directly passed to static JNI

-       methods and returned from them, and the code and the C side does

-       not have to deal with accessing Java fields (or even methods).

-     </para>

-     <para>

-       When using <function>GetPrimitiveArrayCritical</function> or

-       <function>GetStringCritical</function>, make sure that you only

-       perform very little processing between the get and release

-       operations.  Do not access the file system or the network, and

-       not perform locking, because that might introduce blocking.

-       When processing large strings or arrays, consider splitting the

-       computation into multiple sub-chunks, so that you do not prevent

-       the JVM from reaching a safepoint for extended periods of time.

-     </para>

-     <para>

-       If necessary, you can use the Java <literal>long</literal> type

-       to store a C pointer in a field of a Java class.  On the C side,

-       when casting between the <literal>jlong</literal> value and the

-       pointer on the C side, 

-     </para>

-     <para>

-       You should not try to perform pointer arithmetic on the Java

-       side (that is, you should treat pointer-carrying

-       <literal>long</literal> values as opaque).  When passing a slice

-       of an array to the native code, follow the Java convention and

-       pass it as the base array, the integer offset of the start of

-       the slice, and the integer length of the slice.  On the native

-       side, check the offset/length combination against the actual

-       array length, and use the offset to compute the pointer to the

-       beginning of the array.

-     </para>

-     <example id="ex-Defensive_Coding-Java-JNI-Pointers">

-       <title>Array length checking in JNI code</title>

-       <xi:include href="snippets/Java-JNI-Pointers.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       In any case, classes referring to native resources must be

-       declared <literal>final</literal>, and must not be serializeable

-       or cloneable.  Initialization and mutation of the state used by

-       the native side must be controlled carefully.  Otherwise, it

-       might be possible to create an object with inconsistent native

-       state which results in a crash (or worse) when used (or perhaps

-       only finalized) later.  If you need both Java inheritance and

-       native resources, you should consider moving the native state to

-       a separate class, and only keep a reference to objects of that

-       class.  This way, cloning and serialization issues can be

-       avoided in most cases.

-     </para>

-     <para>

-       If there are native resources associated with an object, the

-       class should have an explicit resource deallocation method

-       (<xref

-       linkend="sect-Defensive_Coding-Java-Language-Resources"/>) and a

-       finalizer (<xref

-       linkend="sect-Defensive_Coding-Java-Language-Finalizers"/>) as a

-       last resort.  The need for finalization means that a minimum

-       amount of synchronization is needed.  Code on the native side

-       should check that the object is not in a closed/freed state.

-     </para>

-     <para>

-       Many JNI functions create local references.  By default, these

-       persist until the JNI-implemented method returns.  If you create

-       many such references (e.g., in a loop), you may have to free

-       them using <function>DeleteLocalRef</function>, or start using

-       <function>PushLocalFrame</function> and

-       <function>PopLocalFrame</function>.  Global references must be

-       deallocated with <function>DeleteGlobalRef</function>, otherwise

-       there will be a memory leak, just as with

-       <function>malloc</function> and <function>free</function>.

-     </para>

-     <para>

-       When throwing exceptions using <function>Throw</function> or

-       <function>ThrowNew</function>, be aware that these functions

-       return regularly.  You have to return control manually to the

-       JVM.

-     </para>

-     <para>

-       Technically, the <literal>JNIEnv</literal> pointer is not

-       necessarily constant during the lifetime of your JNI module.

-       Storing it in a global variable is therefore incorrect.

-       Particularly if you are dealing with callbacks, you may have to

-       store the pointer in a thread-local variable (defined with

-       <literal>__thread</literal>).  It is, however, best to avoid the

-       complexity of calling back into Java code.

-     </para>

-     <para>

-       Keep in mind that C/C++ and Java are different languages,

-       despite very similar syntax for expressions.  The Java memory

-       model is much more strict than the C or C++ memory models, and

-       native code needs more synchronization, usually using JVM

-       facilities or POSIX threads mutexes.  Integer overflow in Java

-       is defined, but in C/C++ it is not (for the

-       <literal>jint</literal> and <literal>jlong</literal> types).

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Java-MiscUnsafe">

-     <title><literal>sun.misc.Unsafe</literal></title>

-     <para>

-       The <literal>sun.misc.Unsafe</literal> class is unportable and

-       contains many functions explicitly designed to break Java memory

-       safety (for performance and debugging).  If possible, avoid

-       using this class.

-     </para>

-   </section>

- 

- </section>

en-US/Java-SecurityManager.adoc
file added
+256
@@ -0,0 +1,256 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-Java-SecurityManager]]

+ ==== Interacting with the Security Manager

+ 

+ The Java platform is largely implemented in the Java language

+ itself. Therefore, within the same JVM, code runs which is part

+ of the Java installation and which is trusted, but there might

+ also be code which comes from untrusted sources and is restricted

+ by the Java sandbox (to varying degrees). The *security

+ manager* draws a line between fully trusted, partially

+ trusted and untrusted code.

+ 

+ The type safety and accessibility checks provided by the Java

+ language and JVM would be sufficient to implement a sandbox.

+ However, only some Java APIs employ such a capabilities-based

+ approach. (The Java SE library contains many public classes with

+ public constructors which can break any security policy, such as

+ `java.io.FileOutputStream`.) Instead, critical

+ functionality is protected by *stack

+ inspection*: At a security check, the stack is walked

+ from top (most-nested) to bottom. The security check fails if a

+ stack frame for a method is encountered whose class lacks the

+ permission which the security check requires.

+ 

+ This simple approach would not allow untrusted code (which lacks

+ certain permissions) to call into trusted code while the latter

+ retains trust. Such trust transitions are desirable because they

+ enable Java as an implementation language for most parts of the

+ Java platform, including security-relevant code. Therefore, there

+ is a mechanism to mark certain stack frames as trusted (<<sect-Defensive_Coding-Java-SecurityManager-Privileged>>).

+ 

+ In theory, it is possible to run a Java virtual machine with a

+ security manager that acts very differently from this approach,

+ but a lot of code expects behavior very close to the platform

+ default (including many classes which are part of the OpenJDK

+ implementation).

+ 

+ [[sect-Defensive_Coding-Java-SecurityManager-Compatible]]

+ ===== Security Manager Compatibility

+ 

+ A lot of code can run without any additional permissions at all,

+ with little changes. The following guidelines should help to

+ increase compatibility with a restrictive security manager.

+ 

+ * When retrieving system properties using

+ `System.getProperty(String)` or similar

+ methods, catch `SecurityException`

+ exceptions and treat the property as unset.

+ 

+ * Avoid unnecessary file system or network access.

+ 

+ * Avoid explicit class loading. Access to a suitable class

+ loader might not be available when executing as untrusted

+ code.

+ 

+ If the functionality you are implementing absolutely requires

+ privileged access and this functionality has to be used from

+ untrusted code (hopefully in a restricted and secure manner),

+ see <<sect-Defensive_Coding-Java-SecurityManager-Privileged>>.

+ 

+ [[sect-Defensive_Coding-Java-SecurityManager-Activate]]

+ ===== Activating the Security Manager

+ 

+ The usual command to launch a Java application,

+ [command]`java`, does not activate the security manager.

+ Therefore, the virtual machine does not enforce any sandboxing

+ restrictions, even if explicitly requested by the code (for

+ example, as described in <<sect-Defensive_Coding-Java-SecurityManager-Unprivileged>>).

+ 

+ The [option]`-Djava.security.manager` option activates

+ the security manager, with the fairly restrictive default

+ policy. With a very permissive policy, most Java code will run

+ unchanged. Assuming the policy in <<ex-Defensive_Coding-Java-SecurityManager-GrantAll>>

+ has been saved in a file `grant-all.policy`,

+ this policy can be activated using the option

+ [option]`-Djava.security.policy=grant-all.policy` (in

+ addition to the [option]`-Djava.security.manager`

+ option).

+ 

+ [[ex-Defensive_Coding-Java-SecurityManager-GrantAll]]

+ .Most permissve OpenJDK policy file

+ ====

+ 

+ [source,java]

+ ----

+ 

+ grant {

+       permission java.security.AllPermission;

+ };

+ 

+ ----

+ 

+ ====

+ 

+ With this most permissive policy, the security manager is still

+ active, and explicit requests to drop privileges will be

+ honored.

+ 

+ [[sect-Defensive_Coding-Java-SecurityManager-Unprivileged]]

+ ===== Reducing Trust in Code

+ 

+ The <<ex-Defensive_Coding-Java-SecurityManager-Unprivileged>> example

+ shows how to run a piece code of with reduced privileges.

+ 

+ [[ex-Defensive_Coding-Java-SecurityManager-Unprivileged]]

+ .Using the security manager to run code with reduced privileges

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Java-SecurityManager-Unprivileged.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ The example above does not add any additional permissions to the

+ `permissions` object. If such permissions are

+ necessary, code like the following (which grants read permission

+ on all files in the current directory) can be used:

+ 

+ [source,java]

+ ----

+ include::snippets/Java-SecurityManager-CurrentDirectory.adoc[]

+ 

+ ----

+ 

+ [IMPORTANT]

+ ====

+ 

+ Calls to the

+ `java.security.AccessController.doPrivileged()`

+ methods do not enforce any additional restriction if no

+ security manager has been set. Except for a few special

+ exceptions, the restrictions no longer apply if the

+ `doPrivileged()` has returned, even to

+ objects created by the code which ran with reduced privileges.

+ (This applies to object finalization in particular.)

+ 

+ The example code above does not prevent the called code from

+ calling the

+ `java.security.AccessController.doPrivileged()`

+ methods. This mechanism should be considered an additional

+ safety net, but it still can be used to prevent unexpected

+ behavior of trusted code. As long as the executed code is not

+ dynamic and came with the original application or library, the

+ sandbox is fairly effective.

+ 

+ The `context` argument in <<ex-Defensive_Coding-Java-SecurityManager-Unprivileged>>

+ is extremely important—otherwise, this code would increase

+ privileges instead of reducing them.

+ 

+ ====

+ 

+ For activating the security manager, see <<sect-Defensive_Coding-Java-SecurityManager-Activate>>.

+ Unfortunately, this affects the virtual machine as a whole, so

+ it is not possible to do this from a library.

+ 

+ [[sect-Defensive_Coding-Java-SecurityManager-Privileged]]

+ ===== Re-gaining Privileges

+ 

+ Ordinarily, when trusted code is called from untrusted code, it

+ loses its privileges (because of the untrusted stack frames

+ visible to stack inspection). The

+ `java.security.AccessController.doPrivileged()`

+ family of methods provides a controlled backdoor from untrusted

+ to trusted code.

+ 

+ [IMPORTANT]

+ ====

+ 

+ By design, this feature can undermine the Java security model

+ and the sandbox. It has to be used very carefully. Most

+ sandbox vulnerabilities can be traced back to its misuse.

+ 

+ ====

+ 

+ In essence, the `doPrivileged()` methods

+ cause the stack inspection to end at their call site. Untrusted

+ code further down the call stack becomes invisible to security

+ checks.

+ 

+ The following operations are common and safe to perform with

+ elevated privileges.

+ 

+ * Reading custom system properties with fixed names,

+ especially if the value is not propagated to untrusted code.

+ (File system paths including installation paths, host names

+ and user names are sometimes considered private information

+ and need to be protected.)

+ 

+ * Reading from the file system at fixed paths, either

+ determined at compile time or by a system property. Again,

+ leaking the file contents to the caller can be problematic.

+ 

+ * Accessing network resources under a fixed address, name or

+ URL, derived from a system property or configuration file,

+ information leaks not withstanding.

+ 

+ The <<ex-Defensive_Coding-Java-SecurityManager-Privileged>> example

+ shows how to request additional privileges.

+ 

+ [[ex-Defensive_Coding-Java-SecurityManager-Privileged]]

+ .Using the security manager to run code with increased privileges

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Java-SecurityManager-Privileged.adoc[]

+ 

+ ----

+ 

+ ====

+ 

+ Obviously, this only works if the class containing the call to

+ `doPrivileged()` is marked trusted (usually

+ because it is loaded from a trusted class loader).

+ 

+ When writing code that runs with elevated privileges, make sure

+ that you follow the rules below.

+ 

+ * Make the privileged code as small as possible. Perform as

+ many computations as possible before and after the

+ privileged code section, even if it means that you have to

+ define a new class to pass the data around.

+ 

+ * Make sure that you either control the inputs to the

+ privileged code, or that the inputs are harmless and cannot

+ affect security properties of the privileged code.

+ 

+ * Data that is returned from or written by the privileged code

+ must either be restricted (that is, it cannot be accessed by

+ untrusted code), or must be harmless. Otherwise, privacy

+ leaks or information disclosures which affect security

+ properties can be the result.

+ 

+ If the code calls back into untrusted code at a later stage (or

+ performs other actions under control from the untrusted caller),

+ you must obtain the original security context and restore it

+ before performing the callback, as in <<ex-Defensive_Coding-Java-SecurityManager-Callback>>.

+ (In this example, it would be much better to move the callback

+ invocation out of the privileged code section, of course.)

+ 

+ [[ex-Defensive_Coding-Java-SecurityManager-Callback]]

+ .Restoring privileges when invoking callbacks

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Java-SecurityManager-Callback.adoc[]

+ 

+ ----

+ 

+ ====

en-US/Java-SecurityManager.xml
file removed
-292
@@ -1,292 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <section id="sect-Defensive_Coding-Java-SecurityManager">

-   <title>Interacting with the security manager</title>

-   <para>

-     The Java platform is largely implemented in the Java language

-     itself.  Therefore, within the same JVM, code runs which is part

-     of the Java installation and which is trusted, but there might

-     also be code which comes from untrusted sources and is restricted

-     by the Java sandbox (to varying degrees).  The <emphasis>security

-     manager</emphasis> draws a line between fully trusted, partially

-     trusted and untrusted code.

-   </para>

-   <para>

-     The type safety and accessibility checks provided by the Java

-     language and JVM would be sufficient to implement a sandbox.

-     However, only some Java APIs employ such a capabilities-based

-     approach.  (The Java SE library contains many public classes with

-     public constructors which can break any security policy, such as

-     <literal>java.io.FileOutputStream</literal>.)  Instead, critical

-     functionality is protected by <emphasis>stack

-     inspection</emphasis>: At a security check, the stack is walked

-     from top (most-nested) to bottom.  The security check fails if a

-     stack frame for a method is encountered whose class lacks the

-     permission which the security check requires.

-   </para>

-   <para>

-     This simple approach would not allow untrusted code (which lacks

-     certain permissions) to call into trusted code while the latter

-     retains trust.  Such trust transitions are desirable because they

-     enable Java as an implementation language for most parts of the

-     Java platform, including security-relevant code.  Therefore, there

-     is a mechanism to mark certain stack frames as trusted (<xref

-     linkend="sect-Defensive_Coding-Java-SecurityManager-Privileged"/>).

-   </para>

-   <para>

-     In theory, it is possible to run a Java virtual machine with a

-     security manager that acts very differently from this approach,

-     but a lot of code expects behavior very close to the platform

-     default (including many classes which are part of the OpenJDK

-     implementation).

-   </para>

- 

-   <section id="sect-Defensive_Coding-Java-SecurityManager-Compatible">

-     <title>Security manager compatibility</title>

-     <para>

-       A lot of code can run without any additional permissions at all,

-       with little changes.  The following guidelines should help to

-       increase compatibility with a restrictive security manager.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  When retrieving system properties using

- 	  <function>System.getProperty(String)</function> or similar

- 	  methods, catch <literal>SecurityException</literal>

- 	  exceptions and treat the property as unset.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Avoid unnecessary file system or network access.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Avoid explicit class loading.  Access to a suitable class

- 	  loader might not be available when executing as untrusted

- 	  code.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       If the functionality you are implementing absolutely requires

-       privileged access and this functionality has to be used from

-       untrusted code (hopefully in a restricted and secure manner),

-       see <xref

-       linkend="sect-Defensive_Coding-Java-SecurityManager-Privileged"/>.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Java-SecurityManager-Activate">

-     <title>Activating the security manager</title>

-     <para>

-       The usual command to launch a Java application,

-       <command>java</command>, does not activate the security manager.

-       Therefore, the virtual machine does not enforce any sandboxing

-       restrictions, even if explicitly requested by the code (for

-       example, as described in <xref

-       linkend="sect-Defensive_Coding-Java-SecurityManager-Unprivileged"/>).

-     </para>

-     <para>

-       The <option>-Djava.security.manager</option> option activates

-       the security manager, with the fairly restrictive default

-       policy.  With a very permissive policy, most Java code will run

-       unchanged.  Assuming the policy in <xref

-       linkend="ex-Defensive_Coding-Java-SecurityManager-GrantAll"/>

-       has been saved in a file <filename>grant-all.policy</filename>,

-       this policy can be activated using the option

-       <option>-Djava.security.policy=grant-all.policy</option> (in

-       addition to the <option>-Djava.security.manager</option>

-       option).

-     </para>

-     <example id="ex-Defensive_Coding-Java-SecurityManager-GrantAll">

-       <title>Most permissve OpenJDK policy file</title>

- <programlisting>

- grant {

-       permission java.security.AllPermission;

- };

- </programlisting>

-     </example>

-     <para>

-       With this most permissive policy, the security manager is still

-       active, and explicit requests to drop privileges will be

-       honored.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Java-SecurityManager-Unprivileged">

-     <title>Reducing trust in code</title>

-     <para>

-       <xref linkend="ex-Defensive_Coding-Java-SecurityManager-Unprivileged"/>

-       shows how to run a piece code of with reduced privileges.

-     </para>

-     <example id="ex-Defensive_Coding-Java-SecurityManager-Unprivileged">

-       <title>Using the security manager to run code with reduced

-       privileges</title>

-       <xi:include href="snippets/Java-SecurityManager-Unprivileged.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       The example above does not add any additional permissions to the

-       <literal>permissions</literal> object.  If such permissions are

-       necessary, code like the following (which grants read permission

-       on all files in the current directory) can be used:

-     </para>

-     <informalexample>

-       <xi:include href="snippets/Java-SecurityManager-CurrentDirectory.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </informalexample>

-     <important>

-       <para>

- 	Calls to the

- 	<function>java.security.AccessController.doPrivileged()</function>

- 	methods do not enforce any additional restriction if no

- 	security manager has been set.  Except for a few special

- 	exceptions, the restrictions no longer apply if the

- 	<function>doPrivileged()</function> has returned, even to

- 	objects created by the code which ran with reduced privileges.

- 	(This applies to object finalization in particular.)

-       </para>

-       <para>

- 	The example code above does not prevent the called code from

- 	calling the

- 	<function>java.security.AccessController.doPrivileged()</function>

- 	methods.  This mechanism should be considered an additional

- 	safety net, but it still can be used to prevent unexpected

- 	behavior of trusted code.  As long as the executed code is not

- 	dynamic and came with the original application or library, the

- 	sandbox is fairly effective.

-       </para>

-       <para>

- 	The <literal>context</literal> argument in <xref

- 	linkend="ex-Defensive_Coding-Java-SecurityManager-Unprivileged"/>

- 	is extremely important—otherwise, this code would increase

- 	privileges instead of reducing them.

-       </para>

-     </important>

-     <para>

-       For activating the security manager, see <xref

-       linkend="sect-Defensive_Coding-Java-SecurityManager-Activate"/>.

-       Unfortunately, this affects the virtual machine as a whole, so

-       it is not possible to do this from a library.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Java-SecurityManager-Privileged">

-     <title>Re-gaining privileges</title>

-     <para>

-       Ordinarily, when trusted code is called from untrusted code, it

-       loses its privileges (because of the untrusted stack frames

-       visible to stack inspection).  The

-       <function>java.security.AccessController.doPrivileged()</function>

-       family of methods provides a controlled backdoor from untrusted

-       to trusted code.

-     </para>

-     <important>

-       <para>

- 	By design, this feature can undermine the Java security model

- 	and the sandbox.  It has to be used very carefully.  Most

- 	sandbox vulnerabilities can be traced back to its misuse.

-        </para>

-     </important>

-     <para>

-       In essence, the <function>doPrivileged()</function> methods

-       cause the stack inspection to end at their call site.  Untrusted

-       code further down the call stack becomes invisible to security

-       checks.

-     </para>

-     <para>

-       The following operations are common and safe to perform with

-       elevated privileges.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Reading custom system properties with fixed names,

- 	  especially if the value is not propagated to untrusted code.

- 	  (File system paths including installation paths, host names

- 	  and user names are sometimes considered private information

- 	  and need to be protected.)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Reading from the file system at fixed paths, either

- 	  determined at compile time or by a system property.  Again,

- 	  leaking the file contents to the caller can be problematic.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Accessing network resources under a fixed address, name or

- 	  URL, derived from a system property or configuration file,

- 	  information leaks not withstanding.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       <xref linkend="ex-Defensive_Coding-Java-SecurityManager-Privileged"/>

-       shows how to request additional privileges.

-     </para>

-     <example id="ex-Defensive_Coding-Java-SecurityManager-Privileged">

-       <title>Using the security manager to run code with increased

-       privileges</title>

-       <xi:include href="snippets/Java-SecurityManager-Privileged.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-     <para>

-       Obviously, this only works if the class containing the call to

-       <function>doPrivileged()</function> is marked trusted (usually

-       because it is loaded from a trusted class loader).

-     </para>

-     <para>

-       When writing code that runs with elevated privileges, make sure

-       that you follow the rules below.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Make the privileged code as small as possible.  Perform as

- 	  many computations as possible before and after the

- 	  privileged code section, even if it means that you have to

- 	  define a new class to pass the data around.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Make sure that you either control the inputs to the

- 	  privileged code, or that the inputs are harmless and cannot

- 	  affect security properties of the privileged code.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Data that is returned from or written by the privileged code

- 	  must either be restricted (that is, it cannot be accessed by

- 	  untrusted code), or must be harmless.  Otherwise, privacy

- 	  leaks or information disclosures which affect security

- 	  properties can be the result.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       If the code calls back into untrusted code at a later stage (or

-       performs other actions under control from the untrusted caller),

-       you must obtain the original security context and restore it

-       before performing the callback, as in <xref

-       linkend="ex-Defensive_Coding-Java-SecurityManager-Callback"/>.

-       (In this example, it would be much better to move the callback

-       invocation out of the privileged code section, of course.)

-     </para>

-     <example id="ex-Defensive_Coding-Java-SecurityManager-Callback">

-       <title>Restoring privileges when invoking callbacks</title>

-       <xi:include href="snippets/Java-SecurityManager-Callback.xml"

- 		  xmlns:xi="http://www.w3.org/2001/XInclude" />

-     </example>

-   </section>

- 

- </section>

- 

en-US/Java.adoc
file added
+11
@@ -0,0 +1,11 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Java]]

+ === The Java Programming Language

+ 

+ include::Java-Language.adoc[]

+ 

+ include::Java-LowLevel.adoc[]

+ 

+ include::Java-SecurityManager.adoc[] 

\ No newline at end of file

en-US/Java.xml
file removed
-11
@@ -1,11 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Java">

-   <title>The Java Programming Language</title>

- 

-   <xi:include href="Java-Language.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-   <xi:include href="Java-LowLevel.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-   <xi:include href="Java-SecurityManager.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

- </chapter>

- 

en-US/Python.adoc
file added
+51
@@ -0,0 +1,51 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Python]]

+ === The Python Programming Language

+ 

+ Python provides memory safety by default, so low-level security

+ vulnerabilities are rare and typically needs fixing the Python

+ interpreter or standard library itself.

+ 

+ Other sections with Python-specific advice include:

+ 

+ * <<chap-Defensive_Coding-Tasks-Temporary_Files>>

+ 

+ * <<sect-Defensive_Coding-Tasks-Processes-Creation>>

+ 

+ * <<chap-Defensive_Coding-Tasks-Serialization>>, in

+ particular <<sect-Defensive_Coding-Tasks-Serialization-Library>>

+ 

+ * <<sect-Defensive_Coding-Tasks-Cryptography-Randomness>>

+ 

+ ==== Dangerous Standard Library Features

+ 

+ Some areas of the standard library, notably the

+ `ctypes` module, do not provide memory safety

+ guarantees comparable to the rest of Python. If such

+ functionality is used, the advice in <<sect-Defensive_Coding-C-Language>> should be followed.

+ 

+ ==== Run-time Compilation and Code Generation

+ 

+ The following Python functions and statements related to code

+ execution should be avoided:

+ 

+ * `compile`

+ 

+ * `eval`

+ 

+ * `exec`

+ 

+ * `execfile`

+ 

+ If you need to parse integers or floating point values, use the

+ `int` and `float`

+ functions instead of `eval`. Sandboxing

+ untrusted Python code does not work reliably.

+ 

+ ==== Sandboxing

+ 

+ The `rexec` Python module cannot safely sandbox

+ untrusted code and should not be used. The standard CPython

+ implementation is not suitable for sandboxing. 

\ No newline at end of file

en-US/Python.xml
file removed
-74
@@ -1,74 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Python">

-   <title>The Python Programming Language</title>

-   <para>

-     Python provides memory safety by default, so low-level security

-     vulnerabilities are rare and typically needs fixing the Python

-     interpreter or standard library itself.

-   </para>

-   <para>

-     Other sections with Python-specific advice include:

-   </para>

-   <itemizedlist>

-     <listitem>

-       <para>

- 	<xref linkend="chap-Defensive_Coding-Tasks-Temporary_Files"/>

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	<xref linkend="sect-Defensive_Coding-Tasks-Processes-Creation"/>

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	<xref linkend="chap-Defensive_Coding-Tasks-Serialization"/>, in

- 	particular <xref linkend="sect-Defensive_Coding-Tasks-Serialization-Library"/>

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	<xref linkend="sect-Defensive_Coding-Tasks-Cryptography-Randomness"/>

-       </para>

-     </listitem>

-   </itemizedlist>

-   <section>

-     <title>Dangerous standard library features</title>

-     <para>

-       Some areas of the standard library, notably the

-       <literal>ctypes</literal> module, do not provide memory safety

-       guarantees comparable to the rest of Python.  If such

-       functionality is used, the advice in <xref

-       linkend="sect-Defensive_Coding-C-Language"/> should be followed.

-     </para>

-   </section>

-   <section>

-     <title>Run-time compilation and code generation</title>

-     <para>

-       The following Python functions and statements related to code

-       execution should be avoided:

-     </para>

-     <itemizedlist>

-       <listitem><para><function>compile</function></para></listitem>

-       <listitem><para><function>eval</function></para></listitem>

-       <listitem><para><literal>exec</literal></para></listitem>

-       <listitem><para><function>execfile</function></para></listitem>

-     </itemizedlist>

-     <para>

-       If you need to parse integers or floating point values, use the

-       <function>int</function> and <function>float</function>

-       functions instead of <function>eval</function>.  Sandboxing

-       untrusted Python code does not work reliably.

-     </para>

-   </section>

-   <section>

-     <title>Sandboxing</title>

-     <para>

-       The <literal>rexec</literal> Python module cannot safely sandbox

-       untrusted code and should not be used.  The standard CPython

-       implementation is not suitable for sandboxing.

-     </para>

-   </section>

- </chapter>

en-US/Revision_History.adoc
file added
+60
@@ -0,0 +1,60 @@

+ 

+ :experimental:

+ 

+ [[appe-Defensive_Coding-Revision_History]]

+ == Revision History

+ 

+ `1.5`:: Fri Dec 1 2017, Mirek Jahoda (mjahoda@redhat.com)

+ 

+ * First release in AsciiDoc

+ 

+ * Many updates in the crypto-related sections

+ 

+ * Grammar and typography fixes

+ 

+ `1.3-1`:: Mon Oct 13 2014, Florian Weimer (fweimer@redhat.com)

+ 

+ * Go: Mention default value handling in deserialization

+ 

+ * Shell: New chapter

+ 

+ `1.2-1`:: Wed Jul 16 2014, Florian Weimer (fweimer@redhat.com)

+ 

+ * C: Corrected the `strncat` example

+ 

+ * C: Mention mixed signed/unsigned comparisons

+ 

+ * C: Unsigned overflow checking example

+ 

+ * C++: `operator new[]` has been fixed in GCC

+ 

+ * C++: Additional material on `std::string`, iterators

+ 

+ * OpenSSL: Mention [command]`openssl genrsa` entropy issue

+ 

+ * Packaging: X.509 key generation

+ 

+ * Go, Vala: Add short chapters

+ 

+ * Serialization: Notes on fragmentation and reassembly

+ 

+ `1.1-1`:: Tue Aug 27 2013, Eric Christensen (sparks@redhat.com)

+ 

+ * Add a chapter which covers some Java topics.

+ 

+ * Deserialization: Warn about Java's java.beans.XMLDecoder.

+ 

+ * C: Correct the advice on array allocation

+ (link:++https://bugzilla.redhat.com/show_bug.cgi?id=995595++[bug 995595]).

+ 

+ * C: Add material on global variables.

+ 

+ `1.0-1`:: Thu May 09 2013, Eric Christensen (sparks@redhat.com)

+ 

+ * Added more C and C++ examples.

+ 

+ * TLS Client NSS: Rely on NSS 3.14 cipher suite defaults.

+ 

+ `0-1`:: Thu Mar 7 2013, Eric Christensen (sparks@redhat.com)

+ 

+ * Initial publication. 

\ No newline at end of file

en-US/Revision_History.xml
file removed
-96
@@ -1,96 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- <!ENTITY % BOOK_ENTITIES SYSTEM "Defensive_Coding.ent">

- %BOOK_ENTITIES;

- ]>

- <appendix id="appe-Defensive_Coding-Revision_History">

-   <title>Revision History</title>

-   <simpara>

-     <revhistory>

-       <revision>

-         <revnumber>1.3-1</revnumber>

- 	<date>Mon Oct 13 2014</date>

-         <author>

-           <firstname>Florian</firstname>

-           <surname>Weimer</surname>

-           <email>fweimer@redhat.com</email>

-         </author>

-         <revdescription>

-           <simplelist>

- 	    <member>Go: Mention default value handling in deserialization</member>

- 	    <member>Shell: New chapter</member>

- 	  </simplelist>

- 	</revdescription>

-       </revision>

-       <revision>

-         <revnumber>1.2-1</revnumber>

-         <date>Wed Jul 16 2014</date>

-         <author>

-           <firstname>Florian</firstname>

-           <surname>Weimer</surname>

-           <email>fweimer@redhat.com</email>

-         </author>

-         <revdescription>

-           <simplelist>

-             <member>C: Corrected the <function>strncat</function> example</member>

- 	    <member>C: Mention mixed signed/unsigned comparisons</member>

- 	    <member>C: Unsigned overflow checking example</member>

- 	    <member>C++: <literal>operator new[]</literal> has been fixed in GCC</member>

- 	    <member>C++: Additional material on <literal>std::string</literal>, iterators</member>

- 	    <member>OpenSSL: Mention <command>openssl genrsa</command> entropy issue</member>

- 	    <member>Packaging: X.509 key generation</member>

- 	    <member>Go, Vala: Add short chapters</member>

- 	    <member>Serialization: Notes on fragmentation and reassembly</member>

-           </simplelist>

-         </revdescription>

-       </revision>

-       <revision>

-         <revnumber>1.1-1</revnumber>

-         <date>Tue Aug 27 2013</date>

-         <author>

-           <firstname>Eric</firstname>

-           <surname>Christensen</surname>

-           <email>sparks@redhat.com</email>

-         </author>

-         <revdescription>

-           <simplelist>

-             <member>Add a chapter which covers some Java topics.</member>

- 	    <member>Deserialization: Warn about Java's java.beans.XMLDecoder.</member>

- 	    <member>C: Correct the advice on array allocation

- 	    (<ulink url="https://bugzilla.redhat.com/show_bug.cgi?id=995595">bug 995595</ulink>).</member>

- 	    <member>C: Add material on global variables.</member>

-           </simplelist>

-         </revdescription>

-       </revision>

-       <revision>

-         <revnumber>1.0-1</revnumber>

-         <date>Thu May 09 2013</date>

-         <author>

-           <firstname>Eric</firstname>

-           <surname>Christensen</surname>

-           <email>sparks@redhat.com</email>

-         </author>

-         <revdescription>

-           <simplelist>

-             <member>Added more C and C++ examples.</member>

- 	    <member>TLS Client NSS: Rely on NSS 3.14 cipher suite defaults.</member>

-           </simplelist>

-         </revdescription>

-       </revision>

-       <revision>

- 	<revnumber>0-1</revnumber>

- 	<date>Thu Mar 7 2013</date>

- 	<author>

- 	  <firstname>Eric</firstname>

- 	  <surname>Christensen</surname>

- 	  <email>sparks@redhat.com</email>

- 	</author>

- 	<revdescription>

- 	  <simplelist>

- 	    <member>Initial publication.</member>

- 	  </simplelist>

- 	</revdescription>

-       </revision>

-     </revhistory>

-   </simpara>

- </appendix>

en-US/Shell.adoc
file added
+395
@@ -0,0 +1,395 @@

+ 

+ :experimental:

+ include::entities.adoc[]

+ 

+ [[chap-Defensive_Coding-Shell]]

+ === Shell Programming and [application]*bash*

+ 

+ This chapter contains advice about shell programming, specifically

+ in [application]*bash*. Most of the advice will apply

+ to scripts written for other shells because extensions such as

+ integer or array variables have been implemented there as well, with

+ comparable syntax.

+ 

+ [[sect-Defensive_Coding-Shell-Alternatives]]

+ ==== Consider Alternatives

+ 

+ Once a shell script is so complex that advice in this chapter

+ applies, it is time to step back and consider the question: Is

+ there a more suitable implementation language available?

+ 

+ For example, Python with its `subprocess` module

+ can be used to write scripts which are almost as concise as shell

+ scripts when it comes to invoking external programs, and Python

+ offers richer data structures, with less arcane syntax and more

+ consistent behavior.

+ 

+ [[sect-Defensive_Coding-Shell-Language]]

+ ==== Shell Language Features

+ 

+ The following sections cover subtleties concerning the shell

+ programming languages. They have been written with the

+ [application]*bash* shell in mind, but some of these

+ features apply to other shells as well.

+ 

+ Some of the features described may seem like implementation defects,

+ but these features have been replicated across multiple independent

+ implementations, so they now have to be considered part of the shell

+ programming language.

+ 

+ [[sect-Defensive_Coding-Shell-Parameter_Expansion]]

+ ===== Parameter Expansion

+ 

+ The mechanism by which named shell variables and parameters are

+ expanded is called *parameter expansion*. The

+ most basic syntax is

+ “pass:attributes[{blank}]`$`pass:attributes[{blank}]pass:attributes[{blank}]*variable*pass:attributes[{blank}]” or

+ “pass:attributes[{blank}]`${`pass:attributes[{blank}]pass:attributes[{blank}]*variable*pass:attributes[{blank}]pass:attributes[{blank}]`}`pass:attributes[{blank}]”.

+ 

+ In almost all cases, a parameter expansion should be enclosed in

+ double quotation marks `"`pass:attributes[{blank}]…pass:attributes[{blank}]`"`.

+ 

+ [source,bash]

+ ----

+ 

+ external-program "$arg1" "$arg2"

+     

+ ----

+ 

+ If the double quotation marks are omitted, the value of the

+ variable will be split according to the current value of the

+ `IFS` variable. This may allow the injection of

+ additional options which are then processed by

+ `external-program`.

+ 

+ Parameter expansion can use special syntax for specific features,

+ such as substituting defaults or performing string or array

+ operations. These constructs should not be used because they can

+ trigger arithmetic evaluation, which can result in code execution.

+ See <<sect-Defensive_Coding-Shell-Arithmetic>>.

+ 

+ [[sect-Defensive_Coding-Shell-Double_Expansion]]

+ ===== Double Expansion

+ 

+ *Double expansion* occurs when, during the

+ expansion of a shell variable, not just the variable is expanded,

+ replacing it by its value, but the *value* of

+ the variable is itself is expanded as well. This can trigger

+ arbitrary code execution, unless the value of the variable is

+ verified against a restrictive pattern.

+ 

+ The evaluation process is in fact recursive, so a self-referential

+ expression can cause an out-of-memory condition and a shell crash.

+ 

+ Double expansion may seem like as a defect, but it is implemented

+ by many shells, and has to be considered an integral part of the

+ shell programming language. However, it does make writing robust

+ shell scripts difficult.

+ 

+ Double expansion can be requested explicitly with the

+ `eval` built-in command, or by invoking a

+ subshell with “pass:attributes[{blank}]`bash -c`pass:attributes[{blank}]”. These constructs

+ should not be used.

+ 

+ The following sections give examples of places where implicit

+ double expansion occurs.

+ 

+ [[sect-Defensive_Coding-Shell-Arithmetic]]

+ ====== Arithmetic Evaluation

+ 

+ *Arithmetic evaluation* is a process by which

+ the shell computes the integer value of an expression specified

+ as a string. It is highly problematic for two reasons: It

+ triggers double expansion (see <<sect-Defensive_Coding-Shell-Double_Expansion>>), and the

+ language of arithmetic expressions is not self-contained. Some

+ constructs in arithmetic expressions (notably array subscripts)

+ provide a trapdoor from the restricted language of arithmetic

+ expressions to the full shell language, thus paving the way

+ towards arbitrary code execution. Due to double expansion,

+ input which is (indirectly) referenced from an arithmetic

+ expression can trigger execution of arbitrary code, which is

+ potentially harmful.

+ 

+ Arithmetic evaluation is triggered by the follow constructs:

+ 

+ * The *expression* in

+ “pass:attributes[{blank}]`$((`pass:attributes[{blank}]pass:attributes[{blank}]*expression*pass:attributes[{blank}]pass:attributes[{blank}]`))`pass:attributes[{blank}]”

+ is evaluated. This construct is called *arithmetic

+ expansion*.

+ 

+ * {blank}

+ +

+ “pass:attributes[{blank}]`$[`pass:attributes[{blank}]pass:attributes[{blank}]*expression*pass:attributes[{blank}]pass:attributes[{blank}]`]`pass:attributes[{blank}]”

+ is a deprecated syntax with the same effect.

+ 

+ * The arguments to the `let` shell built-in

+ are evaluated.

+ 

+ * {blank}

+ +

+ “pass:attributes[{blank}]`((`pass:attributes[{blank}]pass:attributes[{blank}]*expression*pass:attributes[{blank}]pass:attributes[{blank}]`))`pass:attributes[{blank}]”

+ is an alternative syntax for “pass:attributes[{blank}]`let` *expression*pass:attributes[{blank}]”.

+ 

+ * Conditional expressions surrounded by

+ “pass:attributes[{blank}]`[[`pass:attributes[{blank}]…pass:attributes[{blank}]`]]`pass:attributes[{blank}]” can trigger

+ arithmetic evaluation if certain operators such as

+ `-eq` are used. (The

+ `test` built-in does not perform arithmetic

+ evaluation, even with integer operators such as

+ `-eq`.)

+ +

+ The conditional expression

+ “pass:attributes[{blank}]`[[ $`pass:attributes[{blank}]pass:attributes[{blank}]*variable* `=~` *regexp* `]]`pass:attributes[{blank}]”

+ can be used for input validation, assuming that

+ *regexp* is a constant regular

+ expression.

+ See <<sect-Defensive_Coding-Shell-Input_Validation>>.

+ 

+ * Certain parameter expansions, for example

+ “pass:attributes[{blank}]`${`pass:attributes[{blank}]pass:attributes[{blank}]*variable*pass:attributes[{blank}]pass:attributes[{blank}]`[`pass:attributes[{blank}]pass:attributes[{blank}]*expression*pass:attributes[{blank}]pass:attributes[{blank}]`]}`pass:attributes[{blank}]”

+ (array indexing) or

+ “pass:attributes[{blank}]`${`pass:attributes[{blank}]pass:attributes[{blank}]*variable*pass:attributes[{blank}]pass:attributes[{blank}]`:`pass:attributes[{blank}]pass:attributes[{blank}]*expression*pass:attributes[{blank}]pass:attributes[{blank}]`}`pass:attributes[{blank}]”

+ (string slicing), trigger arithmetic evaluation of

+ *expression*.

+ 

+ * Assignment to array elements using

+ “pass:attributes[{blank}]*array_variable*pass:attributes[{blank}]pass:attributes[{blank}]`[`pass:attributes[{blank}]pass:attributes[{blank}]*subscript*pass:attributes[{blank}]pass:attributes[{blank}]`]=`pass:attributes[{blank}]pass:attributes[{blank}]*expression*pass:attributes[{blank}]”

+ triggers evaluation of *subscript*, but

+ not *expression*.

+ 

+ * The expressions in the arithmetic `for`

+ command,

+ “pass:attributes[{blank}]`for ((`pass:attributes[{blank}]pass:attributes[{blank}]*expression1*pass:attributes[{blank}]pass:attributes[{blank}]`;` *expression2*pass:attributes[{blank}]pass:attributes[{blank}]`;` *expression3*pass:attributes[{blank}]pass:attributes[{blank}]`)); do` *commands*pass:attributes[{blank}]pass:attributes[{blank}]`; done`pass:attributes[{blank}]”

+ are evaluated. This does not apply to the regular

+ for command,

+ “pass:attributes[{blank}]`for` *variable* `in` *list*pass:attributes[{blank}]pass:attributes[{blank}]`; do` *commands*pass:attributes[{blank}]pass:attributes[{blank}]`; done`pass:attributes[{blank}]”.

+ 

+ [IMPORTANT]

+ ====

+ 

+ Depending on the [application]*bash* version, the

+ above list may be incomplete.

+ 

+ If faced with a situation where using such shell features

+ appears necessary, see <<sect-Defensive_Coding-Shell-Alternatives>>.

+ 

+ ====

+ 

+ If it is impossible to avoid shell arithmetic on untrusted

+ inputs, refer to <<sect-Defensive_Coding-Shell-Input_Validation>>.

+ 

+ [[sect-Defensive_Coding-Shell-Types]]

+ ====== Type declarations

+ 

+ [application]*bash* supports explicit type

+ declarations for shell variables:

+ 

+ [source,bash]

+ ----

+ 

+ 	declare -i integer_variable

+ 	declare -a array_variable

+ 	declare -A assoc_array_variable

+ 

+ 	typeset -i integer_variable

+ 	typeset -a array_variable

+ 	typeset -A assoc_array_variable

+ 

+ 	local -i integer_variable

+ 	local -a array_variable

+ 	local -A assoc_array_variable

+ 

+ 	readonly -i integer_variable

+ 	readonly -a array_variable

+ 	readonly -A assoc_array_variable

+       

+ ----

+ 

+ Variables can also be declared as arrays by assigning them an

+ array expression, as in:

+ 

+ [source,bash]

+ ----

+ 

+ array_variable=(1 2 3 4)

+       

+ ----

+ 

+ Some built-ins (such as `mapfile`) can

+ implicitly create array variables.

+ 

+ Such type declarations should not be used because assignment to

+ such variables (independent of the concrete syntax used for the

+ assignment) triggers arithmetic expansion (and thus double

+ expansion) of the right-hand side of the assignment operation.

+ See <<sect-Defensive_Coding-Shell-Arithmetic>>.

+ 

+ Shell scripts which use integer or array variables should be

+ rewritten in another, more suitable language. Se <<sect-Defensive_Coding-Shell-Alternatives>>.

+ 

+ [[sect-Defensive_Coding-Shell-Obscure]]

+ ===== Other Obscurities

+ 

+ Obscure shell language features should not be used. Examples are:

+ 

+ * Exported functions (`export -f` or

+ `declare -f`).

+ 

+ * Function names which are not valid variable names, such as

+ “pass:attributes[{blank}]`module::function`pass:attributes[{blank}]”.

+ 

+ * The possibility to override built-ins or external commands

+ with shell functions.

+ 

+ * Changing the value of the `IFS` variable to

+ tokenize strings.

+ 

+ [[sect-Defensive_Coding-Shell-Invoke]]

+ ==== Invoking External Commands

+ 

+ When passing shell variables as single command line arguments,

+ they should always be surrounded by double quotes. See

+ <<sect-Defensive_Coding-Shell-Parameter_Expansion>>.

+ 

+ Care is required when passing untrusted values as positional

+ parameters to external commands. If the value starts with a hyphen

+ “pass:attributes[{blank}]`-`pass:attributes[{blank}]”, it may be interpreted by the external

+ command as an option. Depending on the external program, a

+ “pass:attributes[{blank}]`--`pass:attributes[{blank}]” argument stops option processing and treats

+ all following arguments as positional parameters. (Double quotes

+ are completely invisible to the command being invoked, so they do

+ not prevent variable values from being interpreted as options.)

+ 

+ Cleaning the environment before invoking child processes is

+ difficult to implement in script. [application]*bash*

+ keeps a hidden list of environment variables which do not correspond

+ to shell variables, and unsetting them from within a

+ [application]*bash* script is not possible. To reset

+ the environment, a script can re-run itself under the “pass:attributes[{blank}]`env

+ -i`pass:attributes[{blank}]” command with an additional parameter which indicates

+ the environment has been cleared and suppresses a further

+ self-execution. Alternatively, individual commands can be executed

+ with “pass:attributes[{blank}]`env -i`pass:attributes[{blank}]”.

+ 

+ [IMPORTANT]

+ ====

+ 

+ Complete isolation from its original execution environment

+ (which is required when the script is executed after a trust

+ transition, e.g., triggered by the SUID mechanism) is impossible

+ to achieve from within the shell script itself. Instead, the

+ invoking process has to clear the process environment (except for

+ few trusted variables) before running the shell script.

+ 

+ ====

+ 

+ Checking for failures in executed external commands is recommended.

+ If no elaborate error recovery is needed, invoking “pass:attributes[{blank}]`set

+ -e`pass:attributes[{blank}]” may be sufficient. This causes the script to stop on

+ the first failed command. However, failures in pipes

+ (“pass:attributes[{blank}]`command1 | command2`pass:attributes[{blank}]”) are only detected for the

+ last command in the pipe, errors in previous commands are ignored.

+ This can be changed by invoking “pass:attributes[{blank}]`set -o pipefail`pass:attributes[{blank}]”.

+ Due to architectural limitations, only the process that spawned

+ the entire pipe can check for failures in individual commands;

+ it is not possible for a process to tell if the process feeding

+ data (or the process consuming data) exited normally or with 

+ an error.

+ 

+ See <<sect-Defensive_Coding-Tasks-Processes-Creation>>

+ for additional details on creating child processes.

+ 

+ [[sect-Defensive_Coding-Shell-Temporary_Files]]

+ ==== Temporary Files

+ 

+ Temporary files should be created with the

+ `mktemp` command, and temporary directories with

+ “pass:attributes[{blank}]`mktemp -d`pass:attributes[{blank}]”.

+ 

+ To clean up temporary files and directories, write a clean-up

+ shell function and register it as a trap handler, as shown in

+ <<ex-Defensive_Coding-Tasks-Temporary_Files>>.

+ Using a separate function avoids issues with proper quoting of

+ variables.

+ 

+ [[ex-Defensive_Coding-Tasks-Temporary_Files]]

+ .Creating and Cleaning up Temporary Files

+ ====

+ 

+ [source,bash]

+ ----

+ 

+ tmpfile="$(mktemp)"

+ 

+ cleanup () {

+     rm -f -- "$tmpfile"

+ }

+ 

+ trap cleanup 0

+    

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-Shell-Input_Validation]]

+ ==== Performing Input Validation

+ 

+ In some cases, input validation cannot be avoided. For example,

+ if arithmetic evaluation is absolutely required, it is imperative

+ to check that input values are, in fact, integers. See <<sect-Defensive_Coding-Shell-Arithmetic>>.

+ 

+ <<ex-Defensive_Coding-Shell-Input_Validation>>

+ shows a construct which can be used to check if a string

+ “pass:attributes[{blank}]`$value`pass:attributes[{blank}]” is an integer. This construct is

+ specific to [application]*bash* and not portable to

+ POSIX shells.

+ 

+ [[ex-Defensive_Coding-Shell-Input_Validation]]

+ .Input validation in [application]*bash*

+ ====

+ 

+ [source,bash]

+ ----

+ include::snippets/Shell-Input_Validation.adoc[]

+ 		

+ ----

+ 

+ ====

+ 

+ Using `case` statements for input validation is

+ also possible and supported by other (POSIX) shells, but the

+ pattern language is more restrictive, and it can be difficult to

+ write suitable patterns.

+ 

+ The `expr` external command can give misleading

+ results (e.g., if the value being checked contains operators

+ itself) and should not be used.

+ 

+ [[sect-Defensive_Coding-Shell-Edit_Guard]]

+ ==== Guarding Shell Scripts Against Changes

+ 

+ [application]*bash* only reads a shell script up to

+ the point it is needed for executed the next command. This means

+ that if script is overwritten while it is running, execution can

+ jump to a random part of the script, depending on what is modified

+ in the script and how the file offsets change as a result. (This

+ behavior is needed to support self-extracting shell archives whose

+ script part is followed by a stream of bytes which does not follow

+ the shell language syntax.)

+ 

+ Therefore, long-running scripts should be guarded against

+ concurrent modification by putting as much of the program logic

+ into a `main` function, and invoking the

+ `main` function at the end of the script, using

+ this syntax:

+ 

+ [source,bash]

+ ----

+ 

+ main "$@" ; exit $?

+     

+ ----

+ 

+ This construct ensures that [application]*bash* will

+ stop execution after the `main` function, instead

+ of opening the script file and trying to read more commands.

en-US/Shell.xml
file removed
-454
@@ -1,454 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Shell">

- <title>Shell Programming and <application>bash</application></title>

- <para>

-   This chapter contains advice about shell programming, specifically

-   in <application>bash</application>.  Most of the advice will apply

-   to scripts written for other shells because extensions such as

-   integer or array variables have been implemented there as well, with

-   comparable syntax.

- </para>

- <section id="sect-Defensive_Coding-Shell-Alternatives">

-   <title>Consider alternatives</title>

-   <para>

-     Once a shell script is so complex that advice in this chapter

-     applies, it is time to step back and consider the question: Is

-     there a more suitable implementation language available?

-   </para>

-   <para>

-     For example, Python with its <literal>subprocess</literal> module

-     can be used to write scripts which are almost as concise as shell

-     scripts when it comes to invoking external programs, and Python

-     offers richer data structures, with less arcane syntax and more

-     consistent behavior.

-   </para>

- </section>

- <section id="sect-Defensive_Coding-Shell-Language">

- <title>Shell language features</title>

- <para>

-   The following sections cover subtleties concerning the shell

-   programming languages.  They have been written with the

-   <application>bash</application> shell in mind, but some of these

-   features apply to other shells as well.

- </para>

- <para>

-   Some of the features described may seem like implementation defects,

-   but these features have been replicated across multiple independent

-   implementations, so they now have to be considered part of the shell

-   programming language.

- </para>

- <section id="sect-Defensive_Coding-Shell-Parameter_Expansion">

-   <title>Parameter expansion</title>

-   <para>

-     The mechanism by which named shell variables and parameters are

-     expanded is called <emphasis>parameter expansion</emphasis>.  The

-     most basic syntax is

-     “<literal>$</literal><emphasis>variable</emphasis>” or

-     “<literal>${</literal><emphasis>variable</emphasis><literal>}</literal>”.

-   </para>

-   <para>

-     In almost all cases, a parameter expansion should be enclosed in

-     double quotation marks <literal>"</literal>…<literal>"</literal>.

-   </para>

-   <informalexample>

-     <programlisting language="Bash">

- external-program "$arg1" "$arg2"

-     </programlisting>

-   </informalexample>

-   <para>

-     If the double quotation marks are omitted, the value of the

-     variable will be split according to the current value of the

-     <envar>IFS</envar> variable.  This may allow the injection of

-     additional options which are then processed by

-     <literal>external-program</literal>.

-   </para>

-   <para>

-     Parameter expansion can use special syntax for specific features,

-     such as substituting defaults or performing string or array

-     operations.  These constructs should not be used because they can

-     trigger arithmetic evaluation, which can result in code execution.

-     See <xref linkend="sect-Defensive_Coding-Shell-Arithmetic"/>.

-   </para>

- </section>

- <section id="sect-Defensive_Coding-Shell-Double_Expansion">

-   <title>Double expansion</title>

-   <para>

-     <emphasis>Double expansion</emphasis> occurs when, during the

-     expansion of a shell variable, not just the variable is expanded,

-     replacing it by its value, but the <emphasis>value</emphasis> of

-     the variable is itself is expanded as well.  This can trigger

-     arbitrary code execution, unless the value of the variable is

-     verified against a restrictive pattern.

-   </para>

-   <para>

-     The evaluation process is in fact recursive, so a self-referential

-     expression can cause an out-of-memory condition and a shell crash.

-   </para>

-   <para>

-     Double expansion may seem like as a defect, but it is implemented

-     by many shells, and has to be considered an integral part of the

-     shell programming language.  However, it does make writing robust

-     shell scripts difficult.

-   </para>

-   <para>

-     Double expansion can be requested explicitly with the

-     <literal>eval</literal> built-in command, or by invoking a

-     subshell with “<literal>bash -c</literal>”.  These constructs

-     should not be used.

-   </para>

-   <para>

-     The following sections give examples of places where implicit

-     double expansion occurs.

-   </para>

-   <section id="sect-Defensive_Coding-Shell-Arithmetic">

-     <title>Arithmetic evaluation</title>

-     <para>

-       <emphasis>Arithmetic evaluation</emphasis> is a process by which

-       the shell computes the integer value of an expression specified

-       as a string.  It is highly problematic for two reasons: It

-       triggers double expansion (see <xref

-       linkend="sect-Defensive_Coding-Shell-Double_Expansion"/>), and the

-       language of arithmetic expressions is not self-contained.  Some

-       constructs in arithmetic expressions (notably array subscripts)

-       provide a trapdoor from the restricted language of arithmetic

-       expressions to the full shell language, thus paving the way

-       towards arbitrary code execution.  Due to double expansion,

-       input which is (indirectly) referenced from an arithmetic

-       expression can trigger execution of arbitrary code, which is

-       potentially harmful.

-     </para>

-     <para>

-       Arithmetic evaluation is triggered by the follow constructs:

-     </para>

-     <!-- The list was constructed by looking at the bash sources and

-          search for the string "expand_". -->

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  The <emphasis>expression</emphasis> in

- 	  “<literal>$((</literal><emphasis>expression</emphasis><literal>))</literal>”

- 	  is evaluated.  This construct is called <emphasis>arithmetic

- 	  expansion</emphasis>.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  “<literal>$[</literal><emphasis>expression</emphasis><literal>]</literal>”

- 	  is a deprecated syntax with the same effect.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The arguments to the <literal>let</literal> shell built-in

- 	  are evaluated.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  “<literal>((</literal><emphasis>expression</emphasis><literal>))</literal>”

- 	  is an alternative syntax for “<literal>let

- 	  </literal><emphasis>expression</emphasis>”.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Conditional expressions surrounded by

- 	  “<literal>[[</literal>…<literal>]]</literal>” can trigger

- 	  arithmetic evaluation if certain operators such as

- 	  <literal>-eq</literal> are used.  (The

- 	  <literal>test</literal> built-in does not perform arithmetic

- 	  evaluation, even with integer operators such as

- 	  <literal>-eq</literal>.)

- 	</para>

- 	<para>

- 	  The conditional expression

- 	  “<literal>[[ $</literal><emphasis>variable</emphasis><literal> =~ </literal><emphasis>regexp</emphasis><literal> ]]</literal>”

- 	  can be used for input validation, assuming that

- 	  <emphasis>regexp</emphasis> is a constant regular

- 	  expression.

- 	  See <xref linkend="sect-Defensive_Coding-Shell-Input_Validation"/>.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Certain parameter expansions, for example

- 	  “<literal>${</literal><emphasis>variable</emphasis><literal>[</literal><emphasis>expression</emphasis><literal>]}</literal>”

- 	  (array indexing) or

- 	  “<literal>${</literal><emphasis>variable</emphasis><literal>:</literal><emphasis>expression</emphasis><literal>}</literal>”

- 	  (string slicing), trigger arithmetic evaluation of

- 	  <emphasis>expression</emphasis>.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Assignment to array elements using

- 	  “<emphasis>array_variable</emphasis><literal>[</literal><emphasis>subscript</emphasis><literal>]=</literal><emphasis>expression</emphasis>”

- 	  triggers evaluation of <emphasis>subscript</emphasis>, but

- 	  not <emphasis>expression</emphasis>.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The expressions in the arithmetic <literal>for</literal>

- 	  command,

- 	  “<literal>for ((</literal><emphasis>expression1</emphasis><literal>; </literal><emphasis>expression2</emphasis><literal>; </literal><emphasis>expression3</emphasis><literal>)); do </literal><emphasis>commands</emphasis><literal>; done</literal>”

- 	  are evaluated.  This does not apply to the regular

- 	  for command,

- 	  “<literal>for </literal><emphasis>variable</emphasis><literal> in </literal><emphasis>list</emphasis><literal>; do </literal><emphasis>commands</emphasis><literal>; done</literal>”.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <important>

-       <para>

- 	Depending on the <application>bash</application> version, the

- 	above list may be incomplete.

-       </para>

-       <para>

- 	If faced with a situation where using such shell features

- 	appears necessary, see <xref

- 	linkend="sect-Defensive_Coding-Shell-Alternatives"/>.

-       </para>

-     </important>

-     <para>

-       If it is impossible to avoid shell arithmetic on untrusted

-       inputs, refer to <xref

-       linkend="sect-Defensive_Coding-Shell-Input_Validation"/>.

-     </para>

-   </section>

-   <section id="sect-Defensive_Coding-Shell-Types">

-     <title>Type declarations</title>

-     <para>

-       <application>bash</application> supports explicit type

-       declarations for shell variables:

-     </para>

-     <informalexample>

-       <programlisting language="Bash">

- 	declare -i integer_variable

- 	declare -a array_variable

- 	declare -A assoc_array_variable

- 

- 	typeset -i integer_variable

- 	typeset -a array_variable

- 	typeset -A assoc_array_variable

- 

- 	local -i integer_variable

- 	local -a array_variable

- 	local -A assoc_array_variable

- 

- 	readonly -i integer_variable

- 	readonly -a array_variable

- 	readonly -A assoc_array_variable

-       </programlisting>

-     </informalexample>

-     <para>

-       Variables can also be declared as arrays by assigning them an

-       array expression, as in:

-     </para>

-     <informalexample>

-       <programlisting language="Bash">

- array_variable=(1 2 3 4)

-       </programlisting>

-     </informalexample>

-     <para>

-       Some built-ins (such as <literal>mapfile</literal>) can

-       implicitly create array variables.

-     </para>

-     <para>

-       Such type declarations should not be used because assignment to

-       such variables (independent of the concrete syntax used for the

-       assignment) triggers arithmetic expansion (and thus double

-       expansion) of the right-hand side of the assignment operation.

-       See <xref linkend="sect-Defensive_Coding-Shell-Arithmetic"/>.

-     </para>

-     <para>

-       Shell scripts which use integer or array variables should be

-       rewritten in another, more suitable language.  Se <xref

-       linkend="sect-Defensive_Coding-Shell-Alternatives"/>.

-     </para>

-   </section>

- </section>

- <section id="sect-Defensive_Coding-Shell-Obscure">

-   <title>Other obscurities</title>

-   <para>

-     Obscure shell language features should not be used.  Examples are:

-   </para>

-   <itemizedlist>

-     <listitem>

-       <para>

- 	Exported functions (<literal>export -f</literal> or

- 	<literal>declare -f</literal>).

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	Function names which are not valid variable names, such as

- 	“<literal>module::function</literal>”.

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	The possibility to override built-ins or external commands

- 	with shell functions.

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	Changing the value of the <envar>IFS</envar> variable to

- 	tokenize strings.

-       </para>

-     </listitem>

-   </itemizedlist>

- </section>

- </section>

- <section id="sect-Defensive_Coding-Shell-Invoke">

- <title>Invoking external commands</title>

- <para>

-   When passing shell variables as single command line arguments,

-   they should always be surrounded by double quotes.  See

-   <xref linkend="sect-Defensive_Coding-Shell-Parameter_Expansion"/>.

- </para>

- <para>

-   Care is required when passing untrusted values as positional

-   parameters to external commands.  If the value starts with a hyphen

-   “<literal>-</literal>”, it may be interpreted by the external

-   command as an option.  Depending on the external program, a

-   “<literal>--</literal>” argument stops option processing and treats

-   all following arguments as positional parameters.  (Double quotes

-   are completely invisible to the command being invoked, so they do

-   not prevent variable values from being interpreted as options.)

- </para>

- <para>

-   Cleaning the environment before invoking child processes is

-   difficult to implement in script.  <application>bash</application>

-   keeps a hidden list of environment variables which do not correspond

-   to shell variables, and unsetting them from within a

-   <application>bash</application> script is not possible.  To reset

-   the environment, a script can re-run itself under the “<literal>env

-   -i</literal>” command with an additional parameter which indicates

-   the environment has been cleared and suppresses a further

-   self-execution.  Alternatively, individual commands can be executed

-   with “<literal>env -i</literal>”.

- </para>

- <important>

-   <para>

-     Completely isolation from its original execution environment

-     (which is required when the script is executed after a trust

-     transition, e.g., triggered by the SUID mechanism) is impossible

-     to achieve from within the shell script itself.  Instead, the

-     invoking process has to clear the process environment (except for

-     few trusted variables) before running the shell script.

-   </para>

- </important>

- <para>

-   Checking for failures in executed external commands is recommended.

-   If no elaborate error recovery is needed, invoking “<literal>set

-   -e</literal>” may be sufficient.  This causes the script to stop on

-   the first failed command.  However, failures in pipes

-   (“<literal>command1 | command2</literal>”) are only detected for the

-   last command in the pipe, errors in previous commands are ignored.

-   This can be changed by invoking “<literal>set -o pipefail</literal>”.

-   Due to architectural limitations, only the process that spawned

-   the entire pipe can check for failures in individual commands;

-   it is not possible for a process to tell if the process feeding

-   data (or the process consuming data) exited normally or with 

-   an error.

- </para>

- <para>

-   See <xref linkend="sect-Defensive_Coding-Tasks-Processes-Creation"/>

-   for additional details on creating child processes.

- </para>

- </section>

- <section id="sect-Defensive_Coding-Shell-Temporary_Files">

-   <title>Temporary files</title>

-   <para>

-     Temporary files should be created with the

-     <literal>mktemp</literal> command, and temporary directories with

-     “<literal>mktemp -d</literal>”.

-   </para>

-   <para>

-     To clean up temporary files and directories, write a clean-up

-     shell function and register it as a trap handler, as shown in

-     <xref linkend="ex-Defensive_Coding-Tasks-Temporary_Files"/>.

-     Using a separate function avoids issues with proper quoting of

-     variables.

-   </para>

-   <example id="ex-Defensive_Coding-Tasks-Temporary_Files">

-     <title>Creating and cleaning up temporary files</title>

-  <informalexample>

-    <programlisting language="Bash">

- tmpfile="$(mktemp)"

- 

- cleanup () {

-     rm -f -- "$tmpfile"

- }

- 

- trap cleanup 0

-    </programlisting>

-  </informalexample>

-   </example>

- </section>

- <section id="sect-Defensive_Coding-Shell-Input_Validation">

-   <title>Performing input validation</title>

-   <para>

-     In some cases, input validation cannot be avoided.  For example,

-     if arithmetic evaluation is absolutely required, it is imperative

-     to check that input values are, in fact, integers.  See <xref

-     linkend="sect-Defensive_Coding-Shell-Arithmetic"/>.

-   </para>

-   <para>

-     <xref linkend="ex-Defensive_Coding-Shell-Input_Validation"/>

-     shows a construct which can be used to check if a string

-     “<literal>$value</literal>” is an integer.  This construct is

-     specific to <application>bash</application> and not portable to

-     POSIX shells.

-   </para>

-   <example id="ex-Defensive_Coding-Shell-Input_Validation">

-     <title>Input validation in <application>bash</application></title>

-     <xi:include href="snippets/Shell-Input_Validation.xml"

- 		xmlns:xi="http://www.w3.org/2001/XInclude" />

-   </example>

-   <para>

-     Using <literal>case</literal> statements for input validation is

-     also possible and supported by other (POSIX) shells, but the

-     pattern language is more restrictive, and it can be difficult to

-     write suitable patterns.

-   </para>

-   <para>

-     The <literal>expr</literal> external command can give misleading

-     results (e.g., if the value being checked contains operators

-     itself) and should not be used.

-   </para>

- </section>

- <section id="sect-Defensive_Coding-Shell-Edit_Guard">

-   <title>Guarding shell scripts against changes</title>

-   <para>

-     <application>bash</application> only reads a shell script up to

-     the point it is needed for executed the next command.  This means

-     that if script is overwritten while it is running, execution can

-     jump to a random part of the script, depending on what is modified

-     in the script and how the file offsets change as a result.  (This

-     behavior is needed to support self-extracting shell archives whose

-     script part is followed by a stream of bytes which does not follow

-     the shell language syntax.)

-   </para>

-   <para>

-     Therefore, long-running scripts should be guarded against

-     concurrent modification by putting as much of the program logic

-     into a <literal>main</literal> function, and invoking the

-     <literal>main</literal> function at the end of the script, using

-     this syntax:

-   </para>

-   <informalexample>

-     <programlisting language="Bash">

- main "$@" ; exit $?

-     </programlisting>

-   </informalexample>

-   <para>

-     This construct ensures that <application>bash</application> will

-     stop execution after the <literal>main</literal> function, instead

-     of opening the script file and trying to read more commands.

-   </para>

- </section>

- </chapter>

en-US/Tasks-Cryptography.adoc
file added
+132
@@ -0,0 +1,132 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Tasks-Cryptography]]

+ === Cryptography

+ 

+ ==== Primitives

+ 

+ Choosing from the following cryptographic primitives is

+ recommended:

+ 

+ * RSA with 2048-bit keys and OAEP or PSS

+ padding

+ 

+ * AES-128 in CBC mode

+ 

+ * AES-128 in GCM mode

+ 

+ * AES-256 in CBC mode

+ 

+ * AES-256 in GCM mode

+ 

+ * SHA-256

+ 

+ * HMAC-SHA-256

+ 

+ * HMAC-SHA-1

+ 

+ Other cryptographic algorithms can be used if they are required

+ for interoperability with existing software:

+ 

+ * RSA with key sizes larger than 1024

+ and legacy padding

+ 

+ * AES-192

+ 

+ * 3DES (triple DES, with two or three 56-bit keys),

+ but strongly discouraged

+ 

+ * RC4 (but very, very strongly discouraged)

+ 

+ * SHA-1

+ 

+ * HMAC-MD5

+ 

+ .Important

+ [IMPORTANT]

+ ====

+ 

+ These primitives are difficult to use in a secure way. Custom

+ implementation of security protocols should be avoided. For

+ protecting confidentiality and integrity of network

+ transmissions, TLS should be used (<<chap-Defensive_Coding-TLS>>).

+ 

+ In particular, when using AES in CBC mode, it is necessary to

+ add integrity checking by other means, preferably using

+ HMAC-SHA-256 and *after* encryption (that

+ is, on the encrypted cipher text). For AES in GCM mode,

+ correct construction of nonces is absolutely essential.

+ 

+ ====

+ 

+ ==== Randomness

+ 

+ The following facilities can be used to generate unpredictable

+ and non-repeating values. When these functions are used without

+ special safeguards, each individual random value should be at

+ least 12 bytes long.

+ 

+ * `PK11_GenerateRandom` in the NSS library

+ (usable for high data rates)

+ 

+ * `RAND_bytes` in the OpenSSL library

+ (usable for high data rates)

+ 

+ * `gnutls_rnd` in GNUTLS, with

+ `GNUTLS_RND_RANDOM` as the first argument

+ (usable for high data rates)

+ 

+ * `java.security.SecureRandom` in Java

+ (usable for high data rates)

+ 

+ * `os.urandom` in Python

+ 

+ * The `getrandom` system call since glibc 2.25

+ 

+ * The `getentropy` call since glibc 2.25

+ 

+ * Reading from the `/dev/urandom`

+ character device

+ 

+ All these functions should be non-blocking, and they should not

+ wait until physical randomness becomes available. (Some

+ cryptography providers for Java can cause

+ `java.security.SecureRandom` to block, however.)

+ Those functions which do not obtain all bits directly from

+ `/dev/urandom` are suitable for high data

+ rates because they do not deplete the system-wide entropy pool.

+ 

+ .Difficult to use API

+ [IMPORTANT]

+ ====

+ 

+ Both `RAND_bytes` and

+ `PK11_GenerateRandom` have three-state

+ return values (with conflicting meanings). Careful error

+ checking is required. Please review the documentation when

+ using these functions.

+ 

+ ====

+ 

+ .Difficult to use API

+ [IMPORTANT]

+ ====

+ 

+ The `getrandom` system call has three-state

+ return values, hence requires careful error checking.

+ 

+ It was introduced in Linux kernel 3.17, but before glibc 2.25 no API wrappers were

+ provided. As such one could only use it via the syscall interface

+ as `syscall(SYS_getrandom, (void*)dest, (size_t)size, (unsigned int)0)`.

+ For portable code targetting multiple kernel versions one has to check 

+ for the function beingavailable on run-time, and switch to another

+ facility if the running kernel does not support this call.

+ 

+ ====

+ 

+ Other sources of randomness should be considered predictable.

+ 

+ Generating randomness for cryptographic keys in long-term use

+ may need different steps and is best left to cryptographic

+ libraries.

en-US/Tasks-Cryptography.xml
file removed
-122
@@ -1,122 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Tasks-Cryptography">

-   <title>Cryptography</title>

- 

-   <section>

-     <title>Primitives</title>

-     <para>

-       Choosing from the following cryptographic primitives is

-       recommended:

-     </para>

-     <itemizedlist>

-       <listitem><para>RSA with 2048 bit keys and OAEP or PSS

-         padding</para></listitem>

-       <listitem><para>AES-128 in CBC mode</para></listitem>

-       <listitem><para>AES-128 in GCM mode</para></listitem>

-       <listitem><para>AES-256 in CBC mode</para></listitem>

-       <listitem><para>AES-256 in GCM mode</para></listitem>

-       <listitem><para>SHA-256</para></listitem>

-       <listitem><para>HMAC-SHA-256</para></listitem>

-       <listitem><para>HMAC-SHA-1</para></listitem>

-     </itemizedlist>

-     <para>

-       Other cryptographic algorithms can be used if they are required

-       for interoperability with existing software:

-     </para>

-     <itemizedlist>

-       <listitem><para>RSA with key sizes larger than 1024

-         and legacy padding</para></listitem>

-       <listitem><para>AES-192</para></listitem>

-       <listitem><para>3DES (triple DES, with two or three 56 bit keys),

-         but strongly discouraged</para></listitem>

-       <listitem><para>RC4 (but very, very strongly discouraged)</para></listitem>

-       <listitem><para>SHA-1</para></listitem>

-       <listitem><para>HMAC-MD5</para></listitem>

-     </itemizedlist>

-     <important>

-       <title>Important</title>

-       <para>

- 	These primitives are difficult to use in a secure way.  Custom

- 	implementation of security protocols should be avoided.  For

- 	protecting confidentiality and integrity of network

- 	transmissions, TLS should be used (<xref

- 	linkend="chap-Defensive_Coding-TLS"/>).

-       </para>

-       <para>

- 	In particlar, when using AES in CBC mode, it is necessary to

- 	add integrity checking by other means, preferably using

- 	HMAC-SHA-256 and <emphasis>after</emphasis> encryption (that

- 	is, on the encrypted cipher text).  For AES in GCM mode,

- 	correct construction of nonces is absolutely essential.

-       </para>

-     </important>

- <!-- TODO: More algorithms are available in the NIST documents

-      linked from: http://wiki.brq.redhat.com/SecurityTechnologies/FIPS -->

-   </section>

- 

-   <section>

-     <title id="sect-Defensive_Coding-Tasks-Cryptography-Randomness">Randomness</title>

-     <para>

-       The following facilities can be used to generate unpredictable

-       and non-repeating values.  When these functions are used without

-       special safeguards, each individual random value should be at

-       least 12 bytes long.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para><function>PK11_GenerateRandom</function> in the NSS library

- 	  (usable for high data rates)</para>

-       </listitem>

-       <listitem>

- 	<para><function>RAND_bytes</function> in the OpenSSL library

- 	  (usable for high data rates)</para>

-       </listitem>

-       <listitem>

- 	<para><function>gnutls_rnd</function> in GNUTLS, with

- 	<literal>GNUTLS_RND_RANDOM</literal> as the first argument

- 	(usable for high data rates)</para>

-       </listitem>

-       <listitem>

- 	<para><type>java.security.SecureRandom</type> in Java

- 	  (usable for high data rates)</para>

-       </listitem>

-       <listitem>

- 	<para><function>os.urandom</function> in Python</para>

-       </listitem>

-       <listitem>

- 	<para>Reading from the <filename>/dev/urandom</filename>

- 	  character device</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       All these functions should be non-blocking, and they should not

-       wait until physical randomness becomes available.  (Some

-       cryptography providers for Java can cause

-       <type>java.security.SecureRandom</type> to block, however.)

-       Those functions which do not obtain all bits directly from

-       <filename>/dev/urandom</filename> are suitable for high data

-       rates because they do not deplete the system-wide entropy pool.

-     </para>

-     <important>

-       <title>Difficult to use API</title>

-       <para>

- 	Both <function>RAND_bytes</function> and

- 	<function>PK11_GenerateRandom</function> have three-state

- 	return values (with conflicting meanings).  Careful error

- 	checking is required.  Please review the documentation when

- 	using these functions.

-       </para>

-     </important>

-     <para>

-       Other sources of randomness should be considered predictable.

-     </para>

-     <para>

-       Generating randomness for cryptographic keys in long-term use

-       may need different steps and is best left to cryptographic

-       libraries.

-     </para>

-   </section>

- 

- </chapter>

en-US/Tasks-Descriptors.adoc
file added
+216
@@ -0,0 +1,216 @@

+ 

+ :experimental:

+ 

+ [[sect-Defensive_Coding-Tasks-Descriptors]]

+ === File Descriptor Management

+ 

+ File descriptors underlie all input/output mechanisms offered by

+ the system. They are used to implementation the `FILE

+ *`-based functions found in

+ `<stdio.h>`, and all the file and network

+ communication facilities provided by the Python and Java

+ environments are eventually implemented in them.

+ 

+ File descriptors are small, non-negative integers in userspace,

+ and are backed on the kernel side with complicated data structures

+ which can sometimes grow very large.

+ 

+ ==== Closing Descriptors

+ 

+ If a descriptor is no longer used by a program and is not closed

+ explicitly, its number cannot be reused (which is problematic in

+ itself, see <<sect-Defensive_Coding-Tasks-Descriptors-Limit>>), and

+ the kernel resources are not freed. Therefore, it is important

+ to close all descriptors at the earliest point in time

+ possible, but not earlier.

+ 

+ ===== Error Handling during Descriptor Close

+ 

+ The `close` system call is always

+ successful in the sense that the passed file descriptor is

+ never valid after the function has been called. However,

+ `close` still can return an error, for

+ example if there was a file system failure. But this error is

+ not very useful because the absence of an error does not mean

+ that all caches have been emptied and previous writes have

+ been made durable. Programs which need such guarantees must

+ open files with `O_SYNC` or use

+ `fsync` or `fdatasync`, and

+ may also have to `fsync` the directory

+ containing the file.

+ 

+ ===== Closing Descriptors and Race Conditions

+ 

+ Unlike process IDs, which are recycle only gradually, the

+ kernel always allocates the lowest unused file descriptor when

+ a new descriptor is created. This means that in a

+ multi-threaded program which constantly opens and closes file

+ descriptors, descriptors are reused very quickly. Unless

+ descriptor closing and other operations on the same file

+ descriptor are synchronized (typically, using a mutex), there

+ will be race conditons and I/O operations will be applied to

+ the wrong file descriptor.

+ 

+ Sometimes, it is necessary to close a file descriptor

+ concurrently, while another thread might be about to use it in

+ a system call. In order to support this, a program needs to

+ create a single special file descriptor, one on which all I/O

+ operations fail. One way to achieve this is to use

+ `socketpair`, close one of the descriptors,

+ and call `shutdown(fd, SHUTRDWR)` on the

+ other.

+ 

+ When a descriptor is closed concurrently, the program does not

+ call `close` on the descriptor. Instead it

+ program uses `dup2` to replace the

+ descriptor to be closed with the dummy descriptor created

+ earlier. This way, the kernel will not reuse the descriptor,

+ but it will carry out all other steps associated with calling

+ a descriptor (for instance, if the descriptor refers to a

+ stream socket, the peer will be notified).

+ 

+ This is just a sketch, and many details are missing.

+ Additional data structures are needed to determine when it is

+ safe to really close the descriptor, and proper locking is

+ required for that.

+ 

+ ===== Lingering State after Close

+ 

+ By default, closing a stream socket returns immediately, and

+ the kernel will try to send the data in the background. This

+ means that it is impossible to implement accurate accounting

+ of network-related resource utilization from userspace.

+ 

+ The `SO_LINGER` socket option alters the

+ behavior of `close`, so that it will return

+ only after the lingering data has been processed, either by

+ sending it to the peer successfully, or by discarding it after

+ the configured timeout. However, there is no interface which

+ could perform this operation in the background, so a separate

+ userspace thread is needed for each `close`

+ call, causing scalability issues.

+ 

+ Currently, there is no application-level countermeasure which

+ applies universally. Mitigation is possible with

+ [application]*iptables* (the

+ `connlimit` match type in particular) and

+ specialized filtering devices for denial-of-service network

+ traffic.

+ 

+ These problems are not related to the

+ `TIME_WAIT` state commonly seen in

+ [application]*netstat* output. The kernel

+ automatically expires such sockets if necessary.

+ 

+ [[sect-Defensive_Coding-Tasks-Descriptors-Child_Processes]]

+ ==== Preventing File Descriptor Leaks to Child Processes

+ 

+ Child processes created with `fork` share

+ the initial set of file descriptors with their parent

+ process. By default, file descriptors are also preserved if

+ a new process image is created with `execve`

+ (or any of the other functions such as `system`

+ or `posix_spawn`).

+ 

+ Usually, this behavior is not desirable. There are two ways to

+ turn it off, that is, to prevent new process images from

+ inheriting the file descriptors in the parent process:

+ 

+ * Set the close-on-exec flag on all newly created file

+ descriptors. Traditionally, this flag is controlled by the

+ `FD_CLOEXEC` flag, using

+ `F_GETFD` and `F_SETFD`

+ operations of the `fcntl` function.

+ +

+ However, in a multi-threaded process, there is a race

+ condition: a subprocess could have been created between the

+ time the descriptor was created and the

+ `FD_CLOEXEC` was set. Therefore, many system

+ calls which create descriptors (such as

+ `open` and `openat`)

+ now accept the `O_CLOEXEC` flag

+ (`SOCK_CLOEXEC` for

+ `socket` and

+ `socketpair`), which cause the

+ `FD_CLOEXEC` flag to be set for the file

+ descriptor in an atomic fashion. In addition, a few new

+ systems calls were introduced, such as

+ `pipe2` and `dup3`.

+ +

+ The downside of this approach is that every descriptor needs

+ to receive special treatment at the time of creation,

+ otherwise it is not completely effective.

+ 

+ * After calling `fork`, but before creating

+ a new process image with `execve`, all

+ file descriptors which the child process will not need are

+ closed.

+ +

+ Traditionally, this was implemented as a loop over file

+ descriptors ranging from `3` to

+ `255` and later `1023`.

+ But this is only an approximation because it is possible to

+ create file descriptors outside this range easily (see <<sect-Defensive_Coding-Tasks-Descriptors-Limit>>).

+ Another approach reads `/proc/self/fd`

+ and closes the unexpected descriptors listed there, but this

+ approach is much slower.

+ 

+ At present, environments which care about file descriptor

+ leakage implement the second approach. OpenJDK 6 and 7

+ are among them.

+ 

+ [[sect-Defensive_Coding-Tasks-Descriptors-Limit]]

+ ==== Dealing with the `select` Limit

+ 

+ By default, a user is allowed to open only 1024 files in a

+ single process, but the system administrator can easily change

+ this limit (which is necessary for busy network servers).

+ However, there is another restriction which is more difficult to

+ overcome.

+ 

+ The `select` function only supports a

+ maximum of `FD_SETSIZE` file descriptors

+ (that is, the maximum permitted value for a file descriptor

+ is `FD_SETSIZE - 1`, usually 1023.) If a

+ process opens many files, descriptors may exceed such

+ limits. It is impossible to query such descriptors using

+ `select`.

+ 

+ If a library which creates many file descriptors is used in

+ the same process as a library which uses

+ `select`, at least one of them needs to

+ be changed. 

+ Calls to `select` can be replaced with

+ calls to `poll` or another event handling

+ mechanism. Replacing the `select` function

+ is the recommended approach.

+ 

+ Alternatively, the library with high descriptor usage can

+ relocate descriptors above the `FD_SETSIZE`

+ limit using the following procedure.

+ 

+ * Create the file descriptor `fd` as

+ usual, preferably with the `O_CLOEXEC`

+ flag.

+ 

+ * Before doing anything else with the descriptor

+ `fd`, invoke:

+ [source,c]

+ ----

+ 

+ 	  int newfd = fcntl(fd, F_DUPFD_CLOEXEC, (long)FD_SETSIZE);

+ 	

+ ----

+ 

+ * Check that `newfd` result is

+ non-negative, otherwise close `fd` and

+ report an error, and return.

+ 

+ * Close `fd` and continue to use

+ `newfd`.

+ 

+ The new descriptor has been allocated above the

+ `FD_SETSIZE`. Even though this algorithm

+ is racy in the sense that the `FD_SETSIZE`

+ first descriptors could fill up, a very high degree of

+ physical parallelism is required before this becomes a problem.

en-US/Tasks-Descriptors.xml
file removed
-267
@@ -1,267 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="sect-Defensive_Coding-Tasks-Descriptors">

-   <title>File Descriptor Management</title>

-   <para>

-     File descriptors underlie all input/output mechanisms offered by

-     the system.  They are used to implementation the <literal>FILE

-     *</literal>-based functions found in

-     <literal>&lt;stdio.h&gt;</literal>, and all the file and network

-     communication facilities provided by the Python and Java

-     environments are eventually implemented in them.

-   </para>

-   <para>

-     File descriptors are small, non-negative integers in userspace,

-     and are backed on the kernel side with complicated data structures

-     which can sometimes grow very large.

-   </para>

-   <section>

-     <title>Closing descriptors</title>

-     <para>

-       If a descriptor is no longer used by a program and is not closed

-       explicitly, its number cannot be reused (which is problematic in

-       itself, see <xref

-       linkend="sect-Defensive_Coding-Tasks-Descriptors-Limit"/>), and

-       the kernel resources are not freed.  Therefore, it is important

-       to close all descriptors at the earlierst point in time

-       possible, but not earlier.

-     </para>

-     <section>

-       <title>Error handling during descriptor close</title>

-       <para>

- 	The <function>close</function> system call is always

- 	successful in the sense that the passed file descriptor is

- 	never valid after the function has been called.  However,

- 	<function>close</function> still can return an error, for

- 	example if there was a file system failure.  But this error is

- 	not very useful because the absence of an error does not mean

- 	that all caches have been emptied and previous writes have

- 	been made durable.  Programs which need such guarantees must

- 	open files with <literal>O_SYNC</literal> or use

- 	<literal>fsync</literal> or <literal>fdatasync</literal>, and

- 	may also have to <literal>fsync</literal> the directory

- 	containing the file.

-       </para>

-     </section>

-     <section>

-       <title>Closing descriptors and race conditions</title>

-       <para>

- 	Unlike process IDs, which are recycle only gradually, the

- 	kernel always allocates the lowest unused file descriptor when

- 	a new descriptor is created.  This means that in a

- 	multi-threaded program which constantly opens and closes file

- 	descriptors, descriptors are reused very quickly.  Unless

- 	descriptor closing and other operations on the same file

- 	descriptor are synchronized (typically, using a mutex), there

- 	will be race coniditons and I/O operations will be applied to

- 	the wrong file descriptor.

-       </para>

-       <para>

- 	Sometimes, it is necessary to close a file descriptor

- 	concurrently, while another thread might be about to use it in

- 	a system call.  In order to support this, a program needs to

- 	create a single special file descriptor, one on which all I/O

- 	operations fail.  One way to achieve this is to use

- 	<function>socketpair</function>, close one of the descriptors,

- 	and call <literal>shutdown(fd, SHUTRDWR)</literal> on the

- 	other.

-       </para>

-       <para>

- 	When a descriptor is closed concurrently, the program does not

- 	call <function>close</function> on the descriptor.  Instead it

- 	program uses <function>dup2</function> to replace the

- 	descriptor to be closed with the dummy descriptor created

- 	earlier.  This way, the kernel will not reuse the descriptor,

- 	but it will carry out all other steps associated with calling

- 	a descriptor (for instance, if the descriptor refers to a

- 	stream socket, the peer will be notified).

-       </para>

-       <para>

- 	This is just a sketch, and many details are missing.

- 	Additional data structures are needed to determine when it is

- 	safe to really close the descriptor, and proper locking is

- 	required for that.

-       </para>

-     </section>

-     <section>

-       <title>Lingering state after close</title>

-       <para>

- 	By default, closing a stream socket returns immediately, and

- 	the kernel will try to send the data in the background.  This

- 	means that it is impossible to implement accurate accounting

- 	of network-related resource utilization from userspace.

-       </para>

-       <para>

- 	The <literal>SO_LINGER</literal> socket option alters the

- 	behavior of <function>close</function>, so that it will return

- 	only after the lingering data has been processed, either by

- 	sending it to the peer successfully, or by discarding it after

- 	the configured timeout.  However, there is no interface which

- 	could perform this operation in the background, so a separate

- 	userspace thread is needed for each <function>close</function>

- 	call, causing scalability issues.

-       </para>

-       <para>

- 	Currently, there is no application-level countermeasure which

- 	applies universally.  Mitigation is possible with

- 	<application>iptables</application> (the

- 	<literal>connlimit</literal> match type in particular) and

- 	specialized filtering devices for denial-of-service network

- 	traffic.

-       </para>

-       <para>

- 	These problems are not related to the

- 	<literal>TIME_WAIT</literal> state commonly seen in

- 	<application>netstat</application> output.  The kernel

- 	automatically expires such sockets if necessary.

-       </para>

-     </section>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Tasks-Descriptors-Child_Processes">

-     <title>Preventing file descriptor leaks to child processes</title>

-     <para>

-       Child processes created with <function>fork</function> share

-       the initial set of file descriptors with their parent

-       process.  By default, file descriptors are also preserved if

-       a new process image is created with <function>execve</function>

-       (or any of the other functions such as <function>system</function>

-       or <function>posix_spawn</function>).

-     </para>

-     <para>

-       Usually, this behavior is not desirable.  There are two ways to

-       turn it off, that is, to prevent new process images from

-       inheriting the file descriptors in the parent process:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Set the close-on-exec flag on all newly created file

- 	  descriptors.  Traditionally, this flag is controlled by the

- 	  <literal>FD_CLOEXEC</literal> flag, using

- 	  <literal>F_GETFD</literal> and <literal>F_SETFD</literal>

- 	  operations of the <function>fcntl</function> function.

- 	</para>

- 	<para>

- 	  However, in a multi-threaded process, there is a race

- 	  condition: a subprocess could have been created between the

- 	  time the descriptor was created and the

- 	  <literal>FD_CLOEXEC</literal> was set.  Therefore, many system

- 	  calls which create descriptors (such as

- 	  <function>open</function> and <function>openat</function>)

- 	  now accept the <function>O_CLOEXEC</function> flag

- 	  (<function>SOCK_CLOEXEC</function> for

- 	  <function>socket</function> and

- 	  <function>socketpair</function>), which cause the

- 	  <literal>FD_CLOEXEC</literal> flag to be set for the file

- 	  descriptor in an atomic fashion.  In addition, a few new

- 	  systems calls were introduced, such as

- 	  <function>pipe2</function> and <function>dup3</function>.

- 	</para>

- 	<para>

- 	  The downside of this approach is that every descriptor needs

- 	  to receive special treatment at the time of creation,

- 	  otherwise it is not completely effective.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  After calling <function>fork</function>, but before creating

- 	  a new process image with <function>execve</function>, all

- 	  file descriptors which the child process will not need are

- 	  closed.

- 	</para>

- 	<para>

- 	  Traditionally, this was implemented as a loop over file

- 	  descriptors ranging from <literal>3</literal> to

- 	  <literal>255</literal> and later <literal>1023</literal>.

- 	  But this is only an approximatio because it is possible to

- 	  create file descriptors outside this range easily (see <xref

- 	  linkend="sect-Defensive_Coding-Tasks-Descriptors-Limit"/>).

- 	  Another approach reads <filename>/proc/self/fd</filename>

- 	  and closes the unexpected descriptors listed there, but this

- 	  approach is much slower.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       At present, environments which care about file descriptor

-       leakage implement the second approach.  OpenJDK 6 and 7

-       are among them.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Tasks-Descriptors-Limit">

-     <title>Dealing with the <function>select</function> limit</title>

-     <para>

-       By default, a user is allowed to open only 1024 files in a

-       single process, but the system administrator can easily change

-       this limit (which is necessary for busy network servers).

-       However, there is another restriction which is more difficult to

-       overcome.

-     </para>

-     <para>

-       The <function>select</function> function only supports a

-       maximum of <literal>FD_SETSIZE</literal> file descriptors

-       (that is, the maximum permitted value for a file descriptor

-       is <literal>FD_SETSIZE - 1</literal>, usually 1023.)  If a

-       process opens many files, descriptors may exceed such

-       limits.  It is impossible to query such descriptors using

-       <function>select</function>.

-     </para>

-     <para>

-       If a library which creates many file descriptors is used in

-       the same process as a library which uses

-       <function>select</function>, at least one of them needs to

-       be changed.  <!-- ??? refer to event-driven programming -->

-       Calls to <function>select</function> can be replaced with

-       calls to <function>poll</function> or another event handling

-       mechanism.  Replacing the <function>select</function> function

-       is the recommended approach.

-     </para>

-     <para>

-       Alternatively, the library with high descriptor usage can

-       relocate descriptors above the <literal>FD_SETSIZE</literal>

-       limit using the following procedure.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Create the file descriptor <literal>fd</literal> as

- 	  usual, preferably with the <literal>O_CLOEXEC</literal>

- 	  flag.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Before doing anything else with the descriptor

- 	  <literal>fd</literal>, invoke:

- 	</para>

- 	<programlisting language="C">

- 	  int newfd = fcntl(fd, F_DUPFD_CLOEXEC, (long)FD_SETSIZE);

- 	</programlisting>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Check that <literal>newfd</literal> result is

- 	  non-negative, otherwise close <literal>fd</literal> and

- 	  report an error, and return.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Close <literal>fd</literal> and continue to use

- 	  <literal>newfd</literal>.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       The new descriptor has been allocated above the

-       <literal>FD_SETSIZE</literal>.  Even though this algorithm

-       is racy in the sense that the <literal>FD_SETSIZE</literal>

-       first descriptors could fill up, a very high degree of

-       physical parallelism is required before this becomes a problem.

-     </para>

-   </section>

- </chapter>

en-US/Tasks-File_System.adoc
file added
+264
@@ -0,0 +1,264 @@

+ 

+ :experimental:

+ include::entities.adoc[]

+ 

+ [[chap-Defensive_Coding-Tasks-File_System]]

+ === File System Manipulation

+ 

+ In this chapter, we discuss general file system manipulation, with

+ a focus on access files and directories to which an other,

+ potentially untrusted user has write access.

+ 

+ Temporary files are covered in their own chapter, <<chap-Defensive_Coding-Tasks-Temporary_Files>>.

+ 

+ [[sect-Defensive_Coding-Tasks-File_System-Unowned]]

+ ==== Working with Files and Directories Owned by Other Users

+ 

+ Sometimes, it is necessary to operate on files and directories

+ owned by other (potentially untrusted) users. For example, a

+ system administrator could remove the home directory of a user,

+ or a package manager could update a file in a directory which is

+ owned by an application-specific user. This differs from

+ accessing the file system as a specific user; see 

+ <<sect-Defensive_Coding-Tasks-File_System-Foreign>>.

+ 

+ Accessing files across trust boundaries faces several

+ challenges, particularly if an entire directory tree is being

+ traversed:

+ 

+ . Another user might add file names to a writable directory at

+ any time. This can interfere with file creation and the

+ order of names returned by `readdir`.

+ 

+ . Merely opening and closing a file can have side effects.

+ For instance, an automounter can be triggered, or a tape

+ device rewound. Opening a file on a local file system can

+ block indefinitely, due to mandatory file locking, unless

+ the `O_NONBLOCK` flag is specified.

+ 

+ . Hard links and symbolic links can redirect the effect of

+ file system operations in unexpected ways. The

+ `O_NOFOLLOW` and

+ `AT_SYMLINK_NOFOLLOW` variants of system

+ calls only affected final path name component.

+ 

+ . The structure of a directory tree can change. For example,

+ the parent directory of what used to be a subdirectory

+ within the directory tree being processed could suddenly

+ point outside that directory tree.

+ 

+ Files should always be created with the

+ `O_CREAT` and `O_EXCL` flags,

+ so that creating the file will fail if it already exists. This

+ guards against the unexpected appearance of file names, either

+ due to creation of a new file, or hard-linking of an existing

+ file. In multi-threaded programs, rather than manipulating the

+ umask, create the files with mode `000` if

+ possible, and adjust it afterwards with

+ `fchmod`.

+ 

+ To avoid issues related to symbolic links and directory tree

+ restructuring, the “pass:attributes[{blank}]`at`pass:attributes[{blank}]” variants of system

+ calls have to be used (that is, functions like

+ `openat`, `fchownat`,

+ `fchmodat`, and

+ `unlinkat`, together with

+ `O_NOFOLLOW` or

+ `AT_SYMLINK_NOFOLLOW`). Path names passed to

+ these functions must have just a single component (that is,

+ without a slash). When descending, the descriptors of parent

+ directories must be kept open. The missing

+ `opendirat` function can be emulated with

+ `openat` (with an

+ `O_DIRECTORY` flag, to avoid opening special

+ files with side effects), followed by

+ `fdopendir`.

+ 

+ If the “pass:attributes[{blank}]`at`pass:attributes[{blank}]” functions are not available, it

+ is possible to emulate them by changing the current directory.

+ (Obviously, this only works if the process is not multi-threaded.)

+ `fchdir` has to be used to change the current

+ directory, and the descriptors of the parent directories have to

+ be kept open, just as with the “pass:attributes[{blank}]`at`pass:attributes[{blank}]”-based

+ approach. `chdir("...")` is unsafe because it

+ might ascend outside the intended directory tree.

+ 

+ This “pass:attributes[{blank}]`at`pass:attributes[{blank}]” function emulation is currently

+ required when manipulating extended attributes. In this case,

+ the `lsetxattr` function can be used, with a

+ relative path name consisting of a single component. This also

+ applies to SELinux contexts and the

+ `lsetfilecon` function.

+ 

+ Currently, it is not possible to avoid opening special files

+ *and* changes to files with hard links if the

+ directory containing them is owned by an untrusted user.

+ (Device nodes can be hard-linked, just as regular files.)

+ `fchmodat` and `fchownat`

+ affect files whose link count is greater than one. But opening

+ the files, checking that the link count is one with

+ `fstat`, and using

+ `fchmod` and `fchown` on

+ the file descriptor may have unwanted side effects, due to item

+ 2 above. When creating directories, it is therefore important

+ to change the ownership and permissions only after it has been

+ fully created. Until that point, file names are stable, and no

+ files with unexpected hard links can be introduced.

+ 

+ Similarly, when just reading a directory owned by an untrusted

+ user, it is currently impossible to reliably avoid opening

+ special files.

+ 

+ There is no workaround against the instability of the file list

+ returned by `readdir`. Concurrent

+ modification of the directory can result in a list of files

+ being returned which never actually existed on disk.

+ 

+ Hard links and symbolic links can be safely deleted using

+ `unlinkat` without further checks because

+ deletion only affects the name within the directory tree being

+ processed.

+ 

+ [[sect-Defensive_Coding-Tasks-File_System-Foreign]]

+ ==== Accessing the File System as a Different User

+ 

+ This section deals with access to the file system as a specific

+ user. This is different from accessing files and directories owned by a

+ different, potentially untrusted user; see <<sect-Defensive_Coding-Tasks-File_System-Foreign>>.

+ 

+ One approach is to spawn a child process which runs under the

+ target user and group IDs (both effective and real IDs). Note

+ that this child process can block indefinitely, even when

+ processing regular files only. For example, a special FUSE file

+ system could cause the process to hang in uninterruptible sleep

+ inside a `stat` system call.

+ 

+ An existing process could change its user and group ID using

+ `setfsuid` and `setfsgid`.

+ (These functions are preferred over `seteuid`

+ and `setegid` because they do not allow the

+ impersonated user to send signals to the process.) These

+ functions are not thread safe. In multi-threaded processes,

+ these operations need to be performed in a single-threaded child

+ process. Unexpected blocking may occur as well.

+ 

+ It is not recommended to try to reimplement the kernel

+ permission checks in user space because the required checks are

+ complex. It is also very difficult to avoid race conditions

+ during path name resolution.

+ 

+ [[sect-Defensive_Coding-Tasks-File_System-Limits]]

+ ==== File System Limits

+ 

+ For historical reasons, there are preprocessor constants such as

+ `PATH_MAX`, `NAME_MAX`.

+ However, on most systems, the length of canonical path names

+ (absolute path names with all symbolic links resolved, as

+ returned by `realpath` or

+ `canonicalize_file_name`) can exceed

+ `PATH_MAX` bytes, and individual file name

+ components can be longer than `NAME_MAX`. This

+ is also true of the `_PC_PATH_MAX` and

+ `_PC_NAME_MAX` values returned by

+ `pathconf`, and the

+ `f_namemax` member of `struct

+ statvfs`. Therefore, these constants should not be

+ used. This is also reason why the

+ `readdir_r` should never be used (instead,

+ use `readdir`).

+ 

+ You should not write code in a way that assumes that there is an

+ upper limit on the number of subdirectories of a directory, the

+ number of regular files in a directory, or the link count of an

+ inode.

+ 

+ [[sect-Defensive_Coding-Tasks-File_System-Features]]

+ ==== File system features

+ 

+ Not all file systems support all features. This makes it very

+ difficult to write general-purpose tools for copying files. For

+ example, a copy operation intending to preserve file permissions

+ will generally fail when copying to a FAT file system.

+ 

+ * Some file systems are case-insensitive. Most should be

+ case-preserving, though.

+ 

+ * Name length limits vary greatly, from eight to thousands of

+ bytes. Path length limits differ as well. Most systems

+ impose an upper bound on path names passed to the kernel,

+ but using relative path names, it is possible to create and

+ access files whose absolute path name is essentially of

+ unbounded length.

+ 

+ * Some file systems do not store names as fairly unrestricted

+ byte sequences, as it has been traditionally the case on GNU

+ systems. This means that some byte sequences (outside the

+ POSIX safe character set) are not valid names. Conversely,

+ names of existing files may not be representable as byte

+ sequences, and the files are thus inaccessible on GNU

+ systems. Some file systems perform Unicode canonicalization

+ on file names. These file systems preserve case, but

+ reading the name of a just-created file using

+ `readdir` might still result in a

+ different byte sequence.

+ 

+ * Permissions and owners are not universally supported (and

+ SUID/SGID bits may not be available). For example, FAT file

+ systems assign ownership based on a mount option, and

+ generally mark all files as executable. Any attempt to

+ change permissions would result in an error.

+ 

+ * Non-regular files (device nodes, FIFOs) are not generally

+ available.

+ 

+ * Only on some file systems, files can have holes, that is,

+ not all of their contents is backed by disk storage.

+ 

+ * `ioctl` support (even fairly generic

+ functionality such as `FIEMAP` for

+ discovering physical file layout and holes) is

+ file-system-specific.

+ 

+ * Not all file systems support extended attributes, ACLs and

+ SELinux metadata. Size and naming restriction on extended

+ attributes vary.

+ 

+ * Hard links may not be supported at all (FAT) or only within

+ the same directory (AFS). Symbolic links may not be

+ available, either. Reflinks (hard links with copy-on-write

+ semantics) are still very rare. Recent systems restrict

+ creation of hard links to users which own the target file or

+ have read/write access to it, but older systems do not.

+ 

+ * Renaming (or moving) files using `rename`

+ can fail (even when `stat` indicates that

+ the source and target directories are located on the same

+ file system). This system call should work if the old and

+ new paths are located in the same directory, though.

+ 

+ * Locking semantics vary among file systems. This affects

+ advisory and mandatory locks. For example, some network

+ file systems do not allow deleting files which are opened by

+ any process.

+ 

+ * Resolution of time stamps varies from two seconds to

+ nanoseconds. Not all time stamps are available on all file

+ systems. File creation time (*birth

+ time*) is not exposed over the

+ `stat`pass:attributes[{blank}]/pass:attributes[{blank}]`fstat`

+ interface, even if stored by the file system.

+ 

+ [[sect-Defensive_Coding-Tasks-File_System-Free_Space]]

+ ==== Checking Free Space

+ 

+ The `statvfs` and

+ `fstatvfs` functions allow programs to

+ examine the number of available blocks and inodes, through the

+ members `f_bfree`, `f_bavail`,

+ `f_ffree`, and `f_favail` of

+ `struct statvfs`. Some file systems return

+ fictional values in the `f_ffree` and

+ `f_favail` fields, so the only reliable way to

+ discover if the file system still has space for a file is to try

+ to create it. The `f_bfree` field should be

+ reasonably accurate, though. 

\ No newline at end of file

en-US/Tasks-File_System.xml
file removed
-339
@@ -1,339 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Tasks-File_System">

-   <title>File system manipulation</title>

-   <para>

-     In this chapter, we discuss general file system manipulation, with

-     a focus on access files and directories to which an other,

-     potentially untrusted user has write access.

-   </para>

-   <para>

-     Temporary files are covered in their own chapter, <xref

-     linkend="chap-Defensive_Coding-Tasks-Temporary_Files"/>.

-   </para>

-   <section id="sect-Defensive_Coding-Tasks-File_System-Unowned">

-     <title>Working with files and directories owned by other users</title>

-     <para>

-       Sometimes, it is necessary to operate on files and directories

-       owned by other (potentially untrusted) users.  For example, a

-       system administrator could remove the home directory of a user,

-       or a package manager could update a file in a directory which is

-       owned by an application-specific user.  This differs from

-       accessing the file system as a specific user; see 

-       <xref linkend="sect-Defensive_Coding-Tasks-File_System-Foreign"/>.

-     </para>

-     <para>

-       Accessing files across trust boundaries faces several

-       challenges, particularly if an entire directory tree is being

-       traversed:

-     </para>

-     <orderedlist>

-       <listitem>

- 	<para>

- 	  Another user might add file names to a writable directory at

- 	  any time.  This can interfere with file creation and the

- 	  order of names returned by <function>readdir</function>.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Merely opening and closing a file can have side effects.

- 	  For instance, an automounter can be triggered, or a tape

- 	  device rewound.  Opening a file on a local file system can

- 	  block indefinitely, due to mandatory file locking, unless

- 	  the <literal>O_NONBLOCK</literal> flag is specified.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Hard links and symbolic links can redirect the effect of

- 	  file system operations in unexpected ways.  The

- 	  <literal>O_NOFOLLOW</literal> and

- 	  <literal>AT_SYMLINK_NOFOLLOW</literal> variants of system

- 	  calls only affected final path name component.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The structure of a directory tree can change.  For example,

- 	  the parent directory of what used to be a subdirectory

- 	  within the directory tree being processed could suddenly

- 	  point outside that directory tree.

- 	</para>

-       </listitem>

-     </orderedlist>

-     <para>

-       Files should always be created with the

-       <literal>O_CREAT</literal> and <literal>O_EXCL</literal> flags,

-       so that creating the file will fail if it already exists.  This

-       guards against the unexpected appearance of file names, either

-       due to creation of a new file, or hard-linking of an existing

-       file.  In multi-threaded programs, rather than manipulating the

-       umask, create the files with mode <literal>000</literal> if

-       possible, and adjust it afterwards with

-       <function>fchmod</function>.

-     </para>

-     <para>

-       To avoid issues related to symbolic links and directory tree

-       restructuring, the “<literal>at</literal>” variants of system

-       calls have to be used (that is, functions like

-       <function>openat</function>, <function>fchownat</function>,

-       <function>fchmodat</function>, and

-       <function>unlinkat</function>, together with

-       <literal>O_NOFOLLOW</literal> or

-       <literal>AT_SYMLINK_NOFOLLOW</literal>).  Path names passed to

-       these functions must have just a single component (that is,

-       without a slash).  When descending, the descriptors of parent

-       directories must be kept open.  The missing

-       <literal>opendirat</literal> function can be emulated with

-       <literal>openat</literal> (with an

-       <literal>O_DIRECTORY</literal> flag, to avoid opening special

-       files with side effects), followed by

-       <literal>fdopendir</literal>.

-     </para>

-     <para>

-       If the “<literal>at</literal>” functions are not available, it

-       is possible to emulate them by changing the current directory.

-       (Obviously, this only works if the process is not multi-threaded.)

-       <function>fchdir</function> has to be used to change the current

-       directory, and the descriptors of the parent directories have to

-       be kept open, just as with the “<literal>at</literal>”-based

-       approach.  <literal>chdir("...")</literal> is unsafe because it

-       might ascend outside the intended directory tree.

-     </para>

-     <para>

-       This “<literal>at</literal>” function emulation is currently

-       required when manipulating extended attributes.  In this case,

-       the <function>lsetxattr</function> function can be used, with a

-       relative path name consisting of a single component.  This also

-       applies to SELinux contexts and the

-       <function>lsetfilecon</function> function.

-     </para>

-     <para>

-       Currently, it is not possible to avoid opening special files

-       <emphasis>and</emphasis> changes to files with hard links if the

-       directory containing them is owned by an untrusted user.

-       (Device nodes can be hard-linked, just as regular files.)

-       <function>fchmodat</function> and <function>fchownat</function>

-       affect files whose link count is greater than one.  But opening

-       the files, checking that the link count is one with

-       <function>fstat</function>, and using

-       <function>fchmod</function> and <function>fchown</function> on

-       the file descriptor may have unwanted side effects, due to item

-       2 above.  When creating directories, it is therefore important

-       to change the ownership and permissions only after it has been

-       fully created.  Until that point, file names are stable, and no

-       files with unexpected hard links can be introduced.

-     </para>

-     <para>

-       Similarly, when just reading a directory owned by an untrusted

-       user, it is currently impossible to reliably avoid opening

-       special files.

-     </para>

-     <para>

-       There is no workaround against the instability of the file list

-       returned by <function>readdir</function>.  Concurrent

-       modification of the directory can result in a list of files

-       being returned which never actually existed on disk.

-     </para>

-     <para>

-       Hard links and symbolic links can be safely deleted using

-       <function>unlinkat</function> without further checks because

-       deletion only affects the name within the directory tree being

-       processed.

-     </para>

-   </section>

-   <section id="sect-Defensive_Coding-Tasks-File_System-Foreign">

-     <title>Accessing the file system as a different user</title>

-     <para>

-       This section deals with access to the file system as a specific

-       user.  This is different from accessing files and directories owned by a

-       different, potentially untrusted user; see <xref

-       linkend="sect-Defensive_Coding-Tasks-File_System-Foreign"/>.

-     </para>

-     <para>

-       One approach is to spawn a child process which runs under the

-       target user and group IDs (both effective and real IDs).  Note

-       that this child process can block indefinitely, even when

-       processing regular files only.  For example, a special FUSE file

-       system could cause the process to hang in uninterruptible sleep

-       inside a <function>stat</function> system call.

-     </para>

-     <para>

-       An existing process could change its user and group ID using

-       <function>setfsuid</function> and <function>setfsgid</function>.

-       (These functions are preferred over <function>seteuid</function>

-       and <function>setegid</function> because they do not allow the

-       impersonated user to send signals to the process.)  These

-       functions are not thread safe.  In multi-threaded processes,

-       these operations need to be performed in a single-threaded child

-       process.  Unexpected blocking may occur as well.

-     </para>

-     <para>

-       It is not recommended to try to reimplement the kernel

-       permission checks in user space because the required checks are

-       complex.  It is also very difficult to avoid race conditions

-       during path name resolution.

-     </para>

-   </section>

-   <section id="sect-Defensive_Coding-Tasks-File_System-Limits">

-     <title>File system limits</title>

-     <para>

-       For historical reasons, there are preprocessor constants such as

-       <literal>PATH_MAX</literal>, <literal>NAME_MAX</literal>.

-       However, on most systems, the length of canonical path names

-       (absolute path names with all symbolic links resolved, as

-       returned by <function>realpath</function> or

-       <function>canonicalize_file_name</function>) can exceed

-       <literal>PATH_MAX</literal> bytes, and individual file name

-       components can be longer than <literal>NAME_MAX</literal>.  This

-       is also true of the <literal>_PC_PATH_MAX</literal> and

-       <literal>_PC_NAME_MAX</literal> values returned by

-       <function>pathconf</function>, and the

-       <literal>f_namemax</literal> member of <literal>struct

-       statvfs</literal>.  Therefore, these constants should not be

-       used.  This is also reason why the

-       <function>readdir_r</function> should never be used (instead,

-       use <function>readdir</function>).

-     </para>

-     <para>

-       You should not write code in a way that assumes that there is an

-       upper limit on the number of subdirectories of a directory, the

-       number of regular files in a directory, or the link count of an

-       inode.

-     </para>

-   </section>

-   <section id="sect-Defensive_Coding-Tasks-File_System-Features">

-     <title>File system features</title>

-     <para>

-       Not all file systems support all features.  This makes it very

-       difficult to write general-purpose tools for copying files.  For

-       example, a copy operation intending to preserve file permissions

-       will generally fail when copying to a FAT file system.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Some file systems are case-insensitive.  Most should be

- 	  case-preserving, though.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Name length limits vary greatly, from eight to thousands of

- 	  bytes.  Path length limits differ as well.  Most systems

- 	  impose an upper bound on path names passed to the kernel,

- 	  but using relative path names, it is possible to create and

- 	  access files whose absolute path name is essentially of

- 	  unbounded length.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Some file systems do not store names as fairly unrestricted

- 	  byte sequences, as it has been traditionally the case on GNU

- 	  systems.  This means that some byte sequences (outside the

- 	  POSIX safe character set) are not valid names.  Conversely,

- 	  names of existing files may not be representable as byte

- 	  sequences, and the files are thus inaccessible on GNU

- 	  systems.  Some file systems perform Unicode canonicalization

- 	  on file names.  These file systems preserve case, but

- 	  reading the name of a just-created file using

- 	  <function>readdir</function> might still result in a

- 	  different byte sequence.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Permissions and owners are not universally supported (and

- 	  SUID/SGID bits may not be available).  For example, FAT file

- 	  systems assign ownership based on a mount option, and

- 	  generally mark all files as executable.  Any attempt to

- 	  change permissions would result in an error.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Non-regular files (device nodes, FIFOs) are not generally

- 	  available.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Only on some file systems, files can have holes, that is,

- 	  not all of their contents is backed by disk storage.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  <function>ioctl</function> support (even fairly generic

- 	  functionality such as <literal>FIEMAP</literal> for

- 	  discovering physical file layout and holes) is

- 	  file-system-specific.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Not all file systems support extended attributes, ACLs and

- 	  SELinux metadata.  Size and naming restriction on extended

- 	  attributes vary.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Hard links may not be supported at all (FAT) or only within

- 	  the same directory (AFS).  Symbolic links may not be

- 	  available, either.  Reflinks (hard links with copy-on-write

- 	  semantics) are still very rare.  Recent systems restrict

- 	  creation of hard links to users which own the target file or

- 	  have read/write access to it, but older systems do not.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Renaming (or moving) files using <function>rename</function>

- 	  can fail (even when <function>stat</function> indicates that

- 	  the source and target directories are located on the same

- 	  file system).  This system call should work if the old and

- 	  new paths are located in the same directory, though.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Locking semantics vary among file systems.  This affects

- 	  advisory and mandatory locks.  For example, some network

- 	  file systems do not allow deleting files which are opened by

- 	  any process.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Resolution of time stamps varies from two seconds to

- 	  nanoseconds.  Not all time stamps are available on all file

- 	  systems.  File creation time (<emphasis>birth

- 	  time</emphasis>) is not exposed over the

- 	  <function>stat</function>/<function>fstat</function>

- 	  interface, even if stored by the file system.

- 	</para>

-       </listitem>

-     </itemizedlist>

-   </section>

-   <section id="sect-Defensive_Coding-Tasks-File_System-Free_Space">

-     <title>Checking free space</title>

-     <para>

-       The <function>statvfs</function> and

-       <function>fstatvfs</function> functions allow programs to

-       examine the number of available blocks and inodes, through the

-       members <literal>f_bfree</literal>, <literal>f_bavail</literal>,

-       <literal>f_ffree</literal>, and <literal>f_favail</literal> of

-       <literal>struct statvfs</literal>.  Some file systems return

-       fictional values in the <literal>f_ffree</literal> and

-       <literal>f_favail</literal> fields, so the only reliable way to

-       discover if the file system still has space for a file is to try

-       to create it.  The <literal>f_bfree</literal> field should be

-       reasonably accurate, though.

-     </para>

-   </section>

- </chapter>

- 

en-US/Tasks-Library_Design.adoc
file added
+151
@@ -0,0 +1,151 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Tasks-Library_Design]]

+ === Library Design

+ 

+ Through this section, the term *client code*

+ refers to applications and other libraries using the library.

+ 

+ ==== State Management

+ 

+ ===== Global State

+ 

+ Global state should be avoided.

+ 

+ If this is impossible, the global state must be protected with

+ a lock. For C/C++, you can use the

+ `pthread_mutex_lock`

+ and `pthread_mutex_unlock`

+ functions without linking against `-lpthread`

+ because the system provides stubs for non-threaded processes.

+ 

+ For compatibility with `fork`, these locks

+ should be acquired and released in helpers registered with

+ `pthread_atfork`. This function is not

+ available without `-lpthread`, so you need to

+ use `dlsym` or a weak symbol to obtain its

+ address.

+ 

+ If you need `fork` protection for other

+ reasons, you should store the process ID and compare it to the

+ value returned by `getpid` each time you

+ access the global state. (`getpid` is not

+ implemented as a system call and is fast.) If the value

+ changes, you know that you have to re-create the state object.

+ (This needs to be combined with locking, of course.)

+ 

+ ===== Handles

+ 

+ Library state should be kept behind a curtain. Client code

+ should receive only a handle. In C, the handle can be a

+ pointer to an incomplete `struct`. In C++,

+ the handle can be a pointer to an abstract base class, or it

+ can be hidden using the pointer-to-implementation idiom.

+ 

+ The library should provide functions for creating and

+ destroying handles. (In C++, it is possible to use virtual

+ destructors for the latter.) Consistency between creation and

+ destruction of handles is strongly recommended: If the client

+ code created a handle, it is the responsibility of the client

+ code to destroy it. (This is not always possible or

+ convenient, so sometimes, a transfer of ownership has to

+ happen.)

+ 

+ Using handles ensures that it is possible to change the way

+ the library represents state in a way that is transparent to

+ client code. This is important to facilitate security updates

+ and many other code changes.

+ 

+ It is not always necessary to protect state behind a handle

+ with a lock. This depends on the level of thread safety

+ the library provides.

+ 

+ ==== Object Orientation

+ 

+ Classes should be either designed as base classes, or it should

+ be impossible to use them as base classes (like

+ `final` classes in Java). Classes which are

+ not designed for inheritance and are used as base classes

+ nevertheless create potential maintenance hazards because it is

+ difficult to predict how client code will react when calls to

+ virtual methods are added, reordered or removed.

+ 

+ Virtual member functions can be used as callbacks. See 

+ <<sect-Defensive_Coding-Tasks-Library_Design-Callbacks>>

+ for some of the challenges involved.

+ 

+ [[sect-Defensive_Coding-Tasks-Library_Design-Callbacks]]

+ ==== Callbacks

+ 

+ Higher-order code is difficult to analyze for humans and

+ computers alike, so it should be avoided. Often, an

+ iterator-based interface (a library function which is called

+ repeatedly by client code and returns a stream of events) leads

+ to a better design which is easier to document and use.

+ 

+ If callbacks are unavoidable, some guidelines for them follow.

+ 

+ In modern C++ code, `std::function` objects

+ should be used for callbacks.

+ 

+ In older C++ code and in C code, all callbacks must have an

+ additional closure parameter of type `void *`,

+ the value of which can be specified by client code. If

+ possible, the value of the closure parameter should be provided

+ by client code at the same time a specific callback is

+ registered (or specified as a function argument). If a single

+ closure parameter is shared by multiple callbacks, flexibility

+ is greatly reduced, and conflicts between different pieces of

+ client code using the same library object could be unresolvable.

+ In some cases, it makes sense to provide a de-registration

+ callback which can be used to destroy the closure parameter when

+ the callback is no longer used.

+ 

+ Callbacks can throw exceptions or call

+ `longjmp`. If possible, all library objects

+ should remain in a valid state. (All further operations on them

+ can fail, but it should be possible to deallocate them without

+ causing resource leaks.)

+ 

+ The presence of callbacks raises the question if functions

+ provided by the library are *reentrant*.

+ Unless a library was designed for such use, bad things will

+ happen if a callback function uses functions in the same library

+ (particularly if they are invoked on the same objects and

+ manipulate the same state). When the callback is invoked, the

+ library can be in an inconsistent state. Reentrant functions

+ are more difficult to write than thread-safe functions (by

+ definition, simple locking would immediately lead to deadlocks).

+ It is also difficult to decide what to do when destruction of an

+ object which is currently processing a callback is requested.

+ 

+ ==== Process Attributes

+ 

+ Several attributes are global and affect all code in the

+ process, not just the library that manipulates them.

+ 

+ * environment variables

+ (see <<sect-Defensive_Coding-Tasks-secure_getenv>>)

+ 

+ * umask

+ 

+ * user IDs, group IDs and capabilities

+ 

+ * current working directory

+ 

+ * signal handlers, signal masks and signal delivery

+ 

+ * file locks (especially `fcntl` locks

+ behave in surprising ways, not just in a multi-threaded

+ environment)

+ 

+ Library code should avoid manipulating these global process

+ attributes. It should not rely on environment variables, umask,

+ the current working directory and signal masks because these

+ attributes can be inherited from an untrusted source.

+ 

+ In addition, there are obvious process-wide aspects such as the

+ virtual memory layout, the set of open files and dynamic shared

+ objects, but with the exception of shared objects, these can be

+ manipulated in a relatively isolated way. 

\ No newline at end of file

en-US/Tasks-Library_Design.xml
file removed
-195
@@ -1,195 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Tasks-Library_Design">

-   <title>Library Design</title>

-   <para>

-     Throught this section, the term <emphasis>client code</emphasis>

-     refers to applications and other libraries using the library.

-   </para>

- 

-   <section>

-     <title>State management</title>

-     <para>

-     </para>

-     <section>

-       <title>Global state</title>

-       <para>

- 	Global state should be avoided.

-       </para>

-       <para>

- 	If this is impossible, the global state must be protected with

- 	a lock.  For C/C++, you can use the

- 	<function>pthread_mutex_lock</function>

- 	and <function>pthread_mutex_unlock</function>

- 	functions without linking against <literal>-lpthread</literal>

- 	because the system provides stubs for non-threaded processes.

-       </para>

-       <para>

- 	For compatibility with <function>fork</function>, these locks

- 	should be acquired and released in helpers registered with

- 	<function>pthread_atfork</function>.  This function is not

- 	available without <literal>-lpthread</literal>, so you need to

- 	use <function>dlsym</function> or a weak symbol to obtain its

- 	address.

-       </para>

-       <para>

- 	If you need <function>fork</function> protection for other

- 	reasons, you should store the process ID and compare it to the

- 	value returned by <function>getpid</function> each time you

- 	access the global state.  (<function>getpid</function> is not

- 	implemented as a system call and is fast.)  If the value

- 	changes, you know that you have to re-create the state object.

- 	(This needs to be combined with locking, of course.)

-       </para>

-     </section>

-     <section>

-       <title>Handles</title>

-       <para>

- 	Library state should be kept behind a curtain.  Client code

- 	should receive only a handle.  In C, the handle can be a

- 	pointer to an incomplete <literal>struct</literal>.  In C++,

- 	the handle can be a pointer to an abstract base class, or it

- 	can be hidden using the pointer-to-implementation idiom.

-       </para>

-       <para>

- 	The library should provide functions for creating and

- 	destroying handles.  (In C++, it is possible to use virtual

- 	destructors for the latter.)  Consistency between creation and

- 	destruction of handles is strongly recommended: If the client

- 	code created a handle, it is the responsibility of the client

- 	code to destroy it.  (This is not always possible or

- 	convenient, so sometimes, a transfer of ownership has to

- 	happen.)

-       </para>

-       <para>

- 	Using handles ensures that it is possible to change the way

- 	the library represents state in a way that is transparent to

- 	client code.  This is important to facilitate security updates

- 	and many other code changes.

-       </para>

-       <para>

- 	It is not always necessary to protect state behind a handle

- 	with a lock.  This depends on the level of thread safety

- 	the library provides.

-       </para>

-     </section>

-   </section>

- 

-   <section>

-     <title>Object orientation</title>

-     <para>

-       Classes should be either designed as base classes, or it should

-       be impossible to use them as base classes (like

-       <literal>final</literal> classes in Java).  Classes which are

-       not designed for inheritance and are used as base classes

-       nevertheless create potential maintenance hazards because it is

-       difficult to predict how client code will react when calls to

-       virtual methods are added, reordered or removed.

-     </para>

-     <para>

-       Virtual member functions can be used as callbacks.  See 

-       <xref linkend="sect-Defensive_Coding-Tasks-Library_Design-Callbacks"/>

-       for some of the challenges involved.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Tasks-Library_Design-Callbacks">

-     <title>Callbacks</title>

-     <para>

-       Higher-order code is difficult to analyze for humans and

-       computers alike, so it should be avoided.  Often, an

-       iterator-based interface (a library function which is called

-       repeatedly by client code and returns a stream of events) leads

-       to a better design which is easier to document and use.

-     </para>

-     <para>

-       If callbacks are unavoidable, some guidelines for them follow.

-     </para>

-     <para>

-       In modern C++ code, <literal>std::function</literal> objects

-       should be used for callbacks.

-     </para>

-     <para>

-       In older C++ code and in C code, all callbacks must have an

-       additional closure parameter of type <literal>void *</literal>,

-       the value of which can be specified by client code.  If

-       possible, the value of the closure parameter should be provided

-       by client code at the same time a specific callback is

-       registered (or specified as a function argument).  If a single

-       closure parameter is shared by multiple callbacks, flexibility

-       is greatly reduced, and conflicts between different pieces of

-       client code using the same library object could be unresolvable.

-       In some cases, it makes sense to provide a de-registration

-       callback which can be used to destroy the closure parameter when

-       the callback is no longer used.

-     </para>

-     <para>

-       Callbacks can throw exceptions or call

-       <function>longjmp</function>.  If possible, all library objects

-       should remain in a valid state.  (All further operations on them

-       can fail, but it should be possible to deallocate them without

-       causing resource leaks.)

-     </para>

-     <para>

-       The presence of callbacks raises the question if functions

-       provided by the library are <emphasis>reentrant</emphasis>.

-       Unless a library was designed for such use, bad things will

-       happen if a callback function uses functions in the same library

-       (particularly if they are invoked on the same objects and

-       manipulate the same state).  When the callback is invoked, the

-       library can be in an inconsistent state.  Reentrant functions

-       are more difficult to write than thread-safe functions (by

-       definition, simple locking would immediately lead to deadlocks).

-       It is also difficult to decide what to do when destruction of an

-       object which is currently processing a callback is requested.

-     </para>

-   </section>

- 

-   <section>

-     <title>Process attributes</title>

-     <para>

-       Several attributes are global and affect all code in the

-       process, not just the library that manipulates them.

-     </para>

-     <itemizedlist>

-     <listitem><para>

-       environment variables

-       (see <xref linkend="sect-Defensive_Coding-Tasks-secure_getenv"/>)

-     </para></listitem>

-     <listitem><para>

-       umask

-     </para></listitem>

-     <listitem><para>

-       user IDs, group IDs and capabilities

-     </para></listitem>

-     <listitem><para>

-       current working directory

-     </para></listitem>

-     <listitem><para>

-       signal handlers, signal masks and signal delivery

-     </para></listitem>

-     <listitem><para>

-       file locks (especially <function>fcntl</function> locks

-       behave in surprising ways, not just in a multi-threaded

-       environment)

-     </para></listitem>

-     </itemizedlist>

-     <para>

-       Library code should avoid manipulating these global process

-       attributes.  It should not rely on environment variables, umask,

-       the current working directory and signal masks because these

-       attributes can be inherted from an untrusted source.

-     </para>

-     <para>

-       In addition, there are obvious process-wide aspects such as the

-       virtual memory layout, the set of open files and dynamic shared

-       objects, but with the exception of shared objects, these can be

-       manipulated in a relatively isolated way.

-     </para>

- 

-   </section>

- 

- </chapter>

- 

- 

en-US/Tasks-Locking.xml
file removed
-5
@@ -1,5 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="sect-Defensive_Coding-Tasks-Locking">

- </chapter>

en-US/Tasks-Packaging.adoc
file added
+180
@@ -0,0 +1,180 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Tasks-Packaging]]

+ === RPM Packaging

+ 

+ This chapter deals with security-related concerns around RPM

+ packaging. It has to be read in conjunction with

+ distribution-specific packaging guidelines.

+ 

+ [[sect-Defensive_Coding-Tasks-Packaging-Certificates]]

+ ==== Generating X.509 Self-signed Certificates during

+     Installation

+ 

+ Some applications need X.509 certificates for authentication

+ purposes. For example, a single private/public key pair could

+ be used to define cluster membership, enabling authentication

+ and encryption of all intra-cluster communication. (Lack of

+ certification from a CA matters less in such a context.) For

+ such use, generating the key pair at package installation time

+ when preparing system images for use in the cluster is

+ reasonable. For other use cases, it is necessary to generate

+ the key pair before the service is started for the first time,

+ see <<sect-Defensive_Coding-Tasks-Packaging-Certificates-Service>>,

+ and link:++https://fedoraproject.org/wiki/Packaging:Initial_Service_Setup#Generating_Self-Signed_Certificates++[Packaging:Initial Service Setup].

+ 

+ [IMPORTANT]

+ ====

+ 

+ The way the key is generated may not be suitable for key

+ material of critical value. ([command]`openssl

+ genrsa` uses, but does not require, entropy from a

+ physical source of randomness, among other things.) Such keys

+ should be stored in a hardware security module if possible,

+ and generated from random bits reserved for this purpose

+ derived from a non-deterministic physical source.

+ 

+ ====

+ 

+ In the spec file, we define two RPM variables which contain the

+ names of the files used to store the private and public key, and

+ the user name for the service:

+ 

+ [source,bash]

+ ----

+ # Name of the user owning the file with the private key

+ %define tlsuser %{name}

+ # Name of the directory which contains the key and certificate files

+ %define tlsdir %{_sysconfdir}/%{name}

+ %define tlskey %{tlsdir}/%{name}.key

+ %define tlscert %{tlsdir}/%{name}.crt     

+ ----

+ 

+ These variables likely need adjustment based on the needs of the

+ package.

+ 

+ Typically, the file with the private key needs to be owned by

+ the system user which needs to read it,

+ `%{tlsuser}` (not `root`). In

+ order to avoid races, if the *directory*

+ `%{tlsdir}` is *owned by the services

+ user*, you should use the code in <<ex-Defensive_Coding-Packaging-Certificates-Owned>>.

+ The invocation of [application]*su* with the

+ [option]`-s /bin/bash` argument is necessary in case the

+ login shell for the user has been disabled.

+ 

+ [[ex-Defensive_Coding-Packaging-Certificates-Owned]]

+ .Creating a key pair in a user-owned directory

+ ====

+ 

+ [source,bash]

+ ----

+ %post

+ if [ $1 -eq 1 ] ; then

+   if ! test -e %{tlskey} ; then

+     su -s /bin/bash \

+       -c "umask 077 && openssl genrsa -out %{tlskey} 2048 2>/dev/null" \

+       %{tlsuser}

+   fi

+   if ! test -e %{tlscert} ; then

+     cn="Automatically generated certificate for the %{tlsuser} service"

+     req_args="-key %{tlskey} -out %{tlscert} -days 7305 -subj \"/CN=$cn/\""

+     su -s /bin/bash \

+       -c "openssl req -new -x509 -extensions usr_cert $req_args" \

+       %{tlsuser}

+   fi

+ fi

+ 

+ %files

+ %dir %attr(0755,%{tlsuser},%{tlsuser]) %{tlsdir}

+ %ghost %attr(0600,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlskey}

+ %ghost %attr(0644,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlscert}    

+ ----

+ 

+ ====

+ 

+ The files containing the key material are marked as ghost

+ configuration files. This ensures that they are tracked in the

+ RPM database as associated with the package, but RPM will not

+ create them when the package is installed and not verify their

+ contents (the `%ghost`), or delete the files

+ when the package is uninstalled (the

+ `%config(noreplace)` part).

+ 

+ If the *directory*

+ `%{tlsdir}` *is owned by*

+ `root`, use the code in <<ex-Defensive_Coding-Packaging-Certificates-Unowned>>.

+ 

+ [[ex-Defensive_Coding-Packaging-Certificates-Unowned]]

+ .Creating a key pair in a `root`-owned directory

+ ====

+ 

+ [source,bash]

+ ----

+ %post

+ if [ $1 -eq 1 ] ; then

+   if ! test -e %{tlskey} ; then

+     (umask 077 && openssl genrsa -out %{tlskey} 2048 2>/dev/null)

+     chown %{tlsuser} %{tlskey}

+   fi

+   if ! test -e %{tlscert} ; then

+     cn="Automatically generated certificate for the %{tlsuser} service"

+     openssl req -new -x509 -extensions usr_cert \

+       -key %{tlskey} -out %{tlscert} -days 7305 -subj "/CN=$cn/"

+   fi

+ fi

+ 

+ %files

+ %dir %attr(0755,root,root]) %{tlsdir}

+ %ghost %attr(0600,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlskey}

+ %ghost %attr(0644,root,root) %config(noreplace) %{tlscert}    

+ ----

+ 

+ ====

+ 

+ In order for this to work, the package which generates the keys

+ must require the [application]*openssl* package. If

+ the user which owns the key file is generated by a different

+ package, the package generating the certificate must specify a

+ `Requires(pre):` on the package which creates

+ the user. This ensures that the user account will exist when it

+ is needed for the [application]*su* or

+ [application]*chmod* invocation.

+ 

+ [[sect-Defensive_Coding-Tasks-Packaging-Certificates-Service]]

+ ==== Generating X.509 Self-signed Certificates before Service Start

+ 

+ An alternative way to automatically provide an X.509 key pair is

+ to create it just before the service is started for the first

+ time. This ensures that installation images which are created

+ from installed RPM packages receive different key material.

+ Creating the key pair at package installation time (see <<sect-Defensive_Coding-Tasks-Packaging-Certificates>>)

+ would put the key into the image, which may or may not make

+ sense.

+ 

+ [IMPORTANT]

+ ====

+ 

+ The caveats about the way the key is generated in <<sect-Defensive_Coding-Tasks-Packaging-Certificates>>

+ apply to this procedure as well.

+ 

+ ====

+ 

+ Generating key material before service start may happen very

+ early during boot, when the kernel randomness pool has not yet

+ been initialized. Currently, the only way to check for the

+ initialization is to look for the kernel message

+ `random: nonblocking pool is initialized`, or

+ ensure that the application used for generating the keys

+ is utilizing the `getrandom()` system call.

+ 

+ In theory, it is also possible to use an application which reads from

+ `/dev/random` while generating the key

+ material (instead of `/dev/urandom`), but

+ this can block not just during the boot process, but also much

+ later at run time, and generally results in a poor user

+ experience.

+ 

+ The requirements for generating such keys is documented at

+ link:++https://fedoraproject.org/wiki/Packaging:Initial_Service_Setup#Generating_Self-Signed_Certificates++[Packaging:Initial Service Setup].

en-US/Tasks-Packaging.xml
file removed
-175
@@ -1,175 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Tasks-Packaging">

-   <title>RPM packaging</title>

-   <para>

-     This chapter deals with security-related concerns around RPM

-     packaging.  It has to be read in conjunction with

-     distribution-specific packaging guidelines.

-   </para>

-   <section id="sect-Defensive_Coding-Tasks-Packaging-Certificates">

-     <title>Generating X.509 self-signed certificates during

-     installation</title>

-     <para>

-       Some applications need X.509 certificates for authentication

-       purposes.  For example, a single private/public key pair could

-       be used to define cluster membership, enabling authentication

-       and encryption of all intra-cluster communication.  (Lack of

-       certification from a CA matters less in such a context.)  For

-       such use, generating the key pair at package installation time

-       when preparing system images for use in the cluster is

-       reasonable.  For other use cases, it is necessary to generate

-       the key pair before the service is started for the first time,

-       see <xref linkend="sect-Defensive_Coding-Tasks-Packaging-Certificates-Service"/>.

-     </para>

-     <important>

-       <para>

- 	The way the key is generated may not be suitable for key

- 	material of critical value.  (<command>openssl

- 	genrsa</command> uses, but does not require, entropy from a

- 	physical source of randomness, among other things.)  Such keys

- 	should be stored in a hardware security module if possible,

- 	and generated from random bits reserved for this purpose

- 	derived from a non-deterministic physical source.

-       </para>

-     </important>

-     <para>

-       In the spec file, we define two RPM variables which contain the

-       names of the files used to store the private and public key, and

-       the user name for the service:

-     </para>

-     <informalexample>

-       <programlisting language="RPM Spec">

- # Name of the user owning the file with the private key

- %define tlsuser %{name}

- # Name of the directory which contains the key and certificate files

- %define tlsdir %{_sysconfdir}/%{name}

- %define tlskey %{tlsdir}/%{name}.key

- %define tlscert %{tlsdir}/%{name}.crt

-       </programlisting>

-     </informalexample>

-     <para>

-       These variables likely need adjustment based on the needs of the

-       package.

-     </para>

-     <para>

-       Typically, the file with the private key needs to be owned by

-       the system user which needs to read it,

-       <literal>%{tlsuser}</literal> (not <literal>root</literal>).  In

-       order to avoid races, if the <emphasis>directory</emphasis>

-       <literal>%{tlsdir}</literal> is <emphasis>owned by the services

-       user</emphasis>, you should use the code in <xref

-       linkend="ex-Defensive_Coding-Packaging-Certificates-Owned"/>.

-       The invocation of <application>su</application> with the

-       <option>-s /bin/bash</option> argument is necessary in case the

-       login shell for the user has been disabled.

-     </para>

-     <example id="ex-Defensive_Coding-Packaging-Certificates-Owned">

-       <title>Creating a key pair in a user-owned directory</title>

-       <programlisting language="Bash">

- %post

- if [ $1 -eq 1 ] ; then

-   if ! test -e %{tlskey} ; then

-     su -s /bin/bash \

-       -c "umask 077 &amp;&amp; openssl genrsa -out %{tlskey} 2048 2>/dev/null" \

-       %{tlsuser}

-   fi

-   if ! test -e %{tlscert} ; then

-     cn="Automatically generated certificate for the %{tlsuser} service"

-     req_args="-key %{tlskey} -out %{tlscert} -days 7305 -subj \"/CN=$cn/\""

-     su -s /bin/bash \

-       -c "openssl req -new -x509 -extensions usr_cert $req_args" \

-       %{tlsuser}

-   fi

- fi

- 

- %files

- %dir %attr(0755,%{tlsuser},%{tlsuser]) %{tlsdir}

- %ghost %attr(0600,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlskey}

- %ghost %attr(0644,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlscert}

-       </programlisting>

-     </example>

-     <para>

-       The files containing the key material are marked as ghost

-       configuration files.  This ensures that they are tracked in the

-       RPM database as associated with the package, but RPM will not

-       create them when the package is installed and not verify their

-       contents (the <literal>%ghost</literal>), or delete the files

-       when the package is uninstalled (the

-       <literal>%config(noreplace)</literal> part).

-     </para>

-     <para>

-       If the <emphasis>directory</emphasis>

-       <literal>%{tlsdir}</literal> <emphasis>is owned by</emphasis>

-       <literal>root</literal>, use the code in <xref

-       linkend="ex-Defensive_Coding-Packaging-Certificates-Unowned"/>.

-     </para>

-     <example id="ex-Defensive_Coding-Packaging-Certificates-Unowned">

-       <title>Creating a key pair in a <literal>root</literal>-owned directory</title>

-       <programlisting language="Bash">

- %post

- if [ $1 -eq 1 ] ; then

-   if ! test -e %{tlskey} ; then

-     (umask 077 &amp;&amp; openssl genrsa -out %{tlskey} 2048 2>/dev/null)

-     chown %{tlsuser} %{tlskey}

-   fi

-   if ! test -e %{tlscert} ; then

-     cn="Automatically generated certificate for the %{tlsuser} service"

-     openssl req -new -x509 -extensions usr_cert \

-       -key %{tlskey} -out %{tlscert} -days 7305 -subj "/CN=$cn/"

-   fi

- fi

- 

- %files

- %dir %attr(0755,root,root]) %{tlsdir}

- %ghost %attr(0600,%{tlsuser},%{tlsuser}) %config(noreplace) %{tlskey}

- %ghost %attr(0644,root,root) %config(noreplace) %{tlscert}

-       </programlisting>

-     </example>

-     <para>

-       In order for this to work, the package which generates the keys

-       must require the <application>openssl</application> package.  If

-       the user which owns the key file is generated by a different

-       package, the package generating the certificate must specify a

-       <literal>Requires(pre):</literal> on the package which creates

-       the user.  This ensures that the user account will exist when it

-       is needed for the <application>su</application> or

-       <application>chmod</application> invocation.

-     </para>

-   </section>

-   <section id="sect-Defensive_Coding-Tasks-Packaging-Certificates-Service">

-     <title>Generating X.509 self-signed certificates before service

-     start</title>

-     <para>

-       An alternative way to automatically provide an X.509 key pair is

-       to create it just before the service is started for the first

-       time.  This ensures that installation images which are created

-       from installed RPM packages receive different key material.

-       Creating the key pair at package installation time (see <xref

-       linkend="sect-Defensive_Coding-Tasks-Packaging-Certificates"/>)

-       would put the key into the image, which may or may not make

-       sense.

-     </para>

-     <important>

-       <para>

- 	The caveats about the way the key is generated in <xref

- 	linkend="sect-Defensive_Coding-Tasks-Packaging-Certificates"/>

- 	apply to this procedure as well.

-     </para>

-     </important>

-     <para>

-       Generating key material before service start may happen very

-       early during boot, when the kernel randomness pool has not yet

-       been initialized.  Currently, the only way to check for the

-       initialization is to look for the kernel message

-       <literal>random: nonblocking pool is initialized</literal>.  In

-       theory, it is also possible to read from

-       <filename>/dev/random</filename> while generating the key

-       material (instead of <filename>/dev/urandom</filename>), but

-       this can block not just during the boot process, but also much

-       later at run time, and generally results in a poor user

-       experience.

-     </para>

-   </section>

- </chapter>

en-US/Tasks-Processes.adoc
file added
+377
@@ -0,0 +1,377 @@

+ 

+ :experimental:

+ include::entities.adoc[]

+ 

+ [[sect-Defensive_Coding-Tasks-Processes]]

+ === Processes

+ 

+ [[sect-Defensive_Coding-Tasks-Processes-Creation]]

+ ==== Creating Safe Processes

+ 

+ This section describes how to create new child processes in a

+ safe manner. In addition to the concerns addressed below, there

+ is the possibility of file descriptor leaks, see <<sect-Defensive_Coding-Tasks-Descriptors-Child_Processes>>.

+ 

+ ===== Obtaining the Program Path and the Command-line Template

+ 

+ The name and path to the program being invoked should be

+ hard-coded or controlled by a static configuration file stored

+ at a fixed location (at an file system absolute path). The

+ same applies to the template for generating the command line.

+ 

+ The configured program name should be an absolute path. If it

+ is a relative path, the contents of the `PATH`

+ must be obtained in a secure manner (see <<sect-Defensive_Coding-Tasks-secure_getenv>>).

+ If the `PATH` variable is not set or untrusted,

+ the safe default `/bin:/usr/bin` must be

+ used.

+ 

+ If too much flexibility is provided here, it may allow

+ invocation of arbitrary programs without proper authorization.

+ 

+ [[sect-Defensive_Coding-Tasks-Processes-execve]]

+ ===== Bypassing the Shell

+ 

+ Child processes should be created without involving the system

+ shell.

+ 

+ For C/C++, `system` should not be used.

+ The `posix_spawn` function can be used

+ instead, or a combination `fork` and

+ `execve`. (In some cases, it may be

+ preferable to use `vfork` or the

+ Linux-specific `clone` system call instead

+ of `fork`.)

+ 

+ In Python, the `subprocess` module bypasses

+ the shell by default (when the `shell`

+ keyword argument is not set to true).

+ `os.system` should not be used.

+ 

+ The Java class `java.lang.ProcessBuilder` can be

+ used to create subprocesses without interference from the

+ system shell.

+ 

+ .Portability notice

+ [IMPORTANT]

+ ====

+ 

+ On Windows, there is no argument vector, only a single

+ argument string. Each application is responsible for parsing

+ this string into an argument vector. There is considerable

+ variance among the quoting style recognized by applications.

+ Some of them expand shell wildcards, others do not. Extensive

+ application-specific testing is required to make this secure.

+ 

+ ====

+ 

+ Note that some common applications (notably

+ [application]*ssh*) unconditionally introduce the

+ use of a shell, even if invoked directly without a shell. It is

+ difficult to use these applications in a secure manner. In this

+ case, untrusted data should be supplied by other means. For

+ example, standard input could be used, instead of the command

+ line.

+ 

+ [[sect-Defensive_Coding-Tasks-Processes-environ]]

+ ===== Specifying the Process Environment

+ 

+ Child processes should be created with a minimal set of

+ environment variables. This is absolutely essential if there

+ is a trust transition involved, either when the parent process

+ was created, or during the creation of the child process.

+ 

+ In C/C++, the environment should be constructed as an array of

+ strings and passed as the `envp` argument to

+ `posix_spawn` or `execve`.

+ The functions `setenv`,

+ `unsetenv` and `putenv`

+ should not be used. They are not thread-safe and suffer from

+ memory leaks.

+ 

+ Python programs need to specify a `dict` for

+ the the `env` argument of the

+ `subprocess.Popen` constructor.

+ The Java class `java.lang.ProcessBuilder`

+ provides a `environment()` method,

+ which returns a map that can be manipulated.

+ 

+ The following list provides guidelines for selecting the set

+ of environment variables passed to the child process.

+ 

+ * `PATH` should be initialized to

+ `/bin:/usr/bin`.

+ 

+ * `USER` and `HOME` can be inhereted

+ from the parent process environment, or they can be

+ initialized from the `pwent` structure

+ for the user.

+ 

+ * The `DISPLAY` and `XAUTHORITY`

+ variables should be passed to the subprocess if it is an X

+ program. Note that this will typically not work across trust

+ boundaries because `XAUTHORITY` refers to a file

+ with `0600` permissions.

+ 

+ * The location-related environment variables

+ `LANG`, `LANGUAGE`,

+ `LC_ADDRESS`, `LC_ALL`,

+ `LC_COLLATE`, `LC_CTYPE`,

+ `LC_IDENTIFICATION`,

+ `LC_MEASUREMENT`, `LC_MESSAGES`,

+ `LC_MONETARY`, `LC_NAME`,

+ `LC_NUMERIC`, `LC_PAPER`,

+ `LC_TELEPHONE` and `LC_TIME`

+ can be passed to the subprocess if present.

+ 

+ * The called process may need application-specific

+ environment variables, for example for passing passwords.

+ (See <<sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility>>.)

+ 

+ * All other environment variables should be dropped. Names

+ for new environment variables should not be accepted from

+ untrusted sources.

+ 

+ ===== Robust Argument List Processing

+ 

+ When invoking a program, it is sometimes necessary to include

+ data from untrusted sources. Such data should be checked

+ against embedded `NUL` characters because the

+ system APIs will silently truncate argument strings at the first

+ `NUL` character.

+ 

+ The following recommendations assume that the program being

+ invoked uses GNU-style option processing using

+ `getopt_long`. This convention is widely

+ used, but it is just that, and individual programs might

+ interpret a command line in a different way.

+ 

+ If the untrusted data has to go into an option, use the

+ `--option-name=VALUE` syntax, placing the

+ option and its value into the same command line argument.

+ This avoids any potential confusion if the data starts with

+ `-`.

+ 

+ For positional arguments, terminate the option list with a

+ single [option]`--` marker after the last option, and

+ include the data at the right position. The

+ [option]`--` marker terminates option processing, and

+ the data will not be treated as an option even if it starts

+ with a dash.

+ 

+ [[sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility]]

+ ===== Passing Secrets to Subprocesses

+ 

+ The command line (the name of the program and its argument) of

+ a running process is traditionally available to all local

+ users. The called program can overwrite this information, but

+ only after it has run for a bit of time, during which the

+ information may have been read by other processes. However,

+ on Linux, the process environment is restricted to the user

+ who runs the process. Therefore, if you need a convenient way

+ to pass a password to a child process, use an environment

+ variable, and not a command line argument. (See <<sect-Defensive_Coding-Tasks-Processes-environ>>.)

+ 

+ .Portability notice

+ [IMPORTANT]

+ ====

+ 

+ On some UNIX-like systems (notably Solaris), environment

+ variables can be read by any system user, just like command

+ lines.

+ 

+ ====

+ 

+ If the environment-based approach cannot be used due to

+ portability concerns, the data can be passed on standard

+ input. Some programs (notably [application]*gpg*)

+ use special file descriptors whose numbers are specified on

+ the command line. Temporary files are an option as well, but

+ they might give digital forensics access to sensitive data

+ (such as passphrases) because it is difficult to safely delete

+ them in all cases.

+ 

+ ==== Handling Child Process Termination

+ 

+ When child processes terminate, the parent process is signalled.

+ A stub of the terminated processes (a

+ *zombie*, shown as

+ `<defunct>` by

+ [application]*ps*) is kept around until the status

+ information is collected (*reaped*) by the

+ parent process. Over the years, several interfaces for this

+ have been invented:

+ 

+ * The parent process calls `wait`,

+ `waitpid`, `waitid`,

+ `wait3` or `wait4`,

+ without specifying a process ID. This will deliver any

+ matching process ID. This approach is typically used from

+ within event loops.

+ 

+ * The parent process calls `waitpid`,

+ `waitid`, or `wait4`,

+ with a specific process ID. Only data for the specific

+ process ID is returned. This is typically used in code

+ which spawns a single subprocess in a synchronous manner.

+ 

+ * The parent process installs a handler for the

+ `SIGCHLD` signal, using

+ `sigaction`, and specifies to the

+ `SA_NOCLDWAIT` flag.

+ This approach could be used by event loops as well.

+ 

+ None of these approaches can be used to wait for child process

+ terminated in a completely thread-safe manner. The parent

+ process might execute an event loop in another thread, which

+ could pick up the termination signal. This means that libraries

+ typically cannot make free use of child processes (for example,

+ to run problematic code with reduced privileges in a separate

+ address space).

+ 

+ At the moment, the parent process should explicitly wait for

+ termination of the child process using

+ `waitpid` or `waitid`,

+ and hope that the status is not collected by an event loop

+ first.

+ 

+ ==== `SUID`pass:attributes[{blank}]/pass:attributes[{blank}]`SGID` processes

+ 

+ Programs can be marked in the file system to indicate to the

+ kernel that a trust transition should happen if the program is

+ run. The `SUID` file permission bit indicates

+ that an executable should run with the effective user ID equal

+ to the owner of the executable file. Similarly, with the

+ `SGID` bit, the effective group ID is set to

+ the group of the executable file.

+ 

+ Linux supports *fscaps*, which can grant

+ additional capabilities to a process in a finer-grained manner.

+ Additional mechanisms can be provided by loadable security

+ modules.

+ 

+ When such a trust transition has happened, the process runs in a

+ potentially hostile environment. Additional care is necessary

+ not to rely on any untrusted information. These concerns also

+ apply to libraries which can be linked into such processes.

+ 

+ [[sect-Defensive_Coding-Tasks-secure_getenv]]

+ ===== Accessing Environment Variables

+ 

+ The following steps are required so that a program does not

+ accidentally pick up untrusted data from environment

+ variables.

+ 

+ * Compile your C/C++ sources with `-D_GNU_SOURCE`.

+ The Autoconf macro `AC_GNU_SOURCE` ensures this.

+ 

+ * Check for the presence of the `secure_getenv`

+ and `__secure_getenv` function. The Autoconf

+ directive `AC_CHECK_FUNCS([__secure_getenv secure_getenv])`

+ performs these checks.

+ 

+ * Arrange for a proper definition of the

+ `secure_getenv` function. See <<ex-Defensive_Coding-Tasks-secure_getenv>>.

+ 

+ * Use `secure_getenv` instead of

+ `getenv` to obtain the value of critical

+ environment variables. `secure_getenv`

+ will pretend the variable has not bee set if the process

+ environment is not trusted.

+ 

+ Critical environment variables are debugging flags,

+ configuration file locations, plug-in and log file locations,

+ and anything else that might be used to bypass security

+ restrictions or cause a privileged process to behave in an

+ unexpected way.

+ 

+ Either the `secure_getenv` function or the

+ `__secure_getenv` is available from GNU libc.

+ 

+ [[ex-Defensive_Coding-Tasks-secure_getenv]]

+ .Obtaining a definition for `secure_getenv`

+ ====

+ 

+ [source,c]

+ ----

+ #include <stdlib.h>

+ 

+ #ifndef HAVE_SECURE_GETENV

+ #  ifdef HAVE__SECURE_GETENV

+ #    define secure_getenv __secure_getenv

+ #  else

+ #    error neither secure_getenv nor __secure_getenv are available

+ #  endif

+ #endif

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-Tasks-Processes-Daemons]]

+ ==== Daemons

+ 

+ Background processes providing system services

+ (*daemons*) need to decouple themselves from

+ the controlling terminal and the parent process environment:

+ 

+ * Fork.

+ 

+ * In the child process, call `setsid`. The

+ parent process can simply exit (using

+ `_exit`, to avoid running clean-up

+ actions twice).

+ 

+ * In the child process, fork again. Processing continues in

+ the child process. Again, the parent process should just

+ exit.

+ 

+ * Replace the descriptors 0, 1, 2 with a descriptor for

+ `/dev/null`. Logging should be

+ redirected to [application]*syslog*.

+ 

+ Older instructions for creating daemon processes recommended a

+ call to `umask(0)`. This is risky because it

+ often leads to world-writable files and directories, resulting

+ in security vulnerabilities such as arbitrary process

+ termination by untrusted local users, or log file truncation.

+ If the *umask* needs setting, a restrictive

+ value such as `027` or `077`

+ is recommended.

+ 

+ Other aspects of the process environment may have to changed as

+ well (environment variables, signal handler disposition).

+ 

+ It is increasingly common that server processes do not run as

+ background processes, but as regular foreground process under a

+ supervising master process (such as

+ [application]*systemd*). Server processes should

+ offer a command line option which disables forking and

+ replacement of the standard output and standard error streams.

+ Such an option is also useful for debugging.

+ 

+ ==== Semantics of Command-line Arguments

+ 

+ After process creation and option processing, it is up to the

+ child process to interpret the arguments. Arguments can be

+ file names, host names, or URLs, and many other things. URLs

+ can refer to the local network, some server on the Internet,

+ or to the local file system. Some applications even accept

+ arbitrary code in arguments (for example,

+ [application]*python* with the

+ [option]`-c` option).

+ 

+ Similar concerns apply to environment variables, the contents

+ of the current directory and its subdirectories.

+ 

+ Consequently, careful analysis is required if it is safe to

+ pass untrusted data to another program.

+ 

+ [[sect-Defensive_Coding-Tasks-Processes-Fork-Parallel]]

+ ==== `fork` as a Primitive for Parallelism

+ 

+ A call to `fork` which is not immediately

+ followed by a call to `execve` (perhaps after

+ rearranging and closing file descriptors) is typically unsafe,

+ especially from a library which does not control the state of

+ the entire process. Such use of `fork`

+ should be replaced with proper child processes or threads.

en-US/Tasks-Processes.xml
file removed
-483
@@ -1,483 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="sect-Defensive_Coding-Tasks-Processes">

-   <title>Processes</title>

- 

-   <section id="sect-Defensive_Coding-Tasks-Processes-Creation">

-     <title>Safe process creation</title>

-     <para>

-       This section describes how to create new child processes in a

-       safe manner.  In addition to the concerns addressed below, there

-       is the possibility of file descriptor leaks, see <xref

-       linkend="sect-Defensive_Coding-Tasks-Descriptors-Child_Processes"/>.

-     </para>

-     <section>

-       <title>Obtaining the program path and the command line

-       template</title>

-       <para>

- 	The name and path to the program being invoked should be

- 	hard-coded or controlled by a static configuration file stored

- 	at a fixed location (at an file system absolute path).  The

- 	same applies to the template for generating the command line.

-       </para>

-       <para>

- 	The configured program name should be an absolute path.  If it

- 	is a relative path, the contents of the <envar>PATH</envar>

- 	must be obtained in a secure manner (see <xref

- 	linkend="sect-Defensive_Coding-Tasks-secure_getenv"/>).

- 	If the <envar>PATH</envar> variable is not set or untrusted,

- 	the safe default <literal>/bin:/usr/bin</literal> must be

- 	used.

-       </para>

-       <para>

- 	If too much flexibility is provided here, it may allow

- 	invocation of arbitrary programs without proper authorization.

-       </para>

-     </section>

- 

-     <section id="sect-Defensive_Coding-Tasks-Processes-execve">

-       <title>Bypassing the shell</title>

-       <para>

- 	Child processes should be created without involving the system

- 	shell.

-       </para>

-       <para>

- 	For C/C++, <function>system</function> should not be used.

- 	The <function>posix_spawn</function> function can be used

- 	instead, or a combination <function>fork</function> and

- 	<function>execve</function>.  (In some cases, it may be

- 	preferable to use <function>vfork</function> or the

- 	Linux-specific <function>clone</function> system call instead

- 	of <function>fork</function>.)

-       </para>

-       <para>

- 	In Python, the <literal>subprocess</literal> module bypasses

- 	the shell by default (when the <literal>shell</literal>

- 	keyword argument is not set to true).

- 	<function>os.system</function> should not be used.

-       </para>

-       <para>

- 	The Java class <type>java.lang.ProcessBuilder</type> can be

- 	used to create subprocesses without interference from the

- 	system shell.

-       </para>

-       <important>

- 	<title>Portability notice</title>

- 	<para>

- 	  On Windows, there is no argument vector, only a single

- 	  argument string.  Each application is responsible for parsing

- 	  this string into an argument vector.  There is considerable

- 	  variance among the quoting style recognized by applications.

- 	  Some of them expand shell wildcards, others do not.  Extensive

- 	  application-specific testing is required to make this secure.

- 	</para>

-       </important>

-       <para>

- 	Note that some common applications (notably

- 	<application>ssh</application>) unconditionally introduce the

- 	use of a shell, even if invoked directly without a shell.  It is

- 	difficult to use these applications in a secure manner.  In this

- 	case, untrusted data should be supplied by other means.  For

- 	example, standard input could be used, instead of the command

- 	line.

-       </para>

-     </section>

- 

-     <section id="sect-Defensive_Coding-Tasks-Processes-environ">

-       <title>Specifying the process environment</title>

-       <para>

- 	Child processes should be created with a minimal set of

- 	environment variables.  This is absolutely essential if there

- 	is a trust transition involved, either when the parent process

- 	was created, or during the creation of the child process.

-       </para>

-       <para>

- 	In C/C++, the environment should be constructed as an array of

- 	strings and passed as the <varname>envp</varname> argument to

- 	<function>posix_spawn</function> or <function>execve</function>.

- 	The functions <function>setenv</function>,

- 	<function>unsetenv</function> and <function>putenv</function>

- 	should not be used.  They are not thread-safe and suffer from

- 	memory leaks.

-       </para>

-       <para>

- 	Python programs need to specify a <literal>dict</literal> for

- 	the the <varname>env</varname> argument of the

- 	<function>subprocess.Popen</function> constructor.

- 	The Java class <literal>java.lang.ProcessBuilder</literal>

- 	provides a <function>environment()</function> method,

- 	which returns a map that can be manipulated.

-       </para>

-       <para>

- 	The following list provides guidelines for selecting the set

- 	of environment variables passed to the child process.

-       </para>

-       <itemizedlist>

- 	<listitem>

- 	  <para>

- 	    <envar>PATH</envar> should be initialized to

- 	    <literal>/bin:/usr/bin</literal>.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    <envar>USER</envar> and <envar>HOME</envar> can be inhereted

- 	    from the parent process environment, or they can be

- 	    initialized from the <literal>pwent</literal> structure

- 	    for the user. <!-- ??? refer to dropping privileges -->

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>The <envar>DISPLAY</envar> and <envar>XAUTHORITY</envar>

- 	  variables should be passed to the subprocess if it is an X

- 	  program.  Note that this will typically not work across trust

- 	  boundaries because <envar>XAUTHORITY</envar> refers to a file

- 	  with <literal>0600</literal> permissions.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The location-related environment variables

- 	    <envar>LANG</envar>, <envar>LANGUAGE</envar>,

- 	    <envar>LC_ADDRESS</envar>, <envar>LC_ALL</envar>,

- 	    <envar>LC_COLLATE</envar>, <envar>LC_CTYPE</envar>,

- 	    <envar>LC_IDENTIFICATION</envar>,

- 	    <envar>LC_MEASUREMENT</envar>, <envar>LC_MESSAGES</envar>,

- 	    <envar>LC_MONETARY</envar>, <envar>LC_NAME</envar>,

- 	    <envar>LC_NUMERIC</envar>, <envar>LC_PAPER</envar>,

- 	    <envar>LC_TELEPHONE</envar> and <envar>LC_TIME</envar>

- 	    can be passed to the subprocess if present.

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    The called process may need application-specific

- 	    environment variables, for example for passing passwords.

- 	    (See <xref

- 	    linkend="sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility"/>.)

- 	  </para>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    All other environment variables should be dropped.  Names

- 	    for new environment variables should not be accepted from

- 	    untrusted sources.

- 	  </para>

- 	</listitem>

-       </itemizedlist>

-     </section>

- 

-     <section>

-       <title>Robust argument list processing</title>

-       <para>

- 	When invoking a program, it is sometimes necessary to include

- 	data from untrusted sources.  Such data should be checked

- 	against embedded <literal>NUL</literal> characters because the

- 	system APIs will silently truncate argument strings at the first

- 	<literal>NUL</literal> character.

-       </para>

-       <para>

- 	The following recommendations assume that the program being

- 	invoked uses GNU-style option processing using

- 	<function>getopt_long</function>.  This convention is widely

- 	used, but it is just that, and individual programs might

- 	interpret a command line in a different way.

-       </para>

-       <para>

- 	If the untrusted data has to go into an option, use the

- 	<literal>--option-name=VALUE</literal> syntax, placing the

- 	option and its value into the same command line argument.

- 	This avoids any potential confusion if the data starts with

- 	<literal>-</literal>.

-       </para>

-       <para>

- 	For positional arguments, terminate the option list with a

- 	single <option>--</option> marker after the last option, and

- 	include the data at the right position.  The

- 	<option>--</option> marker terminates option processing, and

- 	the data will not be treated as an option even if it starts

- 	with a dash.

-       </para>

-     </section>

- 

-     <section id="sect-Defensive_Coding-Tasks-Processes-Command_Line_Visibility">

-       <title>Passing secrets to subprocesses</title>

-       <para>

- 	The command line (the name of the program and its argument) of

- 	a running process is traditionally available to all local

- 	users.  The called program can overwrite this information, but

- 	only after it has run for a bit of time, during which the

- 	information may have been read by other processes.  However,

- 	on Linux, the process environment is restricted to the user

- 	who runs the process.  Therefore, if you need a convenient way

- 	to pass a password to a child process, use an environment

- 	variable, and not a command line argument.  (See <xref

- 	linkend="sect-Defensive_Coding-Tasks-Processes-environ"/>.)

-       </para>

-       <important>

- 	<title>Portability notice</title>

- 	<para>

- 	  On some UNIX-like systems (notably Solaris), environment

- 	  variables can be read by any system user, just like command

- 	  lines.

- 	</para>

-       </important>

-       <para>

- 	If the environment-based approach cannot be used due to

- 	portability concerns, the data can be passed on standard

- 	input.  Some programs (notably <application>gpg</application>)

- 	use special file descriptors whose numbers are specified on

- 	the command line.  Temporary files are an option as well, but

- 	they might give digital forensics access to sensitive data

- 	(such as passphrases) because it is difficult to safely delete

- 	them in all cases.

-       </para>

-     </section>

-   </section>

- 

-   <section>

-     <title>Handling child process termination</title>

-     <para>

-       When child processes terminate, the parent process is signalled.

-       A stub of the terminated processes (a

-       <emphasis>zombie</emphasis>, shown as

-       <literal>&lt;defunct&gt;</literal> by

-       <application>ps</application>) is kept around until the status

-       information is collected (<emphasis>reaped</emphasis>) by the

-       parent process.  Over the years, several interfaces for this

-       have been invented:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  The parent process calls <function>wait</function>,

- 	  <function>waitpid</function>, <function>waitid</function>,

- 	  <function>wait3</function> or <function>wait4</function>,

- 	  without specifying a process ID.  This will deliver any

- 	  matching process ID.  This approach is typically used from

- 	  within event loops.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The parent process calls <function>waitpid</function>,

- 	  <function>waitid</function>, or <function>wait4</function>,

- 	  with a specific process ID.  Only data for the specific

- 	  process ID is returned.  This is typically used in code

- 	  which spawns a single subprocess in a synchronous manner.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  The parent process installs a handler for the

- 	  <literal>SIGCHLD</literal> signal, using

- 	  <function>sigaction</function>, and specifies to the

- 	  <literal>SA_NOCLDWAIT</literal> flag.

- 	  This approach could be used by event loops as well.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       None of these approaches can be used to wait for child process

-       terminated in a completely thread-safe manner.  The parent

-       process might execute an event loop in another thread, which

-       could pick up the termination signal.  This means that libraries

-       typically cannot make free use of child processes (for example,

-       to run problematic code with reduced privileges in a separate

-       address space).

-     </para>

-     <para>

-       At the moment, the parent process should explicitly wait for

-       termination of the child process using

-       <function>waitpid</function> or <function>waitid</function>,

-       and hope that the status is not collected by an event loop

-       first.

-     </para>

-   </section>

- 

-   <section>

-     <title><literal>SUID</literal>/<literal>SGID</literal>

-     processes</title>

-     <!-- ??? need to document real vs effective UID -->

-     <para>

-       Programs can be marked in the file system to indicate to the

-       kernel that a trust transition should happen if the program is

-       run.  The <literal>SUID</literal> file permission bit indicates

-       that an executable should run with the effective user ID equal

-       to the owner of the executable file.  Similarly, with the

-       <literal>SGID</literal> bit, the effective group ID is set to

-       the group of the executable file.

-     </para>

-     <para>

-       Linux supports <emphasis>fscaps</emphasis>, which can grant

-       additional capabilities to a process in a finer-grained manner.

-       Additional mechanisms can be provided by loadable security

-       modules.

-     </para>

-     <para>

-       When such a trust transition has happened, the process runs in a

-       potentially hostile environment.  Additional care is necessary

-       not to rely on any untrusted information.  These concerns also

-       apply to libraries which can be linked into such processes.

-     </para>

- 

-     <section id="sect-Defensive_Coding-Tasks-secure_getenv">

-       <title>Accessing environment variables</title>

-       <para>

- 	The following steps are required so that a program does not

- 	accidentally pick up untrusted data from environment

- 	variables.

-       </para>

-       <itemizedlist>

- 	<listitem><para>

- 	  Compile your C/C++ sources with <literal>-D_GNU_SOURCE</literal>.

- 	  The Autoconf macro <literal>AC_GNU_SOURCE</literal> ensures this.

- 	</para></listitem>

- 	<listitem><para>

- 	  Check for the presence of the <function>secure_getenv</function>

- 	  and <function>__secure_getenv</function> function.  The Autoconf

- 	  directive <literal>AC_CHECK_FUNCS([__secure_getenv secure_getenv])</literal>

- 	  performs these checks.

- 	</para></listitem>

- 	<listitem><para>

- 	  Arrange for a proper definition of the

- 	  <function>secure_getenv</function> function.  See <xref

- 	  linkend="ex-Defensive_Coding-Tasks-secure_getenv"/>.

- 	</para></listitem>

- 	<listitem><para>

- 	  Use <function>secure_getenv</function> instead of

- 	  <function>getenv</function> to obtain the value of critical

- 	  environment variables.  <function>secure_getenv</function>

- 	  will pretend the variable has not bee set if the process

- 	  environment is not trusted.

- 	</para></listitem>

-       </itemizedlist>

-       <para>

- 	Critical environment variables are debugging flags,

- 	configuration file locations, plug-in and log file locations,

- 	and anything else that might be used to bypass security

- 	restrictions or cause a privileged process to behave in an

- 	unexpected way.

-       </para>

-       <para>

- 	Either the <function>secure_getenv</function> function or the

- 	<function>__secure_getenv</function> is available from GNU libc.

-       </para>

-       <example id="ex-Defensive_Coding-Tasks-secure_getenv">

- 	<title>Obtaining a definition for <function>secure_getenv</function></title>

- 	<programlisting language="C">

- <![CDATA[

- #include <stdlib.h>

- 

- #ifndef HAVE_SECURE_GETENV

- #  ifdef HAVE__SECURE_GETENV

- #    define secure_getenv __secure_getenv

- #  else

- #    error neither secure_getenv nor __secure_getenv are available

- #  endif

- #endif

- ]]>

- 	</programlisting>

-       </example>

-     </section>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Tasks-Processes-Daemons">

-     <title>Daemons</title>

-     <para>

-       Background processes providing system services

-       (<emphasis>daemons</emphasis>) need to decouple themselves from

-       the controlling terminal and the parent process environment:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>Fork.</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  In the child process, call <function>setsid</function>.  The

- 	  parent process can simply exit (using

- 	  <function>_exit</function>, to avoid running clean-up

- 	  actions twice).

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  In the child process, fork again.  Processing continues in

- 	  the child process.  Again, the parent process should just

- 	  exit.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Replace the descriptors 0, 1, 2 with a descriptor for

- 	  <filename>/dev/null</filename>.  Logging should be

- 	  redirected to <application>syslog</application>.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       Older instructions for creating daemon processes recommended a

-       call to <literal>umask(0)</literal>.  This is risky because it

-       often leads to world-writable files and directories, resulting

-       in security vulnerabilities such as arbitrary process

-       termination by untrusted local users, or log file truncation.

-       If the <emphasis>umask</emphasis> needs setting, a restrictive

-       value such as <literal>027</literal> or <literal>077</literal>

-       is recommended.

-     </para>

-     <para>

-       Other aspects of the process environment may have to changed as

-       well (environment variables, signal handler disposition).

-     </para>

-     <para>

-       It is increasingly common that server processes do not run as

-       background processes, but as regular foreground process under a

-       supervising master process (such as

-       <application>systemd</application>).  Server processes should

-       offer a command line option which disables forking and

-       replacement of the standard output and standard error streams.

-       Such an option is also useful for debugging.

-     </para>

-   </section>

- 

-   <section>

-     <title>Semantics of command line arguments</title>

-     <!-- ??? This applies in two ways, safely calling an other process

-          and support for being called safely.  Also need to address

-          untrusted current directory on USB sticks.  -->

-     <para>

-       After process creation and option processing, it is up to the

-       child process to interpret the arguments. Arguments can be

-       file names, host names, or URLs, and many other things.  URLs

-       can refer to the local network, some server on the Internet,

-       or to the local file system.  Some applications even accept

-       arbitrary code in arguments (for example,

-       <application>python</application> with the

-       <option>-c</option> option).

-     </para>

-     <para>

-       Similar concerns apply to environment variables, the contents

-       of the current directory and its subdirectories.

-       <!-- ??? refer to section on temporary directories -->

-     </para>

-     <para>

-       Consequently, careful analysis is required if it is safe to

-       pass untrusted data to another program.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Tasks-Processes-Fork-Parallel">

-     <title><function>fork</function> as a primitive for parallelism</title>

-     <para>

-       A call to <function>fork</function> which is not immediately

-       followed by a call to <function>execve</function> (perhaps after

-       rearranging and closing file descriptors) is typically unsafe,

-       especially from a library which does not control the state of

-       the entire process.  Such use of <function>fork</function>

-       should be replaced with proper child processes or threads.

-     </para>

-   </section>

- 

- </chapter>

en-US/Tasks-Serialization.adoc
file added
+571
@@ -0,0 +1,571 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Tasks-Serialization]]

+ === Serialization and Deserialization

+ 

+ Protocol decoders and file format parsers are often the

+ most-exposed part of an application because they are exposed with

+ little or no user interaction and before any authentication and

+ security checks are made. They are also difficult to write

+ robustly in languages which are not memory-safe.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-Decoders]]

+ ==== Recommendations for Manually-written Decoders

+ 

+ For C and C++, the advice in <<sect-Defensive_Coding-C-Pointers>> applies. In

+ addition, avoid non-character pointers directly into input

+ buffers. Pointer misalignment causes crashes on some

+ architectures.

+ 

+ When reading variable-sized objects, do not allocate large

+ amounts of data solely based on the value of a size field. If

+ possible, grow the data structure as more data is read from the

+ source, and stop when no data is available. This helps to avoid

+ denial-of-service attacks where little amounts of input data

+ results in enormous memory allocations during decoding.

+ Alternatively, you can impose reasonable bounds on memory

+ allocations, but some protocols do not permit this.

+ 

+ ==== Protocol Design

+ 

+ Binary formats with explicit length fields are more difficult to

+ parse robustly than those where the length of dynamically-sized

+ elements is derived from sentinel values. A protocol which does

+ not use length fields and can be written in printable ASCII

+ characters simplifies testing and debugging. However, binary

+ protocols with length fields may be more efficient to parse.

+ 

+ In new datagram-oriented protocols, unique numbers such as

+ sequence numbers or identifiers for fragment reassembly (see

+ <<sect-Defensive_Coding-Tasks-Serialization-Fragmentation>>)

+ should be at least 64 bits large, and really should not be

+ smaller than 32 bits in size. Protocols should not permit

+ fragments with overlapping contents.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-Fragmentation]]

+ ==== Fragmentation

+ 

+ Some serialization formats use frames or protocol data units

+ (PDUs) on lower levels which are smaller than the PDUs on higher

+ levels. With such an architecture, higher-level PDUs may have

+ to be *fragmented* into smaller frames during

+ serialization, and frames may need

+ *reassembly* into large PDUs during

+ deserialization.

+ 

+ Serialization formats may use conceptually similar structures

+ for completely different purposes, for example storing multiple

+ layers and color channels in a single image file.

+ 

+ When fragmenting PDUs, establish a reasonable lower bound for

+ the size of individual fragments (as large as possible—limits as

+ low as one or even zero can add substantial overhead). Avoid

+ fragmentation if at all possible, and try to obtain the maximum

+ acceptable fragment length from a trusted data source.

+ 

+ When implementing reassembly, consider the following aspects.

+ 

+ * Avoid allocating significant amount of resources without

+ proper authentication. Allocate memory for the unfragmented

+ PDU as more and more and fragments are encountered, and not

+ based on the initially advertised unfragmented PDU size,

+ unless there is a sufficiently low limit on the unfragmented

+ PDU size, so that over-allocation cannot lead to performance

+ problems.

+ 

+ * Reassembly queues on top of datagram-oriented transports

+ should be bounded, both in the combined size of the arrived

+ partial PDUs waiting for reassembly, and the total number of

+ partially reassembled fragments. The latter limit helps to

+ reduce the risk of accidental reassembly of unrelated

+ fragments, as it can happen with small fragment IDs (see

+ <<sect-Defensive_Coding-Tasks-Serialization-Fragmentation-ID>>).

+ It also guards to some extent against deliberate injection of fragments,

+ by guessing fragment IDs.

+ 

+ * Carefully keep track of which bytes in the unfragmented PDU

+ have been covered by fragments so far. If message

+ reordering is a concern, the most straightforward data

+ structure for this is an array of bits, with one bit for

+ every byte (or other atomic unit) in the unfragmented PDU.

+ Complete reassembly can be determined by increasing a

+ counter of set bits in the bit array as the bit array is

+ updated, taking overlapping fragments into consideration.

+ 

+ * Reject overlapping fragments (that is, multiple fragments

+ which provide data at the same offset of the PDU being

+ fragmented), unless the protocol explicitly requires

+ accepting overlapping fragments. The bit array used for

+ tracking already arrived bytes can be used for this purpose.

+ 

+ * Check for conflicting values of unfragmented PDU lengths (if

+ this length information is part of every fragment) and

+ reject fragments which are inconsistent.

+ 

+ * Validate fragment lengths and offsets of individual

+ fragments against the unfragmented PDU length (if they are

+ present). Check that the last byte in the fragment does not

+ lie after the end of the unfragmented PDU. Avoid integer

+ overflows in these computations (see <<sect-Defensive_Coding-C-Arithmetic>>).

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-Fragmentation-ID]]

+ ===== Fragment IDs

+ 

+ If the underlying transport is datagram-oriented (so that PDUs

+ can be reordered, duplicated or be lost, like with UDP),

+ fragment reassembly needs to take into account endpoint

+ addresses of the communication channel, and there has to be

+ some sort of fragment ID which identifies the individual

+ fragments as part of a larger PDU. In addition, the

+ fragmentation protocol will typically involve fragment offsets

+ and fragment lengths, as mentioned above.

+ 

+ If the transport may be subject to blind PDU injection (again,

+ like UDP), the fragment ID must be generated randomly. If the

+ fragment ID is 64 bit or larger (strongly recommended), it can

+ be generated in a completely random fashion for most traffic

+ volumes. If it is less than 64 bits large (so that accidental

+ collisions can happen if a lot of PDUs are transmitted), the

+ fragment ID should be incremented sequentially from a starting

+ value. The starting value should be derived using a HMAC-like

+ construction from the endpoint addresses, using a long-lived

+ random key. This construction ensures that despite the

+ limited range of the ID, accidental collisions are as unlikely

+ as possible. (This will not work reliable with really short

+ fragment IDs, such as the 16 bit IDs used by the Internet

+ Protocol.)

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-Library]]

+ ==== Library Support for Deserialization

+ 

+ For some languages, generic libraries are available which allow

+ to serialize and deserialize user-defined objects. The

+ deserialization part comes in one of two flavors, depending on

+ the library. The first kind uses type information in the data

+ stream to control which objects are instantiated. The second

+ kind uses type definitions supplied by the programmer. The

+ first one allows arbitrary object instantiation, the second one

+ generally does not.

+ 

+ The following serialization frameworks are in the first category,

+ are known to be unsafe, and must not be used for untrusted data:

+ 

+ * Python's [package]*pickle* and [package]*cPickle*

+ modules, and wrappers such as [package]*shelve*

+ 

+ * Perl's [package]*Storable* package

+ 

+ * Java serialization (`java.io.ObjectInputStream`),

+ even if encoded in other formats (as with

+ `java.beans.XMLDecoder`)

+ 

+ * PHP serialization (`unserialize`)

+ 

+ * Most implementations of YAML

+ 

+ When using a type-directed deserialization format where the

+ types of the deserialized objects are specified by the

+ programmer, make sure that the objects which can be instantiated

+ cannot perform any destructive actions in their destructors,

+ even when the data members have been manipulated.

+ 

+ In general, JSON decoders do not suffer from this problem. But

+ you must not use the `eval` function to parse

+ JSON objects in Javascript; even with the regular expression

+ filter from RFC 4627, there are still information leaks

+ remaining. JSON-based formats can still turn out risky if they

+ serve as an encoding form for any if the serialization

+ frameworks listed above.

+ 

+ For serialization in C and C++ projects, the Protocol Buffers serialization

+ ([package]*protobuf*) provides type safe automated serialization

+ by relying on code generation. It is positioned as similar, but simpler and

+ more efficient to XML serialization.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML]]

+ ==== XML Serialization

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-External]]

+ ===== External References

+ 

+ XML documents can contain external references. They can occur

+ in various places.

+ 

+ * In the DTD declaration in the header of an XML document:

+ +

+ [source,xml]

+ ----

+ 

+ <!DOCTYPE html PUBLIC

+   "-//W3C//DTD XHTML 1.0 Transitional//EN"

+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

+ 	    

+ ----

+ 

+ * In a namespace declaration:

+ +

+ [source,xml]

+ ----

+ 

+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

+ 	    

+ ----

+ 

+ * In an entity defintion:

+ +

+ [source,xml]

+ ----

+ 

+ <!ENTITY sys SYSTEM "http://www.example.com/ent.adoc[]>

+ <!ENTITY pub PUBLIC "-//Example//Public Entity//EN"

+   "http://www.example.com/pub-ent.adoc[]>

+ 	    

+ ----

+ 

+ * In a notation:

+ +

+ [source,xml]

+ ----

+ 

+ <!NOTATION not SYSTEM "../not.adoc[]>

+ 	    

+ ----

+ 

+ Originally, these external references were intended as unique

+ identifiers, but by many XML implementations, they are used

+ for locating the data for the referenced element. This causes

+ unwanted network traffic, and may disclose file system

+ contents or otherwise unreachable network resources, so this

+ functionality should be disabled.

+ 

+ Depending on the XML library, external referenced might be

+ processed not just when parsing XML, but also when generating

+ it.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-Entities]]

+ ===== Entity Expansion

+ 

+ When external DTD processing is disabled, an internal DTD

+ subset can still contain entity definitions. Entity

+ declarations can reference other entities. Some XML libraries

+ expand entities automatically, and this processing cannot be

+ switched off in some places (such as attribute values or

+ content models). Without limits on the entity nesting level,

+ this expansion results in data which can grow exponentially in

+ length with size of the input. (If there is a limit on the

+ nesting level, the growth is still polynomial, unless further

+ limits are imposed.)

+ 

+ Consequently, the processing internal DTD subsets should be

+ disabled if possible, and only trusted DTDs should be

+ processed. If a particular XML application does not permit

+ such restrictions, then application-specific limits are called

+ for.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-XInclude]]

+ ===== XInclude Processing

+ 

+ XInclude processing can reference file and network resources

+ and include them into the document, much like external entity

+ references. When parsing untrusted XML documents, XInclude

+ processing should be turned off.

+ 

+ XInclude processing is also fairly complex and may pull in

+ support for the XPointer and XPath specifications,

+ considerably increasing the amount of code required for XML

+ processing.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-Validation]]

+ ===== Algorithmic Complexity of XML Validation

+ 

+ DTD-based XML validation uses regular expressions for content

+ models. The XML specification requires that content models

+ are deterministic, which means that efficient validation is

+ possible. However, some implementations do not enforce

+ determinism, and require exponential (or just polynomial)

+ amount of space or time for validating some DTD/document

+ combinations.

+ 

+ XML schemas and RELAX NG (via the `xsd:`

+ prefix) directly support textual regular expressions which are

+ not required to be deterministic.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-Expat]]

+ ===== Using Expat for XML parsing

+ 

+ By default, Expat does not try to resolve external IDs, so no

+ steps are required to block them. However, internal entity

+ declarations are processed. Installing a callback which stops

+ parsing as soon as such entities are encountered disables

+ them, see <<ex-Defensive_Coding-Tasks-Serialization-XML-Expat-EntityDeclHandler>>.

+ Expat does not perform any validation, so there are no

+ problems related to that.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-Expat-EntityDeclHandler]]

+ .Disabling XML entity processing with Expat

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-Expat-EntityDeclHandler.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ This handler must be installed when the

+ `XML_Parser` object is created (<<ex-Defensive_Coding-Tasks-Serialization-XML-Expat-Create>>).

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-Expat-Create]]

+ .Creating an Expat XML parser

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-Expat-Create.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ It is also possible to reject internal DTD subsets altogether,

+ using a suitable

+ `XML_StartDoctypeDeclHandler` handler

+ installed with `XML_SetDoctypeDeclHandler`.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-Qt]]

+ ===== Using Qt for XML Parsing

+ 

+ The XML component of Qt, QtXml, does not resolve external IDs

+ by default, so it is not required to prevent such resolution.

+ Internal entities are processed, though. To change that, a

+ custom `QXmlDeclHandler` and

+ `QXmlSimpleReader` subclasses are needed. It

+ is not possible to use the

+ `QDomDocument::setContent(const QByteArray

+ &)` convenience methods.

+ 

+ <<ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityHandler>>

+ shows an entity handler which always returns errors, causing

+ parsing to stop when encountering entity declarations.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityHandler]]

+ .A QtXml entity handler which blocks entity processing

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-Qt-NoEntityHandler.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ This handler is used in the custom

+ `QXmlReader` subclass in <<ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityReader>>.

+ Some parts of QtXml will call the

+ `setDeclHandler(QXmlDeclHandler *)` method.

+ Consequently, we prevent overriding our custom handler by

+ providing a definition of this method which does nothing. In

+ the constructor, we activate namespace processing; this part

+ may need adjusting.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityReader]]

+ .A QtXml XML reader which blocks entity processing

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-Qt-NoEntityReader.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ Our `NoEntityReader` class can be used with

+ one of the overloaded

+ `QDomDocument::setContent` methods.

+ <<ex-Defensive_Coding-Tasks-Serialization-XML-Qt-QDomDocument>>

+ shows how the `buffer` object (of type

+ `QByteArray`) is wrapped as a

+ `QXmlInputSource`. After calling the

+ `setContent` method, you should check the

+ return value and report any error.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-Qt-QDomDocument]]

+ .Parsing an XML document with QDomDocument, without entity expansion

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-Qt-QDomDocument.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse]]

+ ===== Using OpenJDK for XML Parsing and Validation

+ 

+ OpenJDK contains facilities for DOM-based, SAX-based, and

+ StAX-based document parsing. Documents can be validated

+ against DTDs or XML schemas.

+ 

+ The approach taken to deal with entity expansion differs from

+ the general recommendation in <<sect-Defensive_Coding-Tasks-Serialization-XML-Entities>>.

+ We enable the the feature flag

+ `javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING`,

+ which enforces heuristic restrictions on the number of entity

+ expansions. Note that this flag alone does not prevent

+ resolution of external references (system IDs or public IDs),

+ so it is slightly misnamed.

+ 

+ In the following sections, we use helper classes to prevent

+ external ID resolution.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-NoEntityResolver]]

+ .Helper class to prevent DTD external entity resolution in OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-OpenJDK-NoEntityResolver.adoc[]

+ 		    

+ ----

+ 

+ ====

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-NoResourceResolver]]

+ .Helper class to prevent schema resolution in	OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-OpenJDK-NoResourceResolver.adoc[]	    

+ ----

+ 

+ ====

+ 

+ <<ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-Imports>>

+ shows the imports used by the examples.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-Imports]]

+ .Java imports for OpenJDK XML parsing

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-OpenJDK-Imports.adoc[]	    

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-DOM]]

+ ====== DOM-based XML parsing and DTD validation in OpenJDK

+ 

+ This approach produces a

+ `org.w3c.dom.Document` object from an input

+ stream. <<ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-DOM>>

+ use the data from the `java.io.InputStream`

+ instance in the `inputStream` variable.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-DOM]]

+ .DOM-based XML parsing in OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-OpenJDK_Parse-DOM.adoc[]	      

+ ----

+ 

+ ====

+ 

+ External entity references are prohibited using the

+ `NoEntityResolver` class in

+ <<ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-NoEntityResolver>>.

+ Because external DTD references are prohibited, DTD validation

+ (if enabled) will only happen against the internal DTD subset

+ embedded in the XML document.

+ 

+ To validate the document against an external DTD, use a

+ `javax.xml.transform.Transformer` class to

+ add the DTD reference to the document, and an entity

+ resolver which whitelists this external reference.

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-SAX]]

+ ====== XML Schema Validation in OpenJDK

+ 

+ <<ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_SAX>>

+ shows how to validate a document against an XML Schema,

+ using a SAX-based approach. The XML data is read from an

+ `java.io.InputStream` in the

+ `inputStream` variable.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_SAX]]

+ .SAX-based validation against an XML schema in OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_SAX.adoc[]	      

+ ----

+ 

+ ====

+ 

+ The `NoResourceResolver` class is defined

+ in <<ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-NoResourceResolver>>.

+ 

+ If you need to validate a document against an XML schema,

+ use the code in <<ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-DOM>>

+ to create the document, but do not enable validation at this

+ point. Then use

+ <<ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_DOM>>

+ to perform the schema-based validation on the

+ `org.w3c.dom.Document` instance

+ `document`.

+ 

+ [[ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_DOM]]

+ .Validation of a DOM document against an XML schema in OpenJDK

+ ====

+ 

+ [source,java]

+ ----

+ include::snippets/Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_DOM.adoc[]

+ ----

+ 

+ ====

+ 

+ [[sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-Other]]

+ ====== Other XML Parsers in OpenJDK

+ 

+ OpenJDK contains additional XML parsing and processing

+ facilities. Some of them are insecure.

+ 

+ The class `java.beans.XMLDecoder` acts as a

+ bridge between the Java object serialization format and XML.

+ It is close to impossible to securely deserialize Java

+ objects in this format from untrusted inputs, so its use is

+ not recommended, as with the Java object serialization

+ format itself. See <<sect-Defensive_Coding-Tasks-Serialization-Library>>.

+ 

+ ==== Protocol Encoders

+ 

+ For protocol encoders, you should write bytes to a buffer which

+ grows as needed, using an exponential sizing policy. Explicit

+ lengths can be patched in later, once they are known.

+ Allocating the required number of bytes upfront typically

+ requires separate code to compute the final size, which must be

+ kept in sync with the actual encoding step, or vulnerabilities

+ may result. In multi-threaded code, parts of the object being

+ deserialized might change, so that the computed size is out of

+ date.

+ 

+ You should avoid copying data directly from a received packet

+ during encoding, disregarding the format. Propagating malformed

+ data could enable attacks on other recipients of that data.

+ 

+ When using C or C++ and copying whole data structures directly

+ into the output, make sure that you do not leak information in

+ padding bytes between fields or at the end of the

+ `struct`.

en-US/Tasks-Serialization.xml
file removed
-604
@@ -1,604 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Tasks-Serialization">

-   <title>Serialization and Deserialization</title>

-   <para>

-     Protocol decoders and file format parsers are often the

-     most-exposed part of an application because they are exposed with

-     little or no user interaction and before any authentication and

-     security checks are made.  They are also difficult to write

-     robustly in languages which are not memory-safe.

-   </para>

- 

-   <section id="sect-Defensive_Coding-Tasks-Serialization-Decoders">

-     <title>Recommendations for manually written decoders</title>

-     <para>

-       For C and C++, the advice in <xref

-       linkend="sect-Defensive_Coding-C-Pointers"/> applies.  In

-       addition, avoid non-character pointers directly into input

-       buffers.  Pointer misalignment causes crashes on some

-       architectures.

-     </para>

-     <para>

-       When reading variable-sized objects, do not allocate large

-       amounts of data solely based on the value of a size field.  If

-       possible, grow the data structure as more data is read from the

-       source, and stop when no data is available.  This helps to avoid

-       denial-of-service attacks where little amounts of input data

-       results in enormous memory allocations during decoding.

-       Alternatively, you can impose reasonable bounds on memory

-       allocations, but some protocols do not permit this.

-     </para>

-   </section>

- 

-   <section>

-     <title>Protocol design</title>

-     <para>

-       Binary formats with explicit length fields are more difficult to

-       parse robustly than those where the length of dynamically-sized

-       elements is derived from sentinel values.  A protocol which does

-       not use length fields and can be written in printable ASCII

-       characters simplifies testing and debugging.  However, binary

-       protocols with length fields may be more efficient to parse.

-     </para>

-     <para>

-       In new datagram-oriented protocols, unique numbers such as

-       sequence numbers or identifiers for fragment reassembly (see

-       <xref

-       linkend="sect-Defensive_Coding-Tasks-Serialization-Fragmentation"/>)

-       should be at least 64 bits large, and really should not be

-       smaller than 32 bits in size.  Protocols should not permit

-       fragments with overlapping contents.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Tasks-Serialization-Fragmentation">

-     <title>Fragmentation</title>

-     <para>

-       Some serialization formats use frames or protocol data units

-       (PDUs) on lower levels which are smaller than the PDUs on higher

-       levels.  With such an architecture, higher-level PDUs may have

-       to be <emphasis>fragmented</emphasis> into smaller frames during

-       serialization, and frames may need

-       <emphasis>reassembly</emphasis> into large PDUs during

-       deserialization.

-     </para>

-     <para>

-       Serialization formats may use conceptually similar structures

-       for completely different purposes, for example storing multiple

-       layers and color channels in a single image file.

-     </para>

-     <para>

-       When fragmenting PDUs, establish a reasonable lower bound for

-       the size of individual fragments (as large as possible—limits as

-       low as one or even zero can add substantial overhead).  Avoid

-       fragmentation if at all possible, and try to obtain the maximum

-       acceptable fragment length from a trusted data source.

-     </para>

-     <para>

-       When implementing reassembly, consider the following aspects.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Avoid allocating significant amount of resources without

- 	  proper authentication.  Allocate memory for the unfragmented

- 	  PDU as more and more and fragments are encountered, and not

- 	  based on the initially advertised unfragmented PDU size,

- 	  unless there is a sufficiently low limit on the unfragmented

- 	  PDU size, so that over-allocation cannot lead to performance

- 	  problems.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Reassembly queues on top of datagram-oriented transports

- 	  should be bounded, both in the combined size of the arrived

- 	  partial PDUs waiting for reassembly, and the total number of

- 	  partially reassembled fragments.  The latter limit helps to

- 	  reduce the risk of accidental reassembly of unrelated

- 	  fragments, as it can happen with small fragment IDs (see

- 	  <xref linkend="sect-Defensive_Coding-Tasks-Serialization-Fragmentation-ID"/>).

- 	  It also guards to some extent against deliberate injection of fragments,

- 	  by guessing fragment IDs.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Carefully keep track of which bytes in the unfragmented PDU

- 	  have been covered by fragments so far.  If message

- 	  reordering is a concern, the most straightforward data

- 	  structure for this is an array of bits, with one bit for

- 	  every byte (or other atomic unit) in the unfragmented PDU.

- 	  Complete reassembly can be determined by increasing a

- 	  counter of set bits in the bit array as the bit array is

- 	  updated, taking overlapping fragments into consideration.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Reject overlapping fragments (that is, multiple fragments

- 	  which provide data at the same offset of the PDU being

- 	  fragmented), unless the protocol explicitly requires

- 	  accepting overlapping fragments.  The bit array used for

- 	  tracking already arrived bytes can be used for this purpose.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Check for conflicting values of unfragmented PDU lengths (if

- 	  this length information is part of every fragment) and

- 	  reject fragments which are inconsistent.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Validate fragment lengths and offsets of individual

- 	  fragments against the unfragmented PDU length (if they are

- 	  present).  Check that the last byte in the fragment does not

- 	  lie after the end of the unfragmented PDU.  Avoid integer

- 	  overflows in these computations (see <xref

- 	  linkend="sect-Defensive_Coding-C-Arithmetic"/>).

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <section id="sect-Defensive_Coding-Tasks-Serialization-Fragmentation-ID">

-       <title>Fragment IDs</title>

-       <para>

- 	If the underlying transport is datagram-oriented (so that PDUs

- 	can be reordered, duplicated or be lost, like with UDP),

- 	fragment reassembly needs to take into account endpoint

- 	addresses of the communication channel, and there has to be

- 	some sort of fragment ID which identifies the individual

- 	fragments as part of a larger PDU.  In addition, the

- 	fragmentation protocol will typically involve fragment offsets

- 	and fragment lengths, as mentioned above.

-       </para>

-       <para>

- 	If the transport may be subject to blind PDU injection (again,

- 	like UDP), the fragment ID must be generated randomly.  If the

- 	fragment ID is 64 bit or larger (strongly recommended), it can

- 	be generated in a completely random fashion for most traffic

- 	volumes.  If it is less than 64 bits large (so that accidental

- 	collisions can happen if a lot of PDUs are transmitted), the

- 	fragment ID should be incremented sequentially from a starting

- 	value.  The starting value should be derived using a HMAC-like

- 	construction from the endpoint addresses, using a long-lived

- 	random key.  This construction ensures that despite the

- 	limited range of the ID, accidental collisions are as unlikely

- 	as possible.  (This will not work reliable with really short

- 	fragment IDs, such as the 16 bit IDs used by the Internet

- 	Protocol.)

-       </para>

-     </section>

-   </section>

- 

-   <section>

-     <title id="sect-Defensive_Coding-Tasks-Serialization-Library">Library

-     support for deserialization</title>

-     <para>

-       For some languages, generic libraries are available which allow

-       to serialize and deserialize user-defined objects.  The

-       deserialization part comes in one of two flavors, depending on

-       the library.  The first kind uses type information in the data

-       stream to control which objects are instantiated.  The second

-       kind uses type definitions supplied by the programmer.  The

-       first one allows arbitrary object instantiation, the second one

-       generally does not.

-     </para>

-     <para>

-       The following serialization frameworks are in the first category,

-       are known to be unsafe, and must not be used for untrusted data:

-     </para>

-     <itemizedlist>

-       <listitem><para>

- 	Python's <package>pickle</package> and <package>cPickle</package>

- 	modules, and wrappers such as <package>shelve</package>

-       </para></listitem>

-       <listitem><para>

- 	Perl's <package>Storable</package> package

-       </para></listitem>

-       <listitem><para>

- 	Java serialization (<type>java.io.ObjectInputStream</type>),

- 	even if encoded in other formats (as with

- 	<type>java.beans.XMLDecoder</type>)

-       </para></listitem>

-       <listitem><para>

- 	PHP serialization (<function>unserialize</function>)

-       </para></listitem>

-       <listitem><para>

- 	Most implementations of YAML

-       </para></listitem>

-     </itemizedlist>

-     <para>

-       When using a type-directed deserialization format where the

-       types of the deserialized objects are specified by the

-       programmer, make sure that the objects which can be instantiated

-       cannot perform any destructive actions in their destructors,

-       even when the data members have been manipulated.

-     </para>

-     <para>

-       In general, JSON decoders do not suffer from this problem.  But

-       you must not use the <function>eval</function> function to parse

-       JSON objects in Javascript; even with the regular expression

-       filter from RFC 4627, there are still information leaks

-       remaining.  JSON-based formats can still turn out risky if they

-       serve as an encoding form for any if the serialization

-       frameworks listed above.

-     </para>

-   </section>

- 

-   <section id="sect-Defensive_Coding-Tasks-Serialization-XML">

-     <title>XML serialization</title>

-     <para>

-     </para>

-     <section id="sect-Defensive_Coding-Tasks-Serialization-XML-External">

-       <title>External references</title>

-       <para>

- 	XML documents can contain external references.  They can occur

- 	in various places.

-       </para>

-       <itemizedlist>

- 	<listitem>

- 	  <para>

- 	    In the DTD declaration in the header of an XML document:

- 	  </para>

- 	  <informalexample>

- 	    <programlisting language="XML">

- <![CDATA[<!DOCTYPE html PUBLIC

-   "-//W3C//DTD XHTML 1.0 Transitional//EN"

-   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">]]>

- 	    </programlisting>

- 	  </informalexample>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    In a namespace declaration:

- 	  </para>

- 	  <informalexample>

- 	    <programlisting language="XML">

- <![CDATA[<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">]]>

- 	    </programlisting>

- 	  </informalexample>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    In an entity defintion:

- 	  </para>

- 	  <informalexample>

- 	    <programlisting language="XML">

- <![CDATA[<!ENTITY sys SYSTEM "http://www.example.com/ent.xml">

- <!ENTITY pub PUBLIC "-//Example//Public Entity//EN"

-   "http://www.example.com/pub-ent.xml">]]>

- 	    </programlisting>

- 	  </informalexample>

- 	</listitem>

- 	<listitem>

- 	  <para>

- 	    In a notation:

- 	  </para>

- 	  <informalexample>

- 	    <programlisting language="XML">

- <![CDATA[<!NOTATION not SYSTEM "../not.xml">]]>

- 	    </programlisting>

- 	  </informalexample>

- 	</listitem>

-       </itemizedlist>

-       <para>

- 	Originally, these external references were intended as unique

- 	identifiers, but by many XML implementations, they are used

- 	for locating the data for the referenced element.  This causes

- 	unwanted network traffic, and may disclose file system

- 	contents or otherwise unreachable network resources, so this

- 	functionality should be disabled.

-       </para>

-       <para>

- 	Depending on the XML library, external referenced might be

- 	processed not just when parsing XML, but also when generating

- 	it.

-       </para>

-     </section>

-     <section id="sect-Defensive_Coding-Tasks-Serialization-XML-Entities">

-       <title>Entity expansion</title>

-       <para>

- 	When external DTD processing is disabled, an internal DTD

- 	subset can still contain entity definitions.  Entity

- 	declarations can reference other entities.  Some XML libraries

- 	expand entities automatically, and this processing cannot be

- 	switched off in some places (such as attribute values or

- 	content models).  Without limits on the entity nesting level,

- 	this expansion results in data which can grow exponentially in

- 	length with size of the input.  (If there is a limit on the

- 	nesting level, the growth is still polynomial, unless further

- 	limits are imposed.)

-       </para>

-       <para>

- 	Consequently, the processing internal DTD subsets should be

- 	disabled if possible, and only trusted DTDs should be

- 	processed.  If a particular XML application does not permit

- 	such restrictions, then application-specific limits are called

- 	for.

-       </para>

-     </section>

- 

-     <section id="sect-Defensive_Coding-Tasks-Serialization-XML-XInclude">

-       <title>XInclude processing</title>

-       <para>

- 	XInclude processing can reference file and network resources

- 	and include them into the document, much like external entity

- 	references.  When parsing untrusted XML documents, XInclude

- 	processing should be truned off.

-       </para>

-       <para>

- 	XInclude processing is also fairly complex and may pull in

- 	support for the XPointer and XPath specifications,

- 	considerably increasing the amount of code required for XML

- 	processing.

-       </para>

-     </section>

- 

-     <section id="sect-Defensive_Coding-Tasks-Serialization-XML-Validation">

-       <title>Algorithmic complexity of XML validation</title>

-       <para>

- 	DTD-based XML validation uses regular expressions for content

- 	models.  The XML specification requires that content models

- 	are deterministic, which means that efficient validation is

- 	possible.  However, some implementations do not enforce

- 	determinism, and require exponential (or just polynomial)

- 	amount of space or time for validating some DTD/document

- 	combinations.

-       </para>

-       <para>

- 	XML schemas and RELAX NG (via the <literal>xsd:</literal>

- 	prefix) directly support textual regular expressions which are

- 	not required to be deterministic.

-       </para>

-     </section>

-     <section id="sect-Defensive_Coding-Tasks-Serialization-XML-Expat">

-       <title>Using Expat for XML parsing</title>

-       <para>

- 	By default, Expat does not try to resolve external IDs, so no

- 	steps are required to block them.  However, internal entity

- 	declarations are processed.  Installing a callback which stops

- 	parsing as soon as such entities are encountered disables

- 	them, see <xref

- 	linkend="ex-Defensive_Coding-Tasks-Serialization-XML-Expat-EntityDeclHandler"/>.

- 	Expat does not perform any validation, so there are no

- 	problems related to that.

-       </para>

-       <example id="ex-Defensive_Coding-Tasks-Serialization-XML-Expat-EntityDeclHandler">

- 	<title>Disabling XML entity processing with Expat</title>

- 	<xi:include href="snippets/Tasks-Serialization-XML-Expat-EntityDeclHandler.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	This handler must be installed when the

- 	<literal>XML_Parser</literal> object is created (<xref

- 	linkend="ex-Defensive_Coding-Tasks-Serialization-XML-Expat-Create"/>).

-       </para>

-       <example id="ex-Defensive_Coding-Tasks-Serialization-XML-Expat-Create">

- 	<title>Creating an Expat XML parser</title>

- 	<xi:include href="snippets/Tasks-Serialization-XML-Expat-Create.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	It is also possible to reject internal DTD subsets altogeher,

- 	using a suitable

- 	<literal>XML_StartDoctypeDeclHandler</literal> handler

- 	installed with <function>XML_SetDoctypeDeclHandler</function>.

-       </para>

-     </section>

- 

-     <section id="sect-Defensive_Coding-Tasks-Serialization-Qt">

-       <title>Using Qt for XML parsing</title>

-       <para>

- 	The XML component of Qt, QtXml, does not resolve external IDs

- 	by default, so it is not requred to prevent such resolution.

- 	Internal entities are processed, though.  To change that, a

- 	custom <literal>QXmlDeclHandler</literal> and

- 	<literal>QXmlSimpleReader</literal> subclasses are needed.  It

- 	is not possible to use the

- 	<function>QDomDocument::setContent(const QByteArray

- 	&amp;)</function> convenience methods.

-       </para>

-       <para>

- 	<xref linkend="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityHandler"/>

- 	shows an entity handler which always returns errors, causing

- 	parsing to stop when encountering entity declarations.

-       </para>

-       <example id="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityHandler">

- 	<title>A QtXml entity handler which blocks entity processing</title>

- 	<xi:include href="snippets/Tasks-Serialization-XML-Qt-NoEntityHandler.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	This handler is used in the custom

- 	<literal>QXmlReader</literal> subclass in <xref

- 	linkend="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityReader"/>.

- 	Some parts of QtXml will call the

- 	<function>setDeclHandler(QXmlDeclHandler *)</function> method.

- 	Consequently, we prevent overriding our custom handler by

- 	providing a definition of this method which does nothing.  In

- 	the constructor, we activate namespace processing; this part

- 	may need adjusting.

-       </para>

-       <example id="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-NoEntityReader">

- 	<title>A QtXml XML reader which blocks entity processing</title>

- 	<xi:include href="snippets/Tasks-Serialization-XML-Qt-NoEntityReader.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	Our <literal>NoEntityReader</literal> class can be used with

- 	one of the overloaded

- 	<function>QDomDocument::setContent</function> methods.

- 	<xref linkend="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-QDomDocument"/>

- 	shows how the <literal>buffer</literal> object (of type

- 	<literal>QByteArray</literal>) is wrapped as a

- 	<literal>QXmlInputSource</literal>.  After calling the

- 	<function>setContent</function> method, you should check the

- 	return value and report any error.

-       </para>

-       <example id="ex-Defensive_Coding-Tasks-Serialization-XML-Qt-QDomDocument">

- 	<title>Parsing an XML document with QDomDocument, without entity expansion</title>

- 	<xi:include href="snippets/Tasks-Serialization-XML-Qt-QDomDocument.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-     </section>

- 

-     <section id="sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse">

-       <title>Using OpenJDK for XML parsing and validation</title>

-       <para>

- 	OpenJDK contains facilities for DOM-based, SAX-based, and

- 	StAX-based document parsing.  Documents can be validated

- 	against DTDs or XML schemas.

-       </para>

-       <para>

- 	The approach taken to deal with entity expansion differs from

- 	the general recommendation in <xref

- 	linkend="sect-Defensive_Coding-Tasks-Serialization-XML-Entities"/>.

- 	We enable the the feature flag

- 	<literal>javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING</literal>,

- 	which enforces heuristic restrictions on the number of entity

- 	expansions.  Note that this flag alone does not prevent

- 	resolution of external references (system IDs or public IDs),

- 	so it is slightly misnamed.

-       </para>

-       <para>

- 	In the following sections, we use helper classes to prevent

- 	external ID resolution.

-       </para>

-       <example id="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-NoEntityResolver">

- 	<title>Helper class to prevent DTD external entity resolution in OpenJDK</title>

- 	<xi:include href="snippets/Tasks-Serialization-XML-OpenJDK-NoEntityResolver.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <example id="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-NoResourceResolver">

- 	<title>Helper class to prevent schema resolution in

- 	OpenJDK</title>

- 	<xi:include href="snippets/Tasks-Serialization-XML-OpenJDK-NoResourceResolver.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <para>

- 	<xref linkend="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-Imports"/>

- 	shows the imports used by the examples.

-       </para>

-       <example id="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-Imports">

- 	<title>Java imports for OpenJDK XML parsing</title>

- 	<xi:include href="snippets/Tasks-Serialization-XML-OpenJDK-Imports.xml"

- 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

-       </example>

-       <section id="sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-DOM">

- 	<title>DOM-based XML parsing and DTD validation in OpenJDK</title>

- 	<para>

- 	  This approach produces a

- 	  <literal>org.w3c.dom.Document</literal> object from an input

- 	  stream.  <xref linkend="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-DOM"/>

- 	  use the data from the <literal>java.io.InputStream</literal>

- 	  instance in the <literal>inputStream</literal> variable.

- 	</para>

- 	<example id="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-DOM">

- 	  <title>DOM-based XML parsing in OpenJDK</title>

- 	  <xi:include href="snippets/Tasks-Serialization-XML-OpenJDK_Parse-DOM.xml"

- 		      xmlns:xi="http://www.w3.org/2001/XInclude" />

- 	</example>

- 	<para>

- 	  External entity references are prohibited using the

- 	  <literal>NoEntityResolver</literal> class in

- 	  <xref linkend="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-NoEntityResolver"/>.

- 	  Because external DTD references are prohibited, DTD validation

- 	  (if enabled) will only happen against the internal DTD subset

- 	  embedded in the XML document.

- 	</para>

- 	<para>

- 	  To validate the document against an external DTD, use a

- 	  <literal>javax.xml.transform.Transformer</literal> class to

- 	  add the DTD reference to the document, and an entity

- 	  resolver which whitelists this external reference.

- 	</para>

-       </section>

-       

-       <section id="sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-SAX">

- 	<title>XML Schema validation in OpenJDK</title>

- 	<para>

- 	  <xref linkend="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_SAX"/>

- 	  shows how to validate a document against an XML Schema,

- 	  using a SAX-based approach.  The XML data is read from an

- 	  <literal>java.io.InputStream</literal> in the

- 	  <literal>inputStream</literal> variable.

- 	</para>

- 	<example id="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_SAX">

- 	  <title>SAX-based validation against an XML schema in

- 	  OpenJDK</title>

- 	  <xi:include href="snippets/Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_SAX.xml"

- 		      xmlns:xi="http://www.w3.org/2001/XInclude" />

- 	</example>

- 	<para>

- 	  The <literal>NoResourceResolver</literal> class is defined

- 	  in <xref linkend="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK-NoResourceResolver"/>.

- 	</para>

- 	<para>

- 	  If you need to validate a document against an XML schema,

- 	  use the code in <xref

- 	  linkend="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-DOM"/>

- 	  to create the document, but do not enable validation at this

- 	  point.  Then use

- 	  <xref linkend="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_DOM"/>

- 	  to perform the schema-based validation on the

- 	  <literal>org.w3c.dom.Document</literal> instance

- 	  <literal>document</literal>.

- 	</para>

- 	<example id="ex-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_DOM">

- 	  <title>Validation of a DOM document against an XML schema in

- 	  OpenJDK</title>

- 	  <xi:include href="snippets/Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_DOM.xml"

- 		      xmlns:xi="http://www.w3.org/2001/XInclude" />

- 	</example>

-       </section>

-       <section id="sect-Defensive_Coding-Tasks-Serialization-XML-OpenJDK_Parse-Other">

- 	<title>Other XML parsers in OpenJDK</title>

- 	<para>

- 	  OpenJDK contains additional XML parsing and processing

- 	  facilities.  Some of them are insecure.

- 	</para>

- 	<para>

- 	  The class <type>java.beans.XMLDecoder</type> acts as a

- 	  bridge between the Java object serialization format and XML.

- 	  It is close to impossible to securely deserialize Java

- 	  objects in this format from untrusted inputs, so its use is

- 	  not recommended, as with the Java object serialization

- 	  format itself.  See <xref

- 	  linkend="sect-Defensive_Coding-Tasks-Serialization-Library"/>.

- 	</para>

-       </section>

-     </section>

-   </section>

- 

-   <section>

-     <title>Protocol Encoders</title>

-     <para>

-       For protocol encoders, you should write bytes to a buffer which

-       grows as needed, using an exponential sizing policy.  Explicit

-       lengths can be patched in later, once they are known.

-       Allocating the required number of bytes upfront typically

-       requires separate code to compute the final size, which must be

-       kept in sync with the actual encoding step, or vulnerabilities

-       may result.  In multi-threaded code, parts of the object being

-       deserialized might change, so that the computed size is out of

-       date.

-     </para>

-     <para>

-       You should avoid copying data directly from a received packet

-       during encoding, disregarding the format.  Propagating malformed

-       data could enable attacks on other recipients of that data.

-     </para>

-     <para>

-       When using C or C++ and copying whole data structures directly

-       into the output, make sure that you do not leak information in

-       padding bytes between fields or at the end of the

-       <literal>struct</literal>.

-     </para>

-   </section>

- 

- </chapter>

- 

en-US/Tasks-Temporary_Files.adoc
file added
+181
@@ -0,0 +1,181 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Tasks-Temporary_Files]]

+ === Temporary Files

+ 

+ In this chapter, we describe how to create temporary files and

+ directories, how to remove them, and how to work with programs

+ which do not create files in ways that are safe with a shared

+ directory for temporary files. General file system manipulation

+ is treated in a separate chapter, <<chap-Defensive_Coding-Tasks-File_System>>.

+ 

+ Secure creation of temporary files has four different aspects.

+ 

+ * The location of the directory for temporary files must be

+ obtained in a secure manner (that is, untrusted environment

+ variables must be ignored, see <<sect-Defensive_Coding-Tasks-secure_getenv>>).

+ 

+ * A new file must be created. Reusing an existing file must be

+ avoided (the `/tmp` race

+ condition). This is tricky because traditionally, system-wide

+ temporary directories shared by all users are used.

+ 

+ * The file must be created in a way that makes it impossible for

+ other users to open it.

+ 

+ * The descriptor for the temporary file should not leak to

+ subprocesses.

+ 

+ All functions mentioned below will take care of these aspects.

+ 

+ Traditionally, temporary files are often used to reduce memory

+ usage of programs. More and more systems use RAM-based file

+ systems such as `tmpfs` for storing temporary

+ files, to increase performance and decrease wear on Flash storage.

+ As a result, spooling data to temporary files does not result in

+ any memory savings, and the related complexity can be avoided if

+ the data is kept in process memory.

+ 

+ [[chap-Defensive_Coding-Tasks-Temporary_Files-Location]]

+ ==== Obtaining the Location of Temporary Directory

+ 

+ Some functions below need the location of a directory which

+ stores temporary files. For C/C++ programs, use the following

+ steps to obtain that directory:

+ 

+ * Use `secure_getenv` to obtain the value

+ of the `TMPDIR` environment variable. If

+ it is set, convert the path to a fully-resolved absolute

+ path, using `realpath(path, NULL)`. Check

+ if the new path refers to a directory and is writeable. In

+ this case, use it as the temporary directory.

+ 

+ * Fall back to `/tmp`.

+ 

+ In Python, you can use the `tempfile.tempdir`

+ variable.

+ 

+ Java does not support SUID/SGID programs, so you can use the

+ `java.lang.System.getenv(String)` method to

+ obtain the value of the `TMPDIR` environment

+ variable, and follow the two steps described above. (Java's

+ default directory selection does not honor

+ `TMPDIR`.)

+ 

+ ==== Named Temporary Files

+ 

+ The `mkostemp` function creates a named

+ temporary file. You should specify the

+ `O_CLOEXEC` flag to avoid file descriptor leaks

+ to subprocesses. (Applications which do not use multiple threads

+ can also use `mkstemp`, but libraries should

+ use `mkostemp`.) For determining the

+ directory part of the file name pattern, see <<chap-Defensive_Coding-Tasks-Temporary_Files-Location>>.

+ 

+ The file is not removed automatically. It is not safe to rename

+ or delete the file before processing, or transform the name in

+ any way (for example, by adding a file extension). If you need

+ multiple temporary files, call `mkostemp`

+ multiple times. Do not create additional file names derived

+ from the name provided by a previous

+ `mkostemp` call. However, it is safe to close

+ the descriptor returned by `mkostemp` and

+ reopen the file using the generated name.

+ 

+ The Python class `tempfile.NamedTemporaryFile`

+ provides similar functionality, except that the file is deleted

+ automatically by default. Note that you may have to use the

+ `file` attribute to obtain the actual file

+ object because some programming interfaces cannot deal with

+ file-like objects. The C function `mkostemp`

+ is also available as `tempfile.mkstemp`.

+ 

+ In Java, you can use the

+ `java.io.File.createTempFile(String, String,

+ File)` function, using the temporary file location

+ determined according to <<chap-Defensive_Coding-Tasks-Temporary_Files-Location>>.

+ Do not use `java.io.File.deleteOnExit()` to

+ delete temporary files, and do not register a shutdown hook for

+ each temporary file you create. In both cases, the deletion

+ hint cannot be removed from the system if you delete the

+ temporary file prior to termination of the VM, causing a memory

+ leak.

+ 

+ ==== Temporary Files without Names

+ 

+ The `tmpfile` function creates a temporary

+ file and immediately deletes it, while keeping the file open.

+ As a result, the file lacks a name and its space is deallocated

+ as soon as the file descriptor is closed (including the implicit

+ close when the process terminates). This avoids cluttering the

+ temporary directory with orphaned files.

+ 

+ Alternatively, if the maximum size of the temporary file is

+ known beforehand, the `fmemopen` function can

+ be used to create a `FILE *` object which is

+ backed by memory.

+ 

+ In Python, unnamed temporary files are provided by the

+ `tempfile.TemporaryFile` class, and the

+ `tempfile.SpooledTemporaryFile` class provides

+ a way to avoid creation of small temporary files.

+ 

+ Java does not support unnamed temporary files.

+ 

+ [[chap-Defensive_Coding-Tasks-Temporary_Directory]]

+ ==== Temporary Directories

+ 

+ The `mkdtemp` function can be used to create

+ a temporary directory. (For determining the directory part of

+ the file name pattern, see <<chap-Defensive_Coding-Tasks-Temporary_Files-Location>>.)

+ The directory is not automatically removed. In Python, this

+ function is available as `tempfile.mkdtemp`.

+ In Java 7, temporary directories can be created using the

+ `java.nio.file.Files.createTempDirectory(Path, String,

+ FileAttribute...)` function.

+ 

+ When creating files in the temporary directory, use

+ automatically generated names, e.g., derived from a sequential

+ counter. Files with externally provided names could be picked

+ up in unexpected contexts, and crafted names could actually

+ point outside of the tempoary directory (due to

+ *directory traversal*).

+ 

+ Removing a directory tree in a completely safe manner is

+ complicated. Unless there are overriding performance concerns,

+ the [application]*rm* program should be used, with

+ the [option]`-rf` and [option]`--` options.

+ 

+ ==== Compensating for Unsafe File Creation

+ 

+ There are two ways to make a function or program which excepts a

+ file name safe for use with temporary files. See

+ <<sect-Defensive_Coding-Tasks-Processes-Creation>>,

+ for details on subprocess creation.

+ 

+ * Create a temporary directory and place the file there. If

+ possible, run the program in a subprocess which uses the

+ temporary directory as its current directory, with a

+ restricted environment.

+ Use generated names for all files in that temporary

+ directory. (See <<chap-Defensive_Coding-Tasks-Temporary_Directory>>.)

+ 

+ * Create the temporary file and pass the generated file name

+ to the function or program. This only works if the function

+ or program can cope with a zero-length existing file. It is

+ safe only under additional assumptions:

+ +

+ ** The function or program must not create additional files

+ whose name is derived from the specified file name or

+ are otherwise predictable.

+ +

+ ** The function or program must not delete the file before

+ processing it.

+ +

+ ** It must not access any existing files in the same

+ directory.

+ +

+ It is often difficult to check whether these additional

+ assumptions are matched, therefore this approach is not

+ recommended. 

\ No newline at end of file

en-US/Tasks-Temporary_Files.xml
file removed
-257
@@ -1,257 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Tasks-Temporary_Files">

-   <title>Temporary files</title>

-   <para>

-     In this chapter, we describe how to create temporary files and

-     directories, how to remove them, and how to work with programs

-     which do not create files in ways that are safe with a shared

-     directory for temporary files.  General file system manipulation

-     is treated in a separate chapter, <xref

-     linkend="chap-Defensive_Coding-Tasks-File_System"/>.

-   </para>

-   <para>

-     Secure creation of temporary files has four different aspects.

-   </para>

-   <itemizedlist>

-     <listitem>

-       <para>

- 	The location of the directory for temporary files must be

- 	obtained in a secure manner (that is, untrusted environment

- 	variables must be ignored, see <xref

- 	linkend="sect-Defensive_Coding-Tasks-secure_getenv"/>).

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	A new file must be created.  Reusing an existing file must be

- 	avoided (the <filename class="directory">/tmp</filename> race

- 	condition).  This is tricky because traditionally, system-wide

- 	temporary directories shared by all users are used.

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	The file must be created in a way that makes it impossible for

- 	other users to open it.

-       </para>

-     </listitem>

-     <listitem>

-       <para>

- 	The descriptor for the temporary file should not leak to

- 	subprocesses.

-       </para>

-     </listitem>

-   </itemizedlist>

-   <para>

-     All functions mentioned below will take care of these aspects.

-   </para>

-   <para>

-     Traditionally, temporary files are often used to reduce memory

-     usage of programs.  More and more systems use RAM-based file

-     systems such as <literal>tmpfs</literal> for storing temporary

-     files, to increase performance and decrease wear on Flash storage.

-     As a result, spooling data to temporary files does not result in

-     any memory savings, and the related complexity can be avoided if

-     the data is kept in process memory.

-   </para>

- 

-   <section id="chap-Defensive_Coding-Tasks-Temporary_Files-Location">

-     <title>Obtaining the location of temporary directory</title>

-     <para>

-       Some functions below need the location of a directory which

-       stores temporary files.  For C/C++ programs, use the following

-       steps to obtain that directory:

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Use <function>secure_getenv</function> to obtain the value

- 	  of the <literal>TMPDIR</literal> environment variable.  If

- 	  it is set, convert the path to a fully-resolved absolute

- 	  path, using <literal>realpath(path, NULL)</literal>.  Check

- 	  if the new path refers to a directory and is writeable.  In

- 	  this case, use it as the temporary directory.

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Fall back to <filename class="directory">/tmp</filename>.

- 	</para>

-       </listitem>

-     </itemizedlist>

-     <para>

-       In Python, you can use the <varname>tempfile.tempdir</varname>

-       variable.

-     </para>

-     <para>

-       Java does not support SUID/SGID programs, so you can use the

-       <function>java.lang.System.getenv(String)</function> method to

-       obtain the value of the <literal>TMPDIR</literal> environment

-       variable, and follow the two steps described above.  (Java's

-       default directory selection does not honor

-       <literal>TMPDIR</literal>.)

-     </para>

-   </section>

- 

-   <section>

-     <title>Named temporary files</title>

-     <para>

-       The <function>mkostemp</function> function creates a named

-       temporary file.  You should specify the

-       <literal>O_CLOEXEC</literal> flag to avoid file descriptor leaks

-       to subprocesses. (Applications which do not use multiple threads

-       can also use <function>mkstemp</function>, but libraries should

-       use <function>mkostemp</function>.)  For determining the

-       directory part of the file name pattern, see <xref

-       linkend="chap-Defensive_Coding-Tasks-Temporary_Files-Location"/>.

-     </para>

-     <para>

-       The file is not removed automatically.  It is not safe to rename

-       or delete the file before processing, or transform the name in

-       any way (for example, by adding a file extension).  If you need

-       multiple temporary files, call <function>mkostemp</function>

-       multiple times.  Do not create additional file names derived

-       from the name provided by a previous

-       <function>mkostemp</function> call.  However, it is safe to close

-       the descriptor returned by <function>mkostemp</function> and

-       reopen the file using the generated name.

-     </para>

-     <para>

-       The Python class <literal>tempfile.NamedTemporaryFile</literal>

-       provides similar functionality, except that the file is deleted

-       automatically by default.  Note that you may have to use the

-       <literal>file</literal> attribute to obtain the actual file

-       object because some programming interfaces cannot deal with

-       file-like objects. The C function <function>mkostemp</function>

-       is also available as <function>tempfile.mkstemp</function>.

-     </para>

-     <para>

-       In Java, you can use the

-       <function>java.io.File.createTempFile(String, String,

-       File)</function> function, using the temporary file location

-       determined according to <xref

-       linkend="chap-Defensive_Coding-Tasks-Temporary_Files-Location"/>.

-       Do not use <function>java.io.File.deleteOnExit()</function> to

-       delete temporary files, and do not register a shutdown hook for

-       each temporary file you create.  In both cases, the deletion

-       hint cannot be removed from the system if you delete the

-       temporary file prior to termination of the VM, causing a memory

-       leak.

-     </para>

-   </section>

- 

-   <section>

-     <title>Temporary files without names</title>

-     <para>

-       The <function>tmpfile</function> function creates a temporary

-       file and immediately deletes it, while keeping the file open.

-       As a result, the file lacks a name and its space is deallocated

-       as soon as the file descriptor is closed (including the implicit

-       close when the process terminates).  This avoids cluttering the

-       temporary directory with orphaned files.

-     </para>

-     <para>

-       Alternatively, if the maximum size of the temporary file is

-       known beforehand, the <function>fmemopen</function> function can

-       be used to create a <literal>FILE *</literal> object which is

-       backed by memory.

-     </para>

-     <para>

-       In Python, unnamed temporary files are provided by the

-       <literal>tempfile.TemporaryFile</literal> class, and the

-       <literal>tempfile.SpooledTemporaryFile</literal> class provides

-       a way to avoid creation of small temporary files.

-     </para>

-     <para>

-       Java does not support unnamed temporary files.

-     </para>

-   </section>

- 

-   <section id="chap-Defensive_Coding-Tasks-Temporary_Directory">

-     <title>Temporary directories</title>

-     <para>

-       The <function>mkdtemp</function> function can be used to create

-       a temporary directory.  (For determining the directory part of

-       the file name pattern, see <xref

-       linkend="chap-Defensive_Coding-Tasks-Temporary_Files-Location"/>.)

-       The directory is not automatically removed.  In Python, this

-       function is available as <function>tempfile.mkdtemp</function>.

-       In Java 7, temporary directories can be created using the

-       <function>java.nio.file.Files.createTempDirectory(Path, String,

-       FileAttribute...)</function> function.

-     </para>

-     <para>

-       When creating files in the temporary directory, use

-       automatically generated names, e.g., derived from a sequential

-       counter.  Files with externally provided names could be picked

-       up in unexpected contexts, and crafted names could actually

-       point outside of the tempoary directory (due to

-       <emphasis>directory traversal</emphasis>).

-     </para>

-     <para>

-       Removing a directory tree in a completely safe manner is

-       complicated.  Unless there are overriding performance concerns,

-       the <application>rm</application> program should be used, with

-       the <option>-rf</option> and <option>--</option> options.

-     </para>

-   </section>

- 

-   <section>

-     <title>Compensating for unsafe file creation</title>

-     <para>

-       There are two ways to make a function or program which excepts a

-       file name safe for use with temporary files. See

-       <xref linkend="sect-Defensive_Coding-Tasks-Processes-Creation"/>,

-       for details on subprocess creation.

-     </para>

-     <itemizedlist>

-       <listitem>

- 	<para>

- 	  Create a temporary directory and place the file there.  If

- 	  possible, run the program in a subprocess which uses the

- 	  temporary directory as its current directory, with a

- 	  restricted environment.

- 	  Use generated names for all files in that temporary

- 	  directory.  (See <xref

- 	  linkend="chap-Defensive_Coding-Tasks-Temporary_Directory"/>.)

- 	</para>

-       </listitem>

-       <listitem>

- 	<para>

- 	  Create the temporary file and pass the generated file name

- 	  to the function or program.  This only works if the function

- 	  or program can cope with a zero-length existing file.  It is

- 	  safe only under additional assumptions:

- 	</para>

- 	<itemizedlist>

- 	  <listitem>

- 	    <para>

- 	      The function or program must not create additional files

- 	      whose name is derived from the specified file name or

- 	      are otherwise predictable.

- 	    </para>

- 	  </listitem>

- 	  <listitem>

- 	    <para>

- 	      The function or program must not delete the file before

- 	      processing it.

- 	    </para>

- 	  </listitem>

- 	  <listitem>

- 	    <para>

- 	      It must not access any existing files in the same

- 	      directory.

- 	    </para>

- 	  </listitem>

- 	</itemizedlist>

- 	<para>

- 	  It is often difficult to check whether these additional

- 	  assumptions are matched, therefore this approach is not

- 	  recommended.

- 	</para>

-       </listitem>

-     </itemizedlist>

-   </section>

- </chapter>

en-US/Vala.adoc
file added
+36
@@ -0,0 +1,36 @@

+ 

+ :experimental:

+ 

+ [[chap-Defensive_Coding-Vala]]

+ === The Vala Programming Language

+ 

+ Vala is a programming language mainly targeted at GNOME developers.

+ 

+ Its syntax is inspired by C# (and thus, indirectly, by Java). But

+ unlike C# and Java, Vala does not attempt to provide memory safety:

+ Vala is compiled to C, and the C code is compiled with GCC using

+ typical compiler flags. Basic operations like integer arithmetic

+ are directly mapped to C constructs. As a results, the

+ recommendations in <<chap-Defensive_Coding-C>> apply.

+ 

+ In particular, the following Vala language constructs can result in

+ undefined behavior at run time:

+ 

+ * Integer arithmetic, as described in <<sect-Defensive_Coding-C-Arithmetic>>.

+ 

+ * Pointer arithmetic, string subscripting and the

+ `substring` method on strings (the

+ `string` class in the

+ `glib-2.0` package) are not range-checked. It

+ is the responsibility of the calling code to ensure that the

+ arguments being passed are valid. This applies even to cases

+ (like `substring`) where the implementation

+ would have range information to check the validity of indexes.

+ See <<sect-Defensive_Coding-C-Pointers>>.

+ 

+ * Similarly, Vala only performs garbage collection (through

+ reference counting) for `GObject` values. For

+ plain C pointers (such as strings), the programmer has to ensure

+ that storage is deallocated once it is no longer needed (to

+ avoid memory leaks), and that storage is not being deallocated

+ while it is still being used (see <<sect-Defensive_Coding-C-Use-After-Free>>). 

\ No newline at end of file

en-US/Vala.xml
file removed
-53
@@ -1,53 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Vala">

- <title>The Vala Programming Language</title>

- <para>

-   Vala is a programming language mainly targeted at GNOME developers.

- </para>

- <para>

-   Its syntax is inspired by C# (and thus, indirectly, by Java).  But

-   unlike C# and Java, Vala does not attempt to provide memory safety:

-   Vala is compiled to C, and the C code is compiled with GCC using

-   typical compiler flags.  Basic operations like integer arithmetic

-   are directly mapped to C constructs.  As a results, the

-   recommendations in <xref linkend="chap-Defensive_Coding-C"/> apply.

- </para>

- <para>

-   In particular, the following Vala language constructs can result in

-   undefined behavior at run time:

- </para>

- <itemizedlist>

-   <listitem>

-     <para>

-       Integer arithmetic, as described in <xref

-       linkend="sect-Defensive_Coding-C-Arithmetic"/>.

-     </para>

-   </listitem>

-   <listitem>

-     <para>

-       Pointer arithmetic, string subscripting and the

-       <literal>substring</literal> method on strings (the

-       <literal>string</literal> class in the

-       <literal>glib-2.0</literal> package) are not range-checked.  It

-       is the responsibility of the calling code to ensure that the

-       arguments being passed are valid.  This applies even to cases

-       (like <literal>substring</literal>) where the implementation

-       would have range information to check the validity of indexes.

-       See <xref linkend="sect-Defensive_Coding-C-Pointers"/>.

-     </para>

-   </listitem>

-   <listitem>

-     <para>

-       Similarly, Vala only performs garbage collection (through

-       reference counting) for <literal>GObject</literal> values.  For

-       plain C pointers (such as strings), the programmer has to ensure

-       that storage is deallocated once it is no longer needed (to

-       avoid memory leaks), and that storage is not being deallocated

-       while it is still being used (see <xref

-       linkend="sect-Defensive_Coding-C-Use-After-Free"/>).

-     </para>

-   </listitem>

- </itemizedlist>

- </chapter>

en-US/Web_Applications.xml.txt
file removed
-2118
@@ -1,2118 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <chapter id="chap-Defensive_Coding-Web_Applications">

- 	<title>Web Applications</title>

- 	<para>How to protect your web application against some of the more common format of attacks.</para>

- 

- 	<section id="sect-Defensive_Coding-Web_Applications-Cross_site_scripting">

- 		<title>Cross site scripting</title>

- 		<para>Cross Site Scripting (XSS) vulnerabilities are often used a foothold for more sophisticated vectors and it is why they need to be taken seriously. Generally speaking there are two forms of XSS attacks, reflected and persisted.</para>

- 

- 		<section>

- 			<title>Reflected XSS attack</title>

- 			<para>A reflected XSS attack occurs when an attacker can directly manipulate a HTTP request parameter to inject malicious Javascript code into the rendered page.  The attacker tricks a victim to click on the specially crafted link to execute malicious script.</para>

- 			<para>Consider a simple servlet that greets a user via a HTTP request parameter:</para>

- <code>

-   protected void doGet(...){

-     response.getWriter().printf("Welcome %s", request.getParameter('name'));  

-   }

- </code>

- 

- 			<para>An attacker could in theory create a link that contains Javascript that will be executed in the victims browser like so:</para>

- <code>

- http://example.com/?name=&#60;script&#62;alert(1)&#60;/script&#62;

- </code>

- 		</section>

- 		<section>

- 			<title>Persisted XSS attack</title>

- 			<para>This variation of the XSS attack uses the ability of a registered user to be able to store content in the web applications database. The attacker saves the malicious script to the database via a web form with the knowledge that it will be embedded in a rendered page at a later time when viewed by a victim. This scenario is most common in sites that allow users to post comments or rate products without taking the appropriate security precautions.</para>

- 		</section>

- 	</section>

- 	<section>

- 		<title>Defending against XSS attacks</title>

- 		<para/>

- 

- 		<section>

- 			<title>Escaping user controlled content</title>

- 			<para>The most effective mechanism for preventing XSS attacks is to ensure that any user controlled content is safely escaped. Most modern web frameworks have mechanisms to do this which are automatically enabled. There should be limited reasons to stray outside of this practice for all user controlled input.</para>

- 			<para>The Seam framework escapes content by default unless explicitly told not to.</para>

- 

- <code>

- Will be escaped

- &#60;h:outputText value="#{param.name}"&#62;

- 

- Won't be escaped (DON'T DO THIS!)

- &#60;h:outputText value="#{param.name}" escape=false&#62;

- </code>

- 

- 			<para>Similarly Flask templates will escape content by default unless explicitly told not to.</para>

- 

- <code>

- This will be escaped

- {{ user_controlled_input }}

- 

- Unless you do this

- {{ user_controlled_input | safe }}

- </code>

- 			<para>To escape HTML content directly within a Flask request handler you need only import escape.</para>

- 

- <code>

- from flask import g, request, flash, abort, escape

- 

- @app.route('/say_hello')

- def say_hello():

-   return "&#60;p&#62;Hi %s&#60;/p&#62;" % (escape(request.args.get('name')))

- </code>

- 

- 			<para>You can also do this directly in Java code using Apache commons</para>

- <code>

- import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;

- 

- void doGet(...){

-   response.getWriter().printf("&#60;p&#62;Hello, %s&#60;/p&#62;", escapeHtml(request.getParameter("name")));

- }

- </code>

- 

- 			<important>

- 				<para>You should *NOT* try to implement your own escaping mechanisms or blacklists when a better, security tested alternative is available.</para>

- 			</important>

- 

- 			<para>Some caveats around how to escape content correctly and safely will be covered in more details in the &#60;_output_escaping_and_encoding,output escaping and encoding&#62;&#62; section.</para>

- 

- 			<section>

- 				<title>Monitoring and validating HTTP parameters</title>

- 				<para>Tampering with HTTP parameters can be a good indication that your site is being probed for weaknesses. It is a good idea to validate user HTTP parameters against a whitelist of trusted input characters that omit anything that may be used to construct malicious input.</para>

- <code>

- def say_hello():

-   user_input = request.args.get('name')

-   whitelist = re.compile('^\w+$') 

-   if not whitelist.match(user_input):

-     return abort(400)

- 

-   return "Hello %s" % escape(user_input)

- </code>			

- 			</section>

- 		</section>

- 		<section>

- 			<title>Leveraging browser security features</title>

- 			<para>Most modern browsers have added capabilities to thwart these types of attacks. However to take advantage of them some effort is required by the web application developer.</para>

- 			<section>

- 				<title>X-XSS-Protection</title>

- 				<para>The first of these measures is a simple header that should be supplied with each HTTP response from the server. It ensures that a XSS filter is enabled in some older browsers (IE8 and IE9). The filter mechanism in these browsers is disabled by default. Other browsers will ignore this header.</para>

- <code>

- // You can manually add this header to each request using 

- // a custom filter and enabling it in your web.xml

- public void doFilter(...){

-   request.addHeader("X-XSS-Protection", "1; mode=block;");

-   ... 

- }

- </code>

- <code>

- # (flask)

- @app.after_request

- def xss_protection(rsp):

-   rsp.headers['X-XSS-Protection'] = '1; mode=block;'

- </code>

- 			</section>

- 			<section>

- 				<title>Content Security Policy (CSP)</title>

- 				<para>The trouble with XSS from a browser's perspective is that is difficult to distinguish between a script that's intended to be part of a web application and a script that has been injected by an attacker. Content Security Policy (CSP) is a standard that allows application developers to specify whitelists of trusted sources for their content.</para>

- 				<para>There are however some caveats to using this feature. In-lined content is considered harmful so all content must be loadable from an external source. This means that you cannot embed scripts and styles within HTML content.</para>

- <code>

- &#60;!--

-        You can no longer use inline content when working with CSP. 

-   This is an example of things that will no longer work. 

- --&#62;

- &#60;html&#62;

-   &#60;head&#62;

-     &#60;title&#62;Example&#60;/title&#62;

-     &#60;!-- 

-                All styles need to be loaded from an explicit source 

-       rather than being embedded in a page.

-     --&#62;

-     &#60;style&#62;

-       #foo {

-         padding-top: 2em;

-         margin-left: 1.5em;

-       };

-     &#60;/style&#62;

-   &#60;/head&#62;

-   &#60;body

-     &#60;div id="foo"&#62;

-       &#60;h1&#62;Example&#60;/h1&#62;

-       &#60;p&#62;

-         This is an example of the kind of things that you can no longer do. 

-         You can't invoke &#60;a id='say_hello' href="javascript:sayHello()"&#62;javascript via links&#60;/a&#62;

-         anymore. 

-       &#60;/p&#62;

-       &#60;p id="bad_style" style="color:red"&#62;

-         Inline styles are also prevented. 

-       &#60;/p&#62;

-     &#60;/div&#62;

-     

-     &#60;!-- 

-                All scripts need to be loaded from an explicit source rather 

-       than being embedded in a page.

-     --&#62;

-     &#60;script&#62;

-       function sayHello(){

-         alert("Hello world");

-       }

-     &#60;/script&#62;

-   &#60;/body&#62;

- &#60;/html&#62;

- </code>

- 				<para>Instead you should load content from an explicit source. For example the previous code snippet may be rewritten as follows.</para>

- <code>

- /* hello.css */

- #foo {

-   padding-top: 2em;

-   margin-left: 1.5em;

- }

- 

- #bad_style {

-   color: red;

- }

- </code>

- <code>

- // hello.js

- function sayHello(){

-   alert("Hello world");

- }

- 

- document.addEventListner('DOMContentLoaded', function(){

-   document.getElementById('say_hello').addEventListener('click', sayHello);

- });

- </code>

- <code>

- &#60;html&#62;

-   &#60;head&#62;

-     &#60;link rel="stylesheet" type="text/css" href="hello.css"&#62;

-   &#60;/head&#62;

-   &#60;body&#62;

-     &#60;div id="foo"&#62;

-       &#60;h1&#62;Example&#60;/h1&#62;

-       &#60;p&#62;

-         In this example the scripts and styles are loaded from 

-         an external source. The onclick event handler of &#60;a id='say_hello' href="#"&#62;this link&#60;/a&#62;

-         is handled by the external javascript source file.  This can be used with 

-         CSP. 

-       &#60;/p&#62;

-       &#60;p id="bad_style"&#62;

-         Similarly the style of this paragrah is managed by the external CSS source. This 

-         approach can also be used with CSP. 

-       &#60;/p&#62;

-     &#60;/div&#62;

-     &#60;script type="text/javascript" src="hello.js"&#62;&#60;/script&#62;

-   &#60;/body&#62;

- &#60;/html&#62;

- </code>

- 				<para>The content security policy can be set using the following headers:</para>

- <code>

- [options="header"]

- |===

- | Header | Browsers

- 

- | Content-Security-Policy 

- | Chrome 25+, Firefox 23+

- 

- | X-Content-Security-Policy

- | Firefox 4+, IE 10+ (partial)

- 

- | X-Webkit-CSP

- | Chrome 14+, Safari 6+

- 

- |===

- </code>

- <para>When specifying the header you can create a fine grained policy using a combination 

- of the following directives:</para>

- </code>

- [options="header"]

- |===

- | Directive | Description

- 

- | default-src

- | The default policy for loading all content such as images, scripts, stylesheets, 

- fonts etc. This can be used when a simple broad policy will apply for all content 

- within the web application. 

- 

- | script-src

- | Allows you to set policy around valid sources for Javascript content.

- 

- | object-src

- | Defines valid sources of plugins such as &#60;object&#62;, &#60;embed&#62;, and &#60;applet&#62;.  

- 

- | style-src

- | Allows you to set policy around valid sources for stylesheets. 

- 

- | img-src

- | Allows you to set policy around valid sources of images.

- 

- | media-src

- | Allows you to set policy around valid sources of HTML5 content like

- &#60;audio&#62; and &#60;video&#62;. 

- 

- | frame-src

- | Allows you to set policy around valid sources for loading frames. 

- 

- | font-src

- | Allows you to set policy around valid sources for loading fonts. 

- 

- | connect-src

- | Allows you to put restrictions on AJAX requests, websockets and 

- event source. 

- 

- | sandbox 

- | The sandbox feature allows further preventative restrictions to be 

- placed on the browser context. When specified it will have to most restrictive 

- environment enabled by default, and can disable sandboxing for specific 

- features that are required by the site.  

- 

- *allow-top-navigation*: If not specified along with the sandbox directive auxiliary browsing contexts will be disabled. Using target, window.open() or showModalDiaglog() will be blocked by the browser.  

- 

- *allow-same-origin*: If not specified along with the sandbox directive forces the content into a unique origin. Preventing it from accessing other content from the same origin. It also means that scripts will not be able to access document.cookie or local storage. 

- 

- *allow-forms*: If not specified along with the sandbox directive form submission will be blocked at the browser.

- 

- *allow-scripts*: If not specified with the sandbox directive then no scripts will be executed by the browser. 

- 

- | report-uri

- | CSP failures can be reported back to the application server. This directive allows you to 

- specify the URI to send the CSP report to.

- 

- 

- |===

- </code>

- <para>Most of these directives need to be applied to a source to be enforced by the browser. 

- The exceptions being the sandbox and report-uri directives which have their own special 

- purposes. For ther other directives you may enforce your whitelist by selective usage 

- of the following sources. </para>

- <code>

- [options="headers"]

- |===

- | Source | Description

- 

- | *

- | Wildcard will allow anything to be loaded for this directive.

- 

- | `none' 

- | Prevents loading the content from anywhere.  

- 

- | `self'

- | Restricts the content from being loaded from the same origin (host, scheme and port). 

- 

- | data

- | Allows content to be loaded via the data scheme. For example a base64 encoded img.

- 

- | hostname.example.com or *.example.com

- | Allows content to be loaded from the specified hostname. 

- 

- | https://cdn.example.com

- | An explicit URI to load content from.

- 

- |===

- </code>

- <para>

- Creating a policy requires knowing where your web assets are coming from and restricting 

- external sources as much as possible. Most web applications will be able to get away with

- disabling media, embedded content and frames entirely. The best way to retrofit a policy

- is to start in a restrictive mode, run your test suite and examine any reported CSP failures.  

- The following code snippet demonstrates how you might create a policy for browsers 

- supporting CSP. 

- </para>

- <code>

- [source,java]

- ----

- 

-   // Policy explicitly disables all content then selectively enables 

-   // features required by most modern sites. 

-   String policy = "default-src 'none';";

- 

-   // Enable 'self' for commonly directives. 

-   String[] directives = { 

-     "script-src", 

-     "connect-src", 

-     "img-src", 

-     "style-src"

-   };

- 

-   for (String directive : directives){

-     policy += String.format(" %s 'self';", directive);

-   }

-   

-   // Add appropriate header for browser

-   String userAgent = request.getHeader("user-agent");

-   Pattern chrome = Pattern.compile(" Chrome/([0-9]+)");

-   Matcher browser = null;

- 

-   if ((browser = chrome.matcher(userAgent)).find()){

-     int version = Integer.parseInt(browser.group(1));

-     if (version &#62;= 25){

-       response.addHeader("Content-Security-Policy", policy);

-     } else if (version &#60; 25 &#35;&#35; version &#62; 14){

-       response.addHeader("X-Webkit-CSP", policy);

-     } else {

-       log.debug("CSP not supported by : " + userAgent);

-     }

-   }

- 

-   // ... etc.

- 

- 

- ----

- </code>

- 			</section>

- 			<section>

- 				<title>Summary</title>

- 				<para>Using the CSP in conjunction with the aforementioned mitigation strategies is a really good defense in depth approach to reduce the likelihood of XSS attacks. The great thing is that it requires very little effort by web developers to get a substantial gain in security and therefore it is something that should be considered as a high priority for those looking to boost the security of their applications.</para>

- <note><title>TIP</title><para><simplelist>

- <member>Validate user input against a whitelist</member>

- <member>Escape user controlled input</member>

- <member>Monitor the use of HTTP parameters for signs of attacks.</member>

- <member>Use CSP to limit the trusted sources of scripts in your web application.</member>

- </simplelist></para></note>

- 			</section>

- 		</section>

- 	</section>

- 	<section>

- 		<title>Session Hijacking</title>

- 		<para />

- 		<section>

- 			<title>Overview</title>

- 			<para>A session hijacking attack is when an attacker manages to steal an existing 

- users session token and impersonate them when talking to the server. 

- Session Hijacking is one possible use of a XSS attack, although sessions may 

- be hijacked by other means. For instance, an attacker may construct a link that 

- pre-emptively sets a users session identifier to a known value which the user 

- then authenticates. Other attacks only require you to be logged into the 

- same network as the attacker and they can simply sniff the network traffic 

- to access your session token.</para>

- 

- 			<para>As a result it is essential to ensure all authenticated network traffic is 

- performed over a secure channel via TLS. Session tokens must be also transmitted 

- in a secure manner.</para>

- 		</section>

- 		<section>

- 			<title>Defending against Session Hijacking</title>

- 			<para />

- 			<section>

- 				<title>Use non-deterministic session identifiers</title>

- 				<para>Predictable session identifiers also be used in a session hijacking attack. An attacker 

- only has to guess a valid session identifier to impersonate a different user. Most 

- web frameworks already include a vetted session cookie implementation.  It is not

- recommended that you concoct your own session identification mechanism. It is however

- recommended that you verify that the session identifier is suitably random. A useful tool for doing this is called <ulink url="http://lcamtuf.coredump.cx/soft/stompy.tgz">Stompy</ulink>.</para>

- <para>Stompy is a command line entropy verifier for session cookies and XSRF tokens.</para>

- 

- <!--

- 

- .TODO

-   - Include stompy usage example?

- -->

- 			</section>

- 			<section>

- 				<title>Set the HTTP Only flag</title>

- 				<para>A good protective measure against session hijacking via XSS is to use 

- a session cookie that cannot be accessed by client side Javascript. This 

- is achieved by setting the HTTP only flag on the cookie.</para>

- 

- 				<para>For most web containers you can specify the following option in your web.xml file.</para>

- <code>

- [source,xml]

- ----

- ...

- 

-   &#60;session-config&#62;

-     &#60;cookie-config&#62;

-       &#60;http-only&#62;true&#60;/http-only&#62;

-     &#60;/cookie-config&#62;

-   &#60;/session-config&#62;

- 

- ...

- ----

- </code>

- <para>Of course the +HttpOnly+ flag can be set programmatically when 

- creating the cookie too.</para>

- 

- <code>

- [source,java]

- ----

-   response.addHeader("Set-Cookie", "foo=bar; HttpOnly;");

- ----

- </code>

- 			</section>

- 			<section>

- 				<title>Set the Secure Flag</title>

- 				<para>Setting the HttpOnly flag will prevent the session cookie from 

- being accessed via client side Javascript, but it doesn't protect the 

- token being transmitted over an insecure channel. Setting the +Secure+ 

- flag on the session cookie will tell the browser not to transmit the 

- cookie over an insecure channel.</para>

- 

- <para>Again, this can be done via the web containers web.xml file.</para>

- 

- <code>

- [source, xml]

- ----

- ...

- 

-   &#60;session-config&#62;

-     &#60;cookie-config&#62;

-       &#60;http-only&#62;true&#60;/http-only&#62;

-       &#60;secure&#62;true&#60;/secure&#62;

-     &#60;/cookie-config&#62;

-   &#60;/session-config&#62;

- ...

- 

- ----

- </code>

- <para>Or programatically.</para>

- <code>

- [source,java]

- ----

-   response.addHeader("Set-Cookie", "foo=bar; HttpOnly; Secure;");

- ----

- </code>

- 			</section>

- 			<section>

- 				<title>Strict transport security (HSTS)</title>

- 				<para>Taking this a step further, you should ensure that all authenticated 

- network traffic is sent via a TLS connection. Enabling HTTP Strict Transport

- Security informs compliant browsers to only interact with the web service 

- via a secure HTTPS connection. This protection mechanism is most effective 

- in preventing TLS stripping attacks and helps prevent hijacking by 

- ensuring a secure connection is always used with the server.</para>

- 

- 				<para>To enable HSTS you need only add a Strict-Transport-Security header to 

- client responses with a +max-age+ value in seconds. The +max-age+  

- attribute indicates to the browser how long it should honour the HTST 

- transport request.</para>

- 

- <code>

- [source,java]

- ----

-   ... 

-   response.addHeader("Strict-Transport-Security", "max-age=86400; includeSubdomains");

-   ...

- ----

- </code>

- 			</section>

- 		</section>

- 		<section>

- 			<title>Summary</title>

- 			<para>Using a combination of all these measures will help prevent the incidence of 

- session hijacking on your site.</para>

- 			<note><title>TIP</title><para><simplelist>

- <member>*DON'T* Use deterministic session identifiers</member>

- <member>*DON'T* Send a session identifier via a HTTP parameter or in the URI</member>

- <member>*DON'T* Allow client side Javascript to have access to the session token.</member>

- <member>*DON'T* Send session tokens over an insecure channel</member>

- <member>*DON'T* Allow authenticated content to travel via HTTP</member>

- </simplelist></para></note>

- 		</section>

- 	</section>

- 	<section>

- 		<title>Click Jacking</title>

- 		<para />

- 		<section>

- 			<title>Overview</title>

- 			<para>Click Jacking is when an attacker conceals the true nature of a site using 

- techniques as cursor spoofing or iframe overlays to trick a user into 

- clicking on a malicious link to perform unintended actions.</para>

- 		</section>

- 		<section>

- 			<title>Content Security Policy</title>

- 			<para>The &#60;&#60;_content_security_policy_csp, XSS section&#62;&#62; introduced 

- content security policy, and defining a tight CSP can also 

- help mitigate this class of attack.  W3C currently has 

- a link:https://www.w3.org/TR/UISafety/[working draft]

- of how CSP may be futher used to mitigate user interface redressing.</para>

- 		</section>

- 		<section>

- 			<title>X-Frame-Options</title>

- 			<para>It is common for this class of attack to use iframes to obscure the 

- actual nature of the site. The +X-Frame-Options+ header was introduced

- by Microsoft in IE8. It allows web application developers to prevent frame

- based UI redressing. All modern browsers now support this option so it 

- is worth turning on.</para>

- 

- There are three configuration options for this header. 

- [options="headers"]

- |===

- | Option | Description 

- 

- | DENY 

- | The page cannot be displayed in a frame, regardless of the site attempting to do so. 

- 

- | SAMEORIGIN

- | The page can only be displayed in a frame on the same origin as the

- page itself. 

- 

- | ALLOW-FROM uri

- | The page can only be displayed in a frame on the specified origin.

- |===

- 

- [source, java]

- ----

- 

- // prevent all frames

- response.addHeader("X-Frame-Options", "DENY");

- 

- // allow frames from same origin

- response.addHeader("X-Frame-Options", "SAMEORIGIN"); 

- 

- // allow frames from specific uri

- response.addHeader("X-Frame-Options", "ALLOW-FROM http://example.com"); 

- 

- ----

- 

- 

- === Confirmation 

- 

- It may sound simple but to protect against click jacking another 

- approach is to use +window.confirm()+ to notify the user of 

- the action they are about to perform. This is because it creates 

- a popup that cannot be framed and hidden by the attacker. 

- 

- === Summary 

- 

- Click Jacking can be serious and cause carnage to users of your site. It is worth 

- taking some basic precautions when creating your site. 

- 

- [TIP]

- ====

- * Set the X-Frame-Options header to +DENY+ unless frames are needed for the site.

- * Request user confirmation before attempting irreversible actions. 

- ====

- 

- 

- == Cross site request forgery (CSRF/XSRF)

- 

- === Overview 

- 

- A Cross site request forgery (CSRF) attack leverages an authenticated 

- users existing session to issue commands on their behalf.  This attack 

- generally involves some aspect of social engineering to get a user to click 

- on a malicious link on a third party site or email. The link is usually 

- specially crafted to execute business logic on a site for which the user 

- already has an authenticated session for.  

- 

- === CSRF Token

- 

- It is common for most web frameworks to include mechanism that creates a

- unique CSRF token for each request. The CSRF attack is thwarted by this 

- mechanism as the attacker cannot spoof the random value. 

- 

- 

- Starting from Seam 2.2.1 you can add a CSRF token to user forms as follows. 

- 

- [source, html]

- ----

- &#60;h:form&#62;

-   &#60;s:token/&#62;

-   ...

- &#60;/h:form&#62;

- 

- ----

- 

- Python Flask-WTF forms have CSRF token protection enabled by default. You need 

- only remember to include the hidden tags in your form template. This will 

- include the random _csrf_token. 

- 

- [source, html]

- ----

- &#60;form method="POST" action="/transfer"&#62;

-   {{ form.hidden_tag() }}

-   &#60;!-- Define the rest of form fields goes here --&#62;

-   &#60;button type="submit"&#62;Transfer funds&#60;/button&#62;

- &#60;/form&#62;

- 

- ----

- 

- [IMPORTANT]

- ====

- The CSRF token must be sufficiently random and non deterministic. This can 

- be confirmed by tools like Stompy. Again you should *NOT* try and implement

- your own CSRF mechanism.

- 

- ====

- 

- 

- === Referrer Header Checks

- 

- It is also difficult for an attacker to spoof the referrer header that 

- is sent by the browser in each request. It is therefore pertinent to 

- enable referrer checks within your web framework. These checks should 

- ensure that the request originated from the same origin as the website 

- executing the business logic. 

- 

- This technique can be effective but is not fool proof. Browsers and 

- proxies can be configured to strip the referrer header for privacy 

- reasons. It is therefore recommended to use this in conjunction with 

- CSRF tokens to counter this class of attack. 

- 

- If your framework does not include referrer checks you can add them 

- by comparing the schema, hostname and port of the web application 

- against the supplied referrer header. 

- 

- [source, python]

- ----

- # TODO (This is completely untested)

- from functools import wraps

- from urlparse import urlparse

- from flask import request, abort, render_template, redirect

- from forms import TransferForm

- from app import app 

- 

- # Referrer check decorator. Checks the referrer 

- # against the configured SERVER_NAME for the webapp. 

- def referrer_check(f)

-   @wraps(f)

-   def decorated(*args, **kwargs):

-     url = urlparse(request.referrer)

-     if url.netloc and not(url.netloc == app.config['SERVER_NAME']):

-       return abort(400)

-   return decorated

-       

- @referrer_check

- @app.route('/transfer', methods=[GET, POST])

- def transfer_funds():

-   form = TransferForm()

-   if form.validate_on_submit():

-     # process form

-     pass

-     return redirect('/')

- 

-   # Render form to user 

-   return render_template("transfer.html", form=form)

- 

- ----

- 

- 

- === Summary

- 

- CSRF attacks are common place but can be prevented by deploying a secure 

- random CSRF token on a per-request or per-session basis. When used in 

- conjunction with referrer header checks it is difficult for an attack 

- of this class to be successful. 

- 

- [TIP]

- ====

- * Enable a CSRF token for business logic. 

- * Ensure the CSRF token is non deterministic.

- * Enable referrer header checks in your web framework.

- 

- ====

- 

- == Remote code execution

- 

- === Overview 

- 

- Remote code execution is usually the ultimate goal 

- of most attacks. In 1996 when the infamous _Smashing the 

- stack for fun and for profit_ article hit Phrack magazine 

- this was achieved via buffer overruns and remote injection 

- of shell code. However more modern garbage collected languages

- aren't exempt from this category of attacks. There as still 

- many ways in which remote code can find its way into the 

- execution context of the application and cause unexpected 

- behaviours. This section covers some of the common 

- flaws in applications that can lead to remote code or command 

- execution. 

- 

- === Unsafe use of Serialization 

- 

- Serialization in both the Java and Python language can lead 

- to malicious code execution. Technologies such as Java 

- RMI rely on serialization so care needs to be taken when defining 

- and deserializing objects that could've been exploited by a remote 

- attacker. 

- 

- ==== When it comes to serialization consider practicing abstinence 

- 

- Generally speaking it is better to avoid serialization altogether and 

- fall back to a safer transport medium such as JSON to send messages 

- between services. JSON does not contain any features that would allow 

- an attacker to overwrite object code, and must be explicitly unpacked 

- to instantiate a remote object.. 

- 

- ==== Control the serialization process 

- 

- If serialization is an absolute must then there are several things that 

- you need to consider when developing your class.

- 

-   * Mark sensitive fields as transient

-   * Use serialPersistentFields to restrict serialized state

-   * Implement readObject, writeObject, and readObjectNoData methods with 

-     the following signatures: 

-      - private void writeObject(java.io.ObjectOutputStream out) throws IOException;

-      - private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

-      - private void readObjectNoData() throws ObjectStreamException;

-    

-   * Selectively deserialize each field using readField rather than readObject

-     from the ObjectInputStream.

-   * Ensure that the class is declared as final or has a private constructor that

-     performs a security check with the security manager. 

-   * Reduce privileges when deserializing objects from untrusted source

-   * Do not use public static nonfinal variables

-   * Always generate a unique serialization id for classes. 

-   * Don't serialize instances of inner classes

- 

- Even after taking these precautions it is still dangerous to 

- deserialize data that could be received from an external and 

- untrusted source.  

- 

- 

- === Abuse of JSP Expression Language (EL)  

- 

- The Java Expression Language provides a mechanism to dynamically access 

- Bean methods in the current scope and request context. Unfortunately 

- this capability can be abused if untrusted user input is not correctly 

- validated. 

- 

- A simple example of this attack would be to bypass HttpOnly flag of a 

- session cookie by injecting the EL expression +${cookie["JSESSIONID"].value}+. 

- 

- [source,html]

- ----

- &#60;!-- 

-      Consider what happens when any of these values are supplied 

- for the parameter without server side validation. 

-   http://example.com/?foo=${cookie["JSESSIONID"].value 

-   or 

-   http://example.com/?foo=${pageContext.request.getSession().setAttribute("admin", ture)}

- --&#62;

- 

- ...

- &#60;h:outputText value="${param.foo}" /&#62;

- ...

- 

- ----

- 

- To check for instances of EL injection vulnerabilities in your application 

- you should try a sending a token value for each request parameter that you 

- can check for in the resulting pages. For example you may send +${"IF_WE_FIND_THIS_VALUE_BAD_THINGS_COULD_HAPPEN"}+. If a generic error message or exception is thrown 

- then chances are the field may also be vulnerable to injection also. 

- 

- A simple way to protect against EL injection is to properly sanitize 

- user controlled input. You should restrict all parameters using a 

- whitelist that does not include the characters '$#{}'. A defense in depth 

- approach will also restrict the capabilities of the the EL interpreter using

- a Java security manager policy. 

- 

- .TODO 

-   - Run this by SRT. 

- 

- === Remote command execution 

- 

- Command injection occurs when user controlled input is passed 

- into a operating system command execution content or shell with

- proper sanitization.  

- 

- ==== Python command injection gotchas 

- 

- Python's subprocess module is somewhat impervious to command 

- injection however there are some use cases where unvalidated 

- user input could lead to a

- 

- ===== Injection is possible when shell=True 

- 

- Creating a subprocess in Python and setting the 

- shell setting to True can expose the application 

- to command injection attacks. If the application 

- does not escape or validate user input against a

- secure whitelist of values an attacker may execute 

- multiple commands. For example.

- 

- [source, python]

- ----

- def local_command_injection(cmd):

-   pipe = subprocess.PIPE

-   proc = subprocess.Popen([cmd], shell=True, stdin=pipe, stdout=pipe, stderr=pipe, close_fds=True)

-   proc.wait()

-   err = proc.stderr.read()

-   if err:

-     print(err)

-   else:

-     print(proc.stdout.read())

- 

- 

- # A contrived usage which constructs the command string without 

- # validating user input.

- user_input = ";cat /etc/passwd"

- vulnerable_command = "ls %s" % user_input

- local_command_injection(vulnerable_command)

- 

- ----

- 

- Where possible constructing a subprocess using shell=True 

- should be avoided. If it must be used then caution 

- must be taken to escape user controlled content. 

- 

- .TODO

-   - Safe example 

- 

- 

- ===== Injection is possible for commands run over ssh

- 

- Similarly, care needs to be taken when constructing command

- strings that would be executed on remote machines. The 

- following code snippet demonstrates how user controlled input

- could easily be executed using the Parmiko SSH library. 

- 

- [source, python]

- ----

- def remote_command_injection(host, port, cmd):

-   user = getpass.getuser()

-   passwd = getpass.getpass('Enter password for %s: ' % user)

-   client = paramiko.SSHClient()

-   client.load_system_host_keys()

-   client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

-   client.connect(host, username=user, password=passwd, port=port)

-   stdin, stdout, stderr = client.exec_command(cmd)

-   for line in stdout:

-     print '... ' + line.strip('\n')

- 

-   client.close()

- 

- # A contrived usage which constructs the command string without 

- # validating user input.

- user_input = ";cat /etc/passwd"

- vulnerable_command = "ls %s" % user_input

- remote_command_injection(vulnerable_command)

- 

- ----

- 

- To protect against this scenario it is necessary to either 

- escape user input using shlex.escape and/or use a whitelist 

- of allowed characters to restrict the user input. 

- 

- .TODO

-   - Safe example 

- 

- 

- ==== Java command injection gotchas

-   

- Java is at risk of command injection also. Again it comes back to 

- correctly sanitizing user input, and using a safe API where possible. 

- So instead of invoking something like +Runtime.getRuntime().exec(cmd + userArguments)+

- it would be better to use +ProcessBuilder+ to construct the command. 

- However all input that comes from an untrusted source should be validated 

- against a whitelist of safe characters that will not allow shell 

- escaping.

- 

- 

- ==== Explicit mapping of command arguments

- 

- To further reduce the likelihood of command injection attacks you can 

- restrict command line arguments to a predefined subset of values that 

- the user may select by an enumerated value. This prevents passing

- user controlled information directly to the command string.  

- 

- === Summary

- 

- It is difficult to construct applications that execute external commands 

- on the operating system. However if care is taken to limited the attack 

- surface and frequency of these types of calls then it is possible to 

- do it safely. 

- 

- The same care must be taken when leveraging serialization and expression language

- features of Java. Whilst using these language features can make program development 

- easier, it security implications associated with these capabilities also needs 

- some consideration. 

- 

- [TIP]

- ====

- * Choose a safe serialization mechanism such as JSON. 

- * Avoid using shell=True for Python subprocess 

- * Sanitize user input against a safe subset of characters that cannot be used 

- to have a side effect. 

- * Restrict the external commands that can be executed by the application. 

- * Favour libraries and SDK's over external command execution. 

- 

- ====

-   

- 

- == File system attacks

- 

- === Overview 

- 

- When accessing and manipulating file system objects there are several factors 

- that need to be considered. Python and Java are both cross platform environments and

- the discretionary access controls provided by operating systems alone do not 

- always provide adequate protection against certain classes of attacks. 

- 

- Typically an attacker will exploit unrestricted file system access within an 

- application,  inadequate file system permissions or time of check time of use (TOCTOU) 

- flaws within the application. All of these attacks can be mitigated by restricting

- the scope of file system access and creating files in a way that reduces the 

- chances of race conditions occurring. 

- 

- === Defeating path traversal 

- 

- A path traversal attack is when an attacker supplies input that is used 

- directly to access a file on the file system. The input usually attempts 

- to break out of the applications working directory and access a file elsewhere

- on the file system. 

- 

- [source, java]

- ----

- // Contrived example of how user input may be used to 

- // access unintended system files. 

-   

- File getFile(String filename) throws IOException {

-   return new File(userInput);

- }

- 

- // oops 

- String userInput = "../../../../../../../../etc/passwd";

- File f = getFile(userInput);

- 

- ----

- 

- There are a couple of ways that this can be prevented. The first 

- explicitly restricts file access to a known safe directory, the other

- is to only allow users to access files indirectly by using a enumerated 

- type to reference a particular known safe file. 

- 

- ==== Limiting file system access to specific safe directory

- 

- The key to preventing attackers from accessing external system files is

- to limit access to the file system to a known safe directory. To do this

- when the file name is directly supplied by user controlled input you *must* 

- process the file path in its canonical form. This means resolving all 

- directory switching and environment variables to get the absolute path 

- of the path string. You then should ensure that the absolute path 

- resides in the subset of paths that have the safe directory as the root. 

- 

- 

- Java provides the method +getCanonicalPath+ which will safely resolve 

- the absolute path based on the supplied input. This can then be used 

- to determine if the file resides within a safe directory.  

- 

- [source, java]

- ----

- 

- // This solution is suitable for the Java 1.6 and under. If you are 

- // using the Java 1.7 SDK you should consider the java.nio.file.Path

- // methods to resolve paths, and startsWith options. 

- 

- boolean isSafeFilePath(String safeDir,  String path) throws IOException {

-   return new File(path).getCanonicalPath().startsWith(safeDir);

- } 

- 

- File getFile(path){

-   if (isSafeFilePath("/var/www", userControlledInput)){

-     return new File(userControlledInput);

-   }

-   throw IOException("Attempted path traversal");

- }

- 

- ----

- 

- A similar feat can be achieved using Python. In this example you have 

- the option of resolving symbolic links to ensure that they cannot be 

- used to escape the supplied base directory. 

- 

- [source,python]

- ----

- import os

- 

- def is_safe_path(basedir, path, follow_symlinks=True):

- 

-   # resolves symbolic links

-   if follow_symlinks: 

-     return os.path.realpath(path).startswith(basedir)

- 

-   return os.path.abspath(path).startswith(basedir)

- 

- ----

- 

- 

- ==== Indirect file system object mapping

- 

- Another approach to restricting file system access to maintain an 

- indirect mapping between a unique identifier and a file path that 

- exists on the operating system. This prevents users supplying 

- malicious input to access unintended files. 

- 

- [source,python]

- ----

- 

- localfiles = {

-   "01" : "/var/www/img/001.png",

-   "02" : "/var/www/img/002.png",

-   "03" : "/var/www/img/003.png",

- }

- 

- # Will raise an error if an invalid key is used.

- def get_file(file_id):

-   return open(localfiles[file_id])

- 

- ----

- 

- === Safely creating temporary files and directories.

- 

- On most systems the temporary directory provides a shared location that

- can be used to create temporary files that can be purged periodically 

- or on system restart. This is beneficial for applications performing 

- some operation that may or may not succeed and to prevent leaving 

- dangling files all over the file system. 

- 

- However there is also the problem that this is infact a shared area. 

- This means that an attacker may premptively or actively exploit a 

- race condition to substitue a file for their own. Resulting in 

- the injection of untrusted content in your application, or reading or 

- writing of a file with escalated priviledges.

- 

- TOCTOU attacks exist because programmers continually create files 

- in a shared directory with a predictable path and / or insufficient 

- priviledges. Both the Java(1.7) and Python programming environments provide 

- a API that will create a temporary file or directory in a secure manner.  

- 

- 

- [source, java]

- ----

- // Unfortunately prior to Java 1.7 there was no standard way to create a file 

- // with exlcusive write access and set the default permissions. Therefore even 

- // using +File.createTempFile+ to create a file with a random file name 

- // it does not ensure that the file was created exclusively 

- // with restrictive permissions and cannot be trusted.

- //

- // Java 7 contains features within the java.nio to securely create a 

- // temporary file atomically and set the permissions at the same time.

- 

- import java.nio.file.FileSystems;

- 

- // Securely creating a temporary file in Java 1.7

- import java.nio.file.Files;

- 

- // Restrict read / write to current user only.

- Set&#60;PosixFilePermssions&#62; perms = PosixFilePermissions.fromString("rw-------")

- 

- String prefix = null; // use default

- String suffix = null; // use default

- 

- // Create a temporary file

- Path file = Files.createTempFile(prefix, suffix, PosixFilePermissions.asFileAttributes(perms));

- 

- // Create a temporary directory 

- Path dir = Files.createTempDirectory(prefix, PosixFilePermissions.asFileAttributes(perms));

- 

- ----

- 

- The Python solution is a little bit less verbose. 

- 

- [source, python]

- ----

- import tempfile

- 

- # Securely creating a temporary file in Python

- file = tempfile.mkstemp()

- 

- # Securely creating a temporary directory in Python

- dir = tempfile.mkdtemp()

- 

- ----

- 

- Whilst both these mechanisms are safe it is worth mentioning that

- temporary file usage should also used sparingly where possible. 

- 

- 

- == XML attacks

- 

- === Overview 

- 

- XML is used extensively in Java EE, unfortunately it has serveral weak points 

- from a security perspective. Not all of these are faults of the programmer, some 

- of these are flaws in XML's design.

- 

- === Importance of schema validation 

- 

- XML like many topics covered previously in this document is also susceptable to 

- injection attacks. It is also prone to attacks focused on algorithmic exhautation 

- and denial of service. Both of these problems originate from problems in parsing 

- the XML content. 

- 

- There are generally two camps when it comes to XML parsers. 

- The first is a stream parser that interprets the XML code on the fly whilst maintaining

- state around nesting tags and attributes. This event driven approach typically feeds 

- nodes to callback functions to yield values from the XML content.  Without schema 

- validation this approach is susceptible to XML injection attacks. If an attacker 

- is able to inject a node into the document structure values can be overwritten 

- as the SAX parser will process the document on the fly. 

- 

- [source, xml]

- ----

- 

- &#60;account&#62;

-   &#60;username&#62;fred&#60;/username&#62;

-   &#60;roles&#62;

-     &#60;role&#62;staff&#60;/role&#62;

-   &#60;/roles&#62;

- 

-   &#60;!-- Consider what would happend if the 

-            following user controlled input is supplied for nickname.

-     &#60;/nickname&#62;&#60;roles&#62;&#60;role&#62;admin&#60;/role&#62;&#60;/roles&#62;&#60;nickname&#62;freddie

-   --&#62;

-   &#60;nickname&#62;

-     {{ user_controlled_input }}

-   &#60;/nickname&#62;

- &#60;/account&#62;

- 

- ----

- 

- The alternative approach is to make a full parse of the XML document and use a 

- document object model to represent the entire document. Without validation 

- and other checks this approach can be vulnerable to resource exhaustation 

- attacks. The XML document may have been maliciously contructed to exhaust the

- stack limit or system memory to cause a denial of service of a remote 

- service. 

- 

- By validating the XML document against a known good DTD or schema, as well 

- as placing some common sense limits on the XML document size being processed 

- these types of attacks can be circumvented. 

- 

- 

- 

- [source, java]

- ----

- 

- SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

- Schema schema = schemaFactory.newSchema(new File("schema.xsd"));

- 

- try {

-   schema.newValidator().validate(xmlContent);

-   // XML is in format defined by schema.xsd

- 

- } catch (SAXException e){

-   // XML is invalid. Do not try to process it any further.

- }

- 

- 

- ----

- 

- 

- === Defending XML entity attacks 

- 

- ==== Malicious entity expansion

- 

- 

- XML is susceptable to a denial of service attack through entity expansion.  

- The following is an example of the infamous billion laughs attack where it 

- uses entity recursion to expand a small XML document to a huge size. 

- 

- 

- [source, xml]

- ----

- &#60;!-- billion lolz attack --&#62;

- &#60;?xml version="1.0"?&#62;

- &#60;!DOCTYPE lolz [

- &#60;!ENTITY lol "lol"&#62;

- &#60;!ELEMENT lolz (#PCDATA)&#62;

- &#60;!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"&#62;

- &#60;!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"&#62;

- &#60;!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"&#62;

- &#60;!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"&#62;

- &#60;!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"&#62;

- &#60;!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"&#62;

- &#60;!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"&#62;

- &#60;!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"&#62;

- &#60;!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"&#62;

- ]&#62;

- &#60;lolz&#62;&lol9;&#60;/lolz&#62;

- ----

- 

- To protect against entity expansion in JAXP 1.3 you will need to turn on 

- the secure processing feature to set a limit for the DOM and SAX parsers. 

- 

-   entityExpansionLimit = 64,000;

-   elementAttributeLimit = 10,000;

- 

- However you will need to enable this feature explicitly: 

- 

- [source,java]

- ----

-   SAXParserFactory spf = SAXParserFactory.newInstance();

-   spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

- ----

- 

- In JAXP 1.4 the secure processing feature is turned on by default. 

- You can also set these limits using system properties. For example

- if you wanted to apply something more restrictive across the board 

- you could do start your process with the flag +-DentityExpansionLimit=10+ 

- or explicitly set it in your application: 

- 

- [source,java]

- ----

- System.setProperty("entityExpansionLimit", "10");

- 

- ----

- 

- 

- ==== Unauthorized file access through external entities

- 

- Another way in which a XML entity tag can be abused is by accessing 

- local or remote content. 

- 

- [source,xml]

- ----

- 

- &#60;?xml version="1.0" encoding="ISO-8859-1"?&#62;

- &#60;!DOCTYPE foo [  

-   &#60;!ELEMENT foo ANY &#62;

-   &#60;!ENTITY xxe SYSTEM "file:///etc/passwd" &#62;]&#62;

-   &#60;foo&#62;&xxe;&#60;/foo&#62;

- ----

- 

- 

- To prevent this class of attack you should use your own custom 

- resolver. 

- 

- [source, java]

- ----

- 

- public class RestrictedEntityResolver implements EntityResolver {

- 

-   private static final String EXTERNAL_ENTITY_DIR = "/usr/share/example/xml";

- 

-   public InputSource resolveEntity(String publicId, String systemId)

-     throws SAXException, IOException {

- 

-     // Example restricting external entities to safe directory

-     String resolvedPath = new File(systemId).canonicalPath();

-     if (resolvedPath.startsWith(EXTERNAL_ENTITY_DIR)){

-       return new InputSource(resolvedPath);

-     }

- 

-     // Return empty InputSource which will cause malformed url exception 

-     return new InputSource();

-     

-   }

- }

- 

- 

- // The resolver can then be used with an XML reader to 

- // limit access to external entities.

- SAXParser parser = spf.newSAXParser();

- XMLReader reader = parser.getXMLReader();

- reader.setEntityResolver(new RestrictedEntityResolver());

- reader.parse(new InputSource(input));

- 

- ----

- 

- 

- 

- === Detecting XML deserialization attacks

- 

- .TODO 

-  - http://blog.diniscruz.com/2013/08/using-xmldecoder-to-execute-server-side.html

- 

- 

- 

- == Redirection attacks

- 

- === Overview 

- 

- It is common to redirect a user after form submission. However in 

- some cases developers achieve this by using a URL parameter that 

- could be manipulated by an attacker. An attacker may manipulate the 

- redirection URL to trick a victim into entering their username 

- and password to a fake login dialog. 

- 

- === Validating redirects

- 

- An example of how an attacker may exploit URL redirects:

-     https://www.example.com/login.php?next=http://attacker.com/phonylogin.php

- 

- To counter this type of attack redirects need to be validated before 

- redirecting the user to an external site. Essentially 

- you should confirm that the redirection will take the user

- to another page within your site. 

- 

- [source, java]

- ----

- static String safeRedirect(URI baseUrl,  String target){

- 

-     try {

- 

-       URI redirect = URI.create(target).normalize();

- 

-       // Relative redirect

-       if (! redirect.isAbsolute()){

-         return new URI(baseUrl.getScheme(),

-           baseUrl.getUserInfo(),

-           baseUrl.getHost(),

-           baseUrl.getPort(),

-           redirect.getPath(),

-           redirect.getQuery(),

-           redirect.getFragment()).normalize().toString();

-       }

- 

-       // Assert that normalized URI hostname, port and scheme match

-       if (baseUrl.getHost().equals(redirect.getHost())

-         &#35;&#35; baseUrl.getPort() == redirect.getPort()

-         &#35;&#35; baseUrl.getScheme().equals(redirect.getScheme())){

- 

-         return redirect.toString();

-       }

- 

-     } catch (Exception e){

-     }

- 

-   // or Redirect to default base URL

-   return baseUrl.toString();

- }

- 

- 

- String redirect = safeRedirect(URI.create("https://example.com"), request.getParameter("next"));

- response.sendRedirect(redirect);

- 

- ----

- 

- === Summary 

- 

- [TIP]

- ====

- * Validate all redirects performed by your web application

- * Warn the user when redirecting them to a site outside the hosted web application.

- ====

- 

- 

- == SQL injection 

- 

- === Overview 

- 

- SQL injection is a well known vulnerability that may be exploited when a programmer

- does not safely construct a database query from user supplied data. This problem is

- well known within industry yet it still has high incidence. 

- 

- A classic SQL injection may occur when concatenating or interpolating user input 

- when construction a query string as follows: 

- 

- [source, java]

- ----

- 

- // User controlled

- String username = "admin' OR '1' ='1";

- String password = "";

- 

- boolean login(String username, String password){

- 

-   // Constructing query string

-   String sql = "SELECT * FROM user where username='" 

-     + username + "' and password='" + password + "'";

- 

-   ResultSet rs = db.createStatement().executeQuery(sql);

-   return rs.next() != null;

- 

- }

- 

- ----

- 

- To prevent this type of attack you should always use parameterised queries 

- and validate user input against a whitelist of safe characters. You should 

- *NEVER* construct a SQL query using concatenation or interpolation. 

- 

- === Use JBDC Prepared statements 

- 

- When accessing a SQL database using JDBC it is essential that you use parameterized 

- queries. This prevents injection attacks as all parameters are safely escaped when

- a value is set for them. A parameterized query means that placeholders are used 

- when declaring the initial SQL statement, these placeholders are then substituted

- for a typesafe variable at runtime. 

- 

- [source, java]

- ----

- PreparedStatement findAllEmployeesByFirstName = null;

- 

- try {

-   

-   // ? is the parameter that will be substituted  

-   String queryString = "SELECT * FROM Employee WHERE firstName = ?";

-   findAllEmployeesByFirstName = conn.prepareStatement(queryString);

- 

-   // The value for the parameter is explicitly set 

-   findAllEmployeesByFirstName.set(1, userControlledInput);

- 

-   ResultSet rs = findAllEmployeesByFirstName.executeQuery();

-   // Process results ... 

- 

- } catch (SQLException e){

-   System.err.println(e.toString());

- } finally {

-   if (findAllEmployeesByFirstName != null){

-     findAllEmployeesByFirstName.close();  

-   }

- }

- 

- ----

- 

- Using a prepared statement in this way prevents injection as each parameter 

- is escaped when constructing the query string. It also provides an element 

- of type safety to ensure that supplied parameters are of the correct type.

- 

- 

- === Use JPA named queries

- 

- The Java Persistence API provides a similar mechanism for creating parameterized 

- queries. The best practice is to use named queries to restrict the way in which 

- the database may be accessed. It also prevents dynamic construction of query strings. 

- 

- [source,java]

- ----

- // Parameter :firstname will be safely escaped in this query.

- @Entity 

- @NamedQuery(

-   name="findAllEmployeesByFirstName", 

-   queryString="SELECT OBJECT(emp) FROM Employee emp WHERE emp.firstName = :firstname"

- )

- public final class Employee implements Serializable {

- ...

- }

- 

- Query queryEmployeesByFirstName = em.createNamedQuery("findAllEmployeesByFirstName");

- queryEmployeesByFirstName.setParameter("firstname", userInput);

- Collection employees = queryEmployeesByFirstName.getResultList();

- 

- ----

- 

- In a similar fashion to JDBC parameterized queries using named parameters will 

- prevent SQL injection and is the preferred approach over dynamically generating

- queries by concatenating user input. 

- 

- 

- === Stored Procedures

- .TODO

-   - Decide if I want to keep /add this..

- 

- === Summary

- 

- SQL injection can be easily avoided by using safer libraries and frameworks to 

- access the database. All user input should be properly sanitized before constructing

- SQL statements from it. 

- 

- 

- [TIP]

- ====

-   * Beware string concatenation and interpolation 

-   * Use prepared statements in JDBC

-   * Hibernate and JPA

-   * Stored procedures

-   * Use SQLAlchemy in Python

- 

- ====

- == Session management

- 

- === Overview

- 

- Attackers commonly attempt to exploit the improper use and protection of 

- session identifiers. Deploying and using sessions correctly is therefore 

- essential to securing your web application.

- 

- === Session Fixation 

- 

- Session fixation occurs when an attacker supplies an valid session identifier

- to a user and tricks them into authenticating that session when they login. 

- To prevent this class of attack you need to ensure that a new session identifier

- is generated for each logon. Any supplied session identifier should be discarded. 

- 

- === Session Lifecycle

- 

- The lifetime of sessions needs to be tightly managed. A session should have an 

- expiry and idle timeout. Ensure that your +web.xml+ sets a +session-timeout+ for 

- Java EE applications. It is also vital to invalidate a session when a user logs out. 

- Ensure that +session.invalidate()+ is called in all places where the user can 

- logout of the application.

- 

- === Insecure session identifiers 

- 

- A session identifier must be non-deterministic, bound to client

- properties, and provide non-repudiation. If the session identifier 

- does not possess these qualities it may be subject to a number of 

- attack vectors. 

- 

- If for example an web application uses an incremental number to 

- maintain state for each client then it is trivial for an attacker

- to simply guess the correct session identifier to impersonate 

- a user. You should always use the session management mechanism provided by

- your application container rather than using your own implementation. 

- 

- If you are using client side sessions then should be digitally 

- signed on the server to ensure that a malicious attacker cannot 

- tamper with session information in a request. This is not a common

- approach in the JavaEE applications however it is common in Python. 

- An additional technique is to bind a session to client properties 

- such as the user agent. This can be useful in detecting anomalies 

- in the middle of an established session and acting accordingly however 

- it is more of an obstacle for an attack not a prevention mechanism. 

- 

- 

- === Insecure transmission of session data

- 

- This has already been touched on in the &#60;&#60;_session_hijacking, session hijacking&#62;&#62;

- section. To reiterate the main points: 

- 

-   * Session data should *ALWAYS* be transmitted over a secure channel. 

-   * Session data should *NEVER* be passed in the URL as a HTTP parameter.  

-   * Session data should not be accessible via client side scripts. 

- 

- === Summary

- 

- Most web containers if up to date should have a pretty solid session management

- capabilities built in so it is essential that they are deployed and utilized 

- correctly. 

- 

- [TIP]

- ====

- - Ensure your session identifier is sufficiently random

- - Ensure session data cannot be tampered with on the client side. 

- - Ensure session tokens are only sent over a secure 

- 

- ====

- 

- 

- == Input validation 

- 

- === Overview

- 

- The majority of attacks covered in this guide can be traced back to the 

- unsafe processing and use of user input. This section intends to focus on the 

- merits of having a strong input validation ethos in your web application 

- development projects. Applications need to set stringent guidelines that

- dictate on what terms data may cross a trust boundary and become part of 

- the application state.

- 

- === Whitelists and Blacklists

- 

- A blacklist can be used to filter input by trying to filter out or reject

- input that contains banned characters. This may be implemented as a 

- regular expression or just a list of banned character sequences. 

- 

- [source,java]

- ----

- 

- // NOTE: A case is intentionally missed in this list

- private static final PATH_BLACKLIST = "^.*[./].*$";

- 

- String input = "../../../../../../../../etc/passwd";

- if (input.matches(PATH_BLACKLIST)){

-   // ERROR reject input

-   throw new InvalidInputException(input);

- } 

- 

- // Do something with input

- ----

- 

- The trouble with blacklists as is demonstrated in the code snippet above 

- is that the list may miss a corner case that allows a protected code path 

- to still be executed. (The blacklist in the example above does not include

- a path separator character for the Windows platform). A much safer approach 

- is to flip the usage to define what constitutes safe input and reject everything

- else. For instance if you are expecting a value for a phone number you might 

- restrict input to 10 digits.

- 

- [source,java]

- ----

-   private static final PHONE_NUMBER_WHITELIST = "^\d{10}$+";

-   if (input.matches(PHONE_NUMBER_WHITELIST)){

-     // Valid input continue processing

-     return;

-   }

- 

-   // All other cases are rejcted as invalid

-   throw new InputInputException(input);

- 

- ----

- 

- === Form validation

- 

- ==== Seam validation framework

- 

- http://docs.jboss.org/seam/latest/reference/html/validation.html

- 

- === GWT validation 

- 

- http://www.gwtproject.org/doc/latest/DevGuideValidation.html

- 

- ==== Python WTForms

-   

- The wtforms module comes with several default validators that can 

- be used to ensure that invalid form data is rejected. 

- 

- [options="headers"]

- |===

- | Validator | Description 

- 

- | Required 

- | Ensures that data has been provided for this form field. 

- 

- | Email 

- | Ensures the form field is a valid email address.

- 

- | EqualTo 

- | Ensures that the value of this form field equals the value supplied 

- for another form field. This is useful for confirmation fields.

- 

- | IPAddress

- | Ensures that the form field is a valid IP address (either ipv4 or ipv6).

- 

- | Length

- | Limits the input for the field to a specific length range. 

- 

- | MacAddress

- | Expects the form field to contain a valid mac address. 

- 

- | NumberRange

- | Expects the form field contain a value within a specific number range.

- 

- | Regexp

- | Allows you to specify a regular expression. Useful for specifying 

- a whitelist to validate user information.

- 

- | URL 

- | Expects a valid URL in the form field. 

- 

- | UUID

- | Expects a valid UUID to be specifiied in the form field.

- 

- | AnyOf

- | Expects the form field to contain a value matchin any of a values 

- in the supplied list.

- 

- | NoneOf

- | Expects that the form field won't match any value in the supplied list 

- of values.

- 

- |===

- 

- When defining a form using wtforms you should always ensure that the 

- validation rules mirror the restrictions that are in place for the 

- database. For example a MySQL schema requires hard limits on VARCHAR 

- columns, so the corresponding form field should use the +Length+ validator

- to enforce that limitation. 

- 

- Custom validation is also possible with wtforms. This can be achieved by 

- implementing a +validate_x+ method in your form class where +x+ is the 

- name of a form field to validate. You can also implement inline checks. 

- 

- [source, python]

- ----

- 

- # A custom validator that checks password strength

- def password_strength_check(form, field):

-   """ password must contain of uppercase, lowercase, digit and symbol """

-   return \

-     any((sym in string.ascii_uppercase) for c in field.data) and

-     any((sym in string.ascii_lowercase) for c in field.data) and

-     any((sym in string.digits) for c in field.data) and 

-     any((sym in """!@#$%^&#35;*()-_+={}[]\|;:'"/?.&#62;,&#60;`~""".split()) for c in field)

- 

- 

- # Form definition for user registration.

- class RegisterForm(RedirectForm):

- 

-   # Name field has validators to restrict length, and restricted to 

-   # have only characters that are valid for a persons name. 

-   name = TextField('Name', 

-     [ 

-       Required(), 

-       Regexp(whitelists.IDENTITY_WHITELIST), 

-       Length(min=3, max=constants.MAX_NAME_LENGTH) 

-     ])

- 

-   # Using default email validator along with length restrictions.

-   email = TextField('Email address', 

-     [

-       Required(),

-       Email(),

-       Length(max=constants.MAX_EMAIL_LENGTH)

-     ])

- 

-   # Password field has a restricted minimum length

-   # and also uses a custom validator (password_strength_check) 

-   # to check the password complexity. 

-   password = PasswordField('Password', 

-     [

-       Required(),

-       Length(min=constants.MIN_PASSWORD_LENGTH, max=constants.MAX_PASSWORD_LENGTH), 

-       password_strength_check

-     ])

- 

-   # Confirmation validator is used to make sure 

-   # password entered matches. 

-   confirm = PasswordField('Repeat Password', 

-     [

-       Required(),

-       EqualTo('password', message="Passwords must match")

-     ])

- 

- ----

- 

- 

- === Database validation

- 

- ==== Input validation with Hibernate 

- 

-   * Database Java   - Hibernate validation 

- 

- ==== Input validation with SQLAlchemy

- 

- Input validation can also be enforced at the database layer 

- of your application. SQLAlchemy includes a validates decorator 

- that can be used in your ORM definition. 

- 

- [source, python]

- ----

- 

- from sqlalchemy.orm import validates

- ...

- 

- class User(Base):

-   id = Column(Integer, primary_key=True)

-   email = Column(String)

-   #...

- 

-   # Custom email validation for the supplied field.

-   @validates('email')

-   def validate_email(self, key, address):

-     assert '@' in address

-     return address

- 

- 

- ----

- 

- === Validating data exchange formats 

- 

- ==== JSON schema validation

- 

- JSON is a dominant format for interacting with RESTful API's. An effort to introduce 

- a standard form of schema validation link:http://json-schema.org/examples.html[is underway].

- 

- The link:https://github.com/Julian/jsonschema[jsonschema] module 

- implements full support of Draft3 and Draft4 of the standard. 

- It can be used to enforce type safety and input validation 

- and is recommended for defining and checking API entrypoints

- for any RESTful web services. 

- 

- [options="header"]

- |===

- | Validator | Description | Works on 

- 

- |multipleOf

- |Expects a number which is a multiple of the 

- supplied constraint. 

- 

- +jsonschema.validate(32, {"multipleOf", 2})+

- 

- | +number+

- 

- |maximum and exclusiveMaximum

- |Sets a maximum value for a number field.

- +jsonschema.validate(101, {"maximum", 100})+

- | +number+

- 

- |minimum and exclusiveMinimum

- |Sets a minimum value required for a number field.  

- +jsonschema.validate(0, { "minimum", 21})+

- | +number+

- 

- |maxLength 

- |Checks that the supplied string is at most N characters

- long. +jsonschema.validate("The F word", {"maxLength": 4})

- | +string+

- 

- |minLength

- |Checks that the supplied string is at least N characters 

- long. +jsonschema.validate("foo", {"minLength" : 6 })+

- | +string+

- 

- |pattern

- |Validate using a regular expression in ECMA 262 format. 

- +jsonschema.validate("aardvark", {"pattern" : "^aa.*$" })+

- | +string+

- 

- |additionalItems and items

- | The +items+ validator allows you to apply validation rules 

- over an entire array. This may be to ensure that each item 

- is of a specific type or only a subset of values. The additionalItems

- allows the array to contain supplementary values to be included 

- at the end of the array.  

- 

- This would fail validation as it contains an additional 

- entry over the defined schema.

- 

- +jsonschema.validate([1, 2, "This is a string"], {

-   "items" : [

-       { "type" : "number" },

-       { "type" : "number" }

-     ] 

-   })+

- 

- To allow additional data at the end of the 

- array you need to specify +additionalData = True+. 

- 

- | +array+

- 

- |maxItems

- |Sets a hard limit on the maximum number of items that can be 

- supplied.

- +jsonschema.validate([1, 2, 3], { "maxItems" : 3 })+

- | +array+

- 

- |minItems

- |Sets a hard limit on the minumum number of items that can be 

- supplied. 

- +jsonschema.validate([1, 2, 3], { "minItems" : 1 })+

- | +array+

- 

- |uniqueItems

- |True of false value to indicate that all items in the array must

- be unique. 

- +jsonschema.validate([1, 2, 2], { "uniqueItems" : true })

- | +array+

- 

- |maxProperties

- |Validates that an object has at most N properties. 

- +jsonschema.validate({'name' : 'bob', 'age' : 21 }, { "maxProperties" : 2 })+

- | +object+

- 

- |minProperties

- |Validates that an object has at least N properties. 

- +jsonschema.validate({'name' : 'bob', 'age' : 21 }, { "minProperties" : 2 })+

- | +object+

- 

- |required

- |Dictates which properties an object must possess. Should be specified as 

- a list of objects. 

- 

- +jsonschema.validate({ 'firstname' : 'bob', 'lastname' : 'marley' }, { 'required' : ['firstname', 'lastname']})+

- |+object+

- 

- |additionalProperties, properties and patternProperties

- | Checks an object for the supplied properties. A property name

- may be matched by a pattern or explicitly. The additionalProperties

- attribute can restrict or allow additional properties to exist within

- the object. 

- |

- 

- 

- |dependencies

- |

- |

- 

- |enum 

- |

- |

- 

- |type

- |Defines the basic types that instances can take. 

- * object

- * array

- * string

- * number

- * boolean

- * null

- * any

- +jsonschema.validate("foo", { "type" : "string" })+

- | +any+

- 

- |allOf

- |Provides a list of schema's that a value must adhere to. 

- It is a way to separate schema's into separate definitions 

- and use all of them to validate a value.

- +jsonschema.validate("foo", { 

-   "allOf" : [ 

-     { "title" : "first schema", "type" : "string"}, 

-     { "title": "second schema", "minLength" : 3 }

-   ]})+

- | +any+

- 

- |anyOf

- |Requires that at least one of the provided schema's apply 

- to the value being validated. 

- +jsonschema.validate("foo", { 

-   "anyOf" : [ 

-     { "title" : "first schema", "type" : "string"}, 

-     { "title": "second schema", "minLength" : 5 }

-   ]})+

- | +any+

- 

- 

- |oneOf

- |Requires that *EXACTLY* one of the provided schema's 

- apply to the value being validated.

- 

- +jsonschema.validate("foo", { 

-   "oneOf" : [ 

-     { "title": "[on]", "properties": { "status" : {"enum" : [True]} }},

-     { "title": "[off]", "properties": { "status" : {"enum" : [False]} }}

-   ]})+

- |+any+

- 

- 

- |not

- |Negates the validation result of the supplied schema.

- +jsonschema.validate(1, { "not" : { "type" : "number" } })+

- |+any+

- 

- 

- |format

- | There are several useful built-in format verification

- attributes that can be applied to a value. These include:

- * date-time

- * email

- * hostname

- * ipv4

- * ipv6

- * uri

- 

- +jsonschema.validate("user@example.com", {"format", "email"})+

- | +string+

- 

- 

- |===

- 

- Bringing all of this together allows you to safely define 

- a the constraints and expectations around your API usage. 

- When the schema is defined it dramatically reduces the 

- complexity associated with validating an inbound request.  

- 

- [source, python]

- ----

- def validate_person(data):

- 

-   # Could externally define and document 

-   # expected request format for each API call

-   Person = {

-     "properties": {

-       "firstname" : {

-         "type"      : "string", 

-         "minLength" : 2,

-         "pattern"   : "^[A-Za-z]+$"

-       }, 

-       "lastname"  : {

-         "type"      : "string", 

-         "minLength  : 2,

-         "pattern"   : "^[A-Za-z]+$"

-       }, 

-       "age"       : {

-         "type"    : "number", 

-         "minimum" : 0,

-         "maximum" : 150, 

-       }, 

-       additionProperties : False

-     }

-   }

-   return jsonschema.validate(data, Person)

- 

- 

- @app.route("/person", methods=["POST"])

- def create_person():

- 

-   if not request.json: 

-     return abort(400)

- 

-   try: 

-     validate_person(request.json)

-     id = save_person(request.json)

-     return jsonify(status="success", id=id)

- 

-   except Exception as e: 

-     return  jsonify(status="error", message=str(e)), 400 

-     

- ----

- 

- 

- 

- ==== XML schema validation 

- 

- The &#60;&#60;_importance_of_schema_validation,importance of XML schema validation&#62;&#62; 

- has already been touched on in this guide. To summarize you should explicitly 

- validate XML input against a xsd to ensure it is a valid document. 

- 

- 

- === Summary

- 

- Input validation should be considered a high priority activity 

- when developing web applications. Having strict constraints on the 

- type of input that can cross a trust boundary will help prevent 

- applications being exploited by attackers.

- 

- You should try to identify your applications attack surface and 

- ensure that all input that comes from an external source is correctly

- validated before allowing your application to interact with it. 

- 

- [TIP]

- ====

- * Validate all fields when processing user forms

- * Ensure the database constraints are protected by input validation

- * Validate all input at API boundaries

- * Use whitelists to define what input is valid and reject everything else.  

- ====

- 

- 

- == Output escaping and encoding 

- 

-   * Safely escaping and encoding

- 

- == Authentication and Authorization

- 

-   * JAAS

-   * JBoss declarative security 

-   * Federated authentication

-   * LDAP authentication

-   * Kerberos authentication

- 

- == Deployment issues

- 

-   * Incorrectly configured TLS and keystores

-   * Deploying using known vulnerable artifacts

-   * Beward the risks of embedded dependencies

- === 

- 

- 

- === Environment Hardening 

- 

- A good defensive strategy for command or code injection is to 

- reduce the attack surface and limit exposure of the application 

- as much as possible. 

- 

-   * Linux containers and SELinux

-   * Java security policy

- 

- === Summary

- 

- .TODO

-   - Insert summary here. 

- 

-  

- == Verifying application correctness

- 

-   * OWASP application verification standard.

- 

- == Supporting libraries &#35; tools

- 

-   * OWASP ESAPI

-   * OWASP AntiSammy

-   * OWASP CSRF Guard Project

-   * Picketbox 

-   * Apache Santuario  

-   * Apache Shiro

-   * Bouncy Castle

-   * Checker framework (@Tainted)

-   * Google Guava Libraries 

-     - Using and avoiding null 

-     - Preconditions

-     - Immutable Collections

-   * Java Simplified Encryption - jasypt

-   * Coverity security library - https://github.com/coverity/coverity-security-library

-   * Coverty scanner

-   * Findbugs 

-   * Web application firewall  

-   *

- 

- 

- </chapter>

- 

en-US/entities.adoc
file added
+6
@@ -0,0 +1,6 @@

+ 

+ :HOLDER: Red Hat, Inc

+ 

+ :YEAR: 2012-2018

+ 

+ :nbsp:  

en-US/images/icon.svg
file removed
-3936
@@ -1,3936 +0,0 @@

- <?xml version="1.0" encoding="UTF-8" standalone="no"?>

- <!-- Created with Inkscape (http://www.inkscape.org/) -->

- <svg

-    xmlns:ns="http://ns.adobe.com/AdobeSVGViewerExtensions/3/"

-    xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"

-    xmlns:dc="http://purl.org/dc/elements/1.1/"

-    xmlns:cc="http://web.resource.org/cc/"

-    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

-    xmlns:svg="http://www.w3.org/2000/svg"

-    xmlns="http://www.w3.org/2000/svg"

-    xmlns:xlink="http://www.w3.org/1999/xlink"

-    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"

-    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"

-    version="1.0"

-    width="32"

-    height="32"

-    id="svg3017"

-    sodipodi:version="0.32"

-    inkscape:version="0.44+devel"

-    sodipodi:docname="book.svg"

-    sodipodi:docbase="/home/andy/Desktop">

-   <metadata

-      id="metadata489">

-     <rdf:RDF>

-       <cc:Work

-          rdf:about="">

-         <dc:format>image/svg+xml</dc:format>

-         <dc:type

-            rdf:resource="http://purl.org/dc/dcmitype/StillImage" />

-       </cc:Work>

-     </rdf:RDF>

-   </metadata>

-   <sodipodi:namedview

-      inkscape:window-height="480"

-      inkscape:window-width="858"

-      inkscape:pageshadow="0"

-      inkscape:pageopacity="0.0"

-      guidetolerance="10.0"

-      gridtolerance="10.0"

-      objecttolerance="10.0"

-      borderopacity="1.0"

-      bordercolor="#666666"

-      pagecolor="#ffffff"

-      id="base"

-      inkscape:zoom="1"

-      inkscape:cx="16"

-      inkscape:cy="15.944056"

-      inkscape:window-x="0"

-      inkscape:window-y="33"

-      inkscape:current-layer="svg3017" />

-   <defs

-      id="defs3019">

-     <linearGradient

-        id="linearGradient2381">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="stop2383" />

-       <stop

-          style="stop-color:white;stop-opacity:0"

-          offset="1"

-          id="stop2385" />

-     </linearGradient>

-     <linearGradient

-        x1="415.73831"

-        y1="11.854"

-        x2="418.13361"

-        y2="18.8104"

-        id="XMLID_1758_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.8362,0.5206,-1.1904,0.992,147.62,-30.9374)">

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="0"

-          id="stop3903" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="1"

-          id="stop3905" />

-       <a:midPointStop

-          style="stop-color:#CCCCCC"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#CCCCCC"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#F2F2F2"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="500.70749"

-        y1="-13.2441"

-        x2="513.46442"

-        y2="-2.1547"

-        id="XMLID_1757_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0"

-          id="stop3890" />

-       <stop

-          style="stop-color:#96bad6;stop-opacity:1"

-          offset="1"

-          id="stop3892" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#96BAD6"

-          offset="1" />

-     </linearGradient>

-     <clipPath

-        id="XMLID_1755_">

-       <use

-          id="use3874"

-          x="0"

-          y="0"

-          width="744.09448"

-          height="600"

-          xlink:href="#XMLID_343_" />

-     </clipPath>

-     <linearGradient

-        x1="505.62939"

-        y1="-14.9526"

-        x2="527.49402"

-        y2="-0.7536"

-        id="XMLID_1756_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0"

-          id="stop3877" />

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0.51120001"

-          id="stop3879" />

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0.64609998"

-          id="stop3881" />

-       <stop

-          style="stop-color:#16336e;stop-opacity:1"

-          offset="1"

-          id="stop3883" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5112" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.6461" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#16336E"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="471.0806"

-        y1="201.07761"

-        x2="481.91711"

-        y2="210.4977"

-        id="XMLID_1754_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#6498c1;stop-opacity:1"

-          offset="0.005618"

-          id="stop3863" />

-       <stop

-          style="stop-color:#79a9cc;stop-opacity:1"

-          offset="0.2332"

-          id="stop3865" />

-       <stop

-          style="stop-color:#a4cde2;stop-opacity:1"

-          offset="0.74049997"

-          id="stop3867" />

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="1"

-          id="stop3869" />

-       <a:midPointStop

-          style="stop-color:#6498C1"

-          offset="5.618000e-003" />

-       <a:midPointStop

-          style="stop-color:#6498C1"

-          offset="0.4438" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="516.57672"

-        y1="-15.769"

-        x2="516.57672"

-        y2="0.84280002"

-        id="XMLID_1753_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="0"

-          id="stop3851" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="1"

-          id="stop3853" />

-       <a:midPointStop

-          style="stop-color:#B2B2B2"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#B2B2B2"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#F2F2F2"

-          offset="1" />

-     </linearGradient>

-     <clipPath

-        id="XMLID_1751_">

-       <use

-          id="use3837"

-          x="0"

-          y="0"

-          width="744.09448"

-          height="600"

-          xlink:href="#XMLID_338_" />

-     </clipPath>

-     <linearGradient

-        x1="506.09909"

-        y1="-11.5137"

-        x2="527.99609"

-        y2="2.7063999"

-        id="XMLID_1752_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0"

-          id="stop3840" />

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0.51120001"

-          id="stop3842" />

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0.64609998"

-          id="stop3844" />

-       <stop

-          style="stop-color:#16336e;stop-opacity:1"

-          offset="1"

-          id="stop3846" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5112" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.6461" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#16336E"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="468.2915"

-        y1="204.7612"

-        x2="479.39871"

-        y2="214.4166"

-        id="XMLID_1750_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0"

-          id="stop3830" />

-       <stop

-          style="stop-color:#96bad6;stop-opacity:1"

-          offset="1"

-          id="stop3832" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#96BAD6"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="502.70749"

-        y1="115.3013"

-        x2="516.39001"

-        y2="127.1953"

-        id="XMLID_1749_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.9703,0.2419,-0.2419,0.9703,11.0227,-35.6159)">

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0"

-          id="stop3818" />

-       <stop

-          style="stop-color:#96bad6;stop-opacity:1"

-          offset="1"

-          id="stop3820" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#96BAD6"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="501.0903"

-        y1="-19.2544"

-        x2="531.85413"

-        y2="0.72390002"

-        id="XMLID_1748_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0"

-          id="stop3803" />

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0.51120001"

-          id="stop3805" />

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0.64609998"

-          id="stop3807" />

-       <stop

-          style="stop-color:#16336e;stop-opacity:1"

-          offset="1"

-          id="stop3809" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5112" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.6461" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#16336E"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="481.23969"

-        y1="212.5742"

-        x2="472.92981"

-        y2="207.4967"

-        id="XMLID_2275_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#f3403f;stop-opacity:1"

-          offset="0"

-          id="stop9947" />

-       <stop

-          style="stop-color:#d02a28;stop-opacity:1"

-          offset="0.37889999"

-          id="stop9949" />

-       <stop

-          style="stop-color:#b21714;stop-opacity:1"

-          offset="0.77649999"

-          id="stop9951" />

-       <stop

-          style="stop-color:#a6100c;stop-opacity:1"

-          offset="1"

-          id="stop9953" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0.4213" />

-       <a:midPointStop

-          style="stop-color:#A6100C"

-          offset="1" />

-     </linearGradient>

-     <clipPath

-        id="XMLID_2273_">

-       <use

-          id="use9933"

-          x="0"

-          y="0"

-          width="744.09448"

-          height="600"

-          xlink:href="#XMLID_960_" />

-     </clipPath>

-     <linearGradient

-        x1="473.7681"

-        y1="209.17529"

-        x2="486.98099"

-        y2="213.2001"

-        id="XMLID_2274_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#f3403f;stop-opacity:1"

-          offset="0"

-          id="stop9936" />

-       <stop

-          style="stop-color:#d02a28;stop-opacity:1"

-          offset="0.37889999"

-          id="stop9938" />

-       <stop

-          style="stop-color:#b21714;stop-opacity:1"

-          offset="0.77649999"

-          id="stop9940" />

-       <stop

-          style="stop-color:#a6100c;stop-opacity:1"

-          offset="1"

-          id="stop9942" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0.4213" />

-       <a:midPointStop

-          style="stop-color:#A6100C"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="478.21341"

-        y1="-131.9297"

-        x2="469.85818"

-        y2="-140.28481"

-        id="XMLID_2272_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.5592,0.829,-0.829,0.5592,101.3357,-104.791)">

-       <stop

-          style="stop-color:#f3403f;stop-opacity:1"

-          offset="0"

-          id="stop9917" />

-       <stop

-          style="stop-color:#d02a28;stop-opacity:1"

-          offset="0.37889999"

-          id="stop9919" />

-       <stop

-          style="stop-color:#b21714;stop-opacity:1"

-          offset="0.77649999"

-          id="stop9921" />

-       <stop

-          style="stop-color:#a6100c;stop-opacity:1"

-          offset="1"

-          id="stop9923" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0.4213" />

-       <a:midPointStop

-          style="stop-color:#A6100C"

-          offset="1" />

-     </linearGradient>

-     <marker

-        refX="0"

-        refY="0"

-        orient="auto"

-        style="overflow:visible"

-        id="TriangleInM">

-       <path

-          d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z "

-          transform="scale(-0.4,-0.4)"

-          style="fill:#5c5c4f"

-          id="path3197" />

-     </marker>

-     <linearGradient

-        x1="200.7363"

-        y1="100.4028"

-        x2="211.99519"

-        y2="89.143997"

-        id="XMLID_3298_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#bfbfbf;stop-opacity:1"

-          offset="0"

-          id="stop20103" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="1"

-          id="stop20105" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#BFBFBF" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#BFBFBF" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#F2F2F2" />

-     </linearGradient>

-     <linearGradient

-        x1="200.7363"

-        y1="100.4028"

-        x2="211.99519"

-        y2="89.143997"

-        id="linearGradient36592"

-        xlink:href="#XMLID_3298_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.029078,0,0,1,-183.2624,-79.44655)" />

-     <linearGradient

-        x1="181.2925"

-        y1="110.8481"

-        x2="192.6369"

-        y2="99.5037"

-        id="XMLID_3297_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0"

-          id="stop20096" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="stop20098" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#CCCCCC" />

-     </linearGradient>

-     <linearGradient

-        x1="181.2925"

-        y1="110.8481"

-        x2="192.6369"

-        y2="99.5037"

-        id="linearGradient36595"

-        xlink:href="#XMLID_3297_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.029078,0,0,1,-183.2624,-79.44655)" />

-     <linearGradient

-        x1="211.77589"

-        y1="105.7749"

-        x2="212.6619"

-        y2="108.2092"

-        id="XMLID_3296_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#0f6124;stop-opacity:1"

-          offset="0"

-          id="stop20087" />

-       <stop

-          style="stop-color:#219630;stop-opacity:1"

-          offset="1"

-          id="stop20089" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#0F6124" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#0F6124" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#219630" />

-     </linearGradient>

-     <linearGradient

-        x1="211.77589"

-        y1="105.7749"

-        x2="212.6619"

-        y2="108.2092"

-        id="linearGradient36677"

-        xlink:href="#XMLID_3296_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.029078,0,0,1,-183.2624,-79.44655)" />

-     <linearGradient

-        x1="208.9834"

-        y1="116.8296"

-        x2="200.0811"

-        y2="96.834602"

-        id="XMLID_3295_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="0"

-          id="stop20076" />

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0.5"

-          id="stop20078" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="1"

-          id="stop20080" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#B2B2B2" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#B2B2B2" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#FFFFFF" />

-     </linearGradient>

-     <linearGradient

-        x1="208.9834"

-        y1="116.8296"

-        x2="200.0811"

-        y2="96.834602"

-        id="linearGradient36604"

-        xlink:href="#XMLID_3295_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.029078,0,0,1,-183.2624,-79.44655)" />

-     <linearGradient

-        x1="195.5264"

-        y1="97.911102"

-        x2="213.5213"

-        y2="115.9061"

-        id="XMLID_3294_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="0"

-          id="stop20069" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="1"

-          id="stop20071" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#CCCCCC" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#CCCCCC" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#FFFFFF" />

-     </linearGradient>

-     <linearGradient

-        x1="195.5264"

-        y1="97.911102"

-        x2="213.5213"

-        y2="115.9061"

-        id="linearGradient36607"

-        xlink:href="#XMLID_3294_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.029078,0,0,1,-183.2624,-79.44655)" />

-     <linearGradient

-        x1="186.1938"

-        y1="109.1343"

-        x2="206.6881"

-        y2="88.639999"

-        id="XMLID_3293_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="0"

-          id="stop20056" />

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0.16850001"

-          id="stop20058" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0.23029999"

-          id="stop20060" />

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0.2809"

-          id="stop20062" />

-       <stop

-          style="stop-color:#c2c2c2;stop-opacity:1"

-          offset="0.5"

-          id="stop20064" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#B2B2B2" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#B2B2B2" />

-       <a:midPointStop

-          offset="0.1685"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.2303"

-          style="stop-color:#FFFFFF" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#FFFFFF" />

-       <a:midPointStop

-          offset="0.2809"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#C2C2C2" />

-     </linearGradient>

-     <linearGradient

-        x1="186.1938"

-        y1="109.1343"

-        x2="206.6881"

-        y2="88.639999"

-        id="linearGradient36610"

-        xlink:href="#XMLID_3293_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.029078,0,0,1,-183.2624,-79.44655)" />

-     <linearGradient

-        x1="184.8569"

-        y1="112.2676"

-        x2="211.94099"

-        y2="89.541397"

-        id="XMLID_3292_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="0"

-          id="stop20043" />

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0.16850001"

-          id="stop20045" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0.23029999"

-          id="stop20047" />

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0.2809"

-          id="stop20049" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="stop20051" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#B2B2B2" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#B2B2B2" />

-       <a:midPointStop

-          offset="0.1685"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.2303"

-          style="stop-color:#FFFFFF" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#FFFFFF" />

-       <a:midPointStop

-          offset="0.2809"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#CCCCCC" />

-     </linearGradient>

-     <linearGradient

-        x1="184.8569"

-        y1="112.2676"

-        x2="211.94099"

-        y2="89.541397"

-        id="linearGradient36613"

-        xlink:href="#XMLID_3292_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.029078,0,0,1,-183.2624,-79.44655)" />

-     <marker

-        refX="0"

-        refY="0"

-        orient="auto"

-        style="overflow:visible"

-        id="TriangleOutM">

-       <path

-          d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z "

-          transform="scale(0.4,0.4)"

-          style="fill:#5c5c4f;fill-rule:evenodd;stroke-width:1pt;marker-start:none"

-          id="path3238" />

-     </marker>

-     <linearGradient

-        x1="165.3"

-        y1="99.5"

-        x2="165.3"

-        y2="115.9"

-        id="XMLID_3457_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#999;stop-opacity:1"

-          offset="0"

-          id="stop8309" />

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="0.30000001"

-          id="stop8311" />

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="1"

-          id="stop8313" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#999999" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#999999" />

-       <a:midPointstop

-          offset="0.3"

-          style="stop-color:#B2B2B2" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#B2B2B2" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#B2B2B2" />

-     </linearGradient>

-     <linearGradient

-        x1="165.3"

-        y1="99.5"

-        x2="165.3"

-        y2="115.9"

-        id="lg1997"

-        xlink:href="#XMLID_3457_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.2,0,0,1.2,-175.9,-114.6)" />

-     <linearGradient

-        x1="175"

-        y1="99.800003"

-        x2="175"

-        y2="112.5"

-        id="XMLID_3456_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#737373;stop-opacity:1"

-          offset="0"

-          id="stop8300" />

-       <stop

-          style="stop-color:#191919;stop-opacity:1"

-          offset="0.60000002"

-          id="stop8302" />

-       <stop

-          style="stop-color:#191919;stop-opacity:1"

-          offset="1"

-          id="stop8304" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#737373" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#737373" />

-       <a:midPointstop

-          offset="0.6"

-          style="stop-color:#191919" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#191919" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#191919" />

-     </linearGradient>

-     <linearGradient

-        x1="175"

-        y1="99.800003"

-        x2="175"

-        y2="112.5"

-        id="lg2000"

-        xlink:href="#XMLID_3456_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.2,0,0,1.2,-175.9,-114.6)" />

-     <linearGradient

-        x1="168.8"

-        y1="107.1"

-        x2="164.5"

-        y2="110"

-        id="XMLID_3455_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#666;stop-opacity:1"

-          offset="0"

-          id="stop8291" />

-       <stop

-          style="stop-color:#191919;stop-opacity:1"

-          offset="0.69999999"

-          id="stop8293" />

-       <stop

-          style="stop-color:#191919;stop-opacity:1"

-          offset="1"

-          id="stop8295" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#666666" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#666666" />

-       <a:midPointstop

-          offset="0.7"

-          style="stop-color:#191919" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#191919" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#191919" />

-     </linearGradient>

-     <linearGradient

-        x1="168.8"

-        y1="107.1"

-        x2="164.5"

-        y2="110"

-        id="lg2003"

-        xlink:href="#XMLID_3455_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.2,0,0,1.2,-175.9,-114.6)" />

-     <linearGradient

-        id="lg63694">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="stop63696" />

-       <stop

-          style="stop-color:white;stop-opacity:0"

-          offset="1"

-          id="stop63698" />

-     </linearGradient>

-     <linearGradient

-        x1="458"

-        y1="483"

-        x2="465.20001"

-        y2="271.39999"

-        id="lg2006"

-        xlink:href="#lg63694"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(6.3e-2,0,0,6.3e-2,-1.3,-9.8)" />

-     <linearGradient

-        x1="176.3"

-        y1="110.1"

-        x2="158.7"

-        y2="105"

-        id="XMLID_3453_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#666;stop-opacity:1"

-          offset="0"

-          id="stop8271" />

-       <stop

-          style="stop-color:#737373;stop-opacity:1"

-          offset="0.2"

-          id="stop8273" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="1"

-          id="stop8275" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#666666" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#666666" />

-       <a:midPointstop

-          offset="0.2"

-          style="stop-color:#737373" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#737373" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#FFFFFF" />

-     </linearGradient>

-     <linearGradient

-        x1="176.3"

-        y1="110.1"

-        x2="158.7"

-        y2="105"

-        id="lg2009"

-        xlink:href="#XMLID_3453_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.2,0,0,1.2,-175.9,-114.6)" />

-     <linearGradient

-        x1="173.60001"

-        y1="118.9"

-        x2="172.8"

-        y2="128.2"

-        id="XMLID_3449_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#ecb300;stop-opacity:1"

-          offset="0"

-          id="stop8232" />

-       <stop

-          style="stop-color:#fff95e;stop-opacity:1"

-          offset="0.60000002"

-          id="stop8234" />

-       <stop

-          style="stop-color:#ecd600;stop-opacity:1"

-          offset="1"

-          id="stop8236" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.6"

-          style="stop-color:#FFF95E" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFF95E" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#ECD600" />

-     </linearGradient>

-     <linearGradient

-        x1="173.60001"

-        y1="118.9"

-        x2="172.8"

-        y2="128.2"

-        id="lg2016"

-        xlink:href="#XMLID_3449_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.2,0,0,1.2,-175.9,-114.6)" />

-     <radialGradient

-        cx="284.60001"

-        cy="172.60001"

-        r="6.5"

-        fx="284.60001"

-        fy="172.60001"

-        id="XMLID_3448_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.4,0,0,1.4,-237.3,-126.8)">

-       <stop

-          style="stop-color:#ecb300;stop-opacity:1"

-          offset="0"

-          id="stop8219" />

-       <stop

-          style="stop-color:#ecb300;stop-opacity:1"

-          offset="0.30000001"

-          id="stop8221" />

-       <stop

-          style="stop-color:#c96b00;stop-opacity:1"

-          offset="0.89999998"

-          id="stop8223" />

-       <stop

-          style="stop-color:#9a5500;stop-opacity:1"

-          offset="1"

-          id="stop8225" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.3"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.9"

-          style="stop-color:#C96B00" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#C96B00" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#9A5500" />

-     </radialGradient>

-     <radialGradient

-        cx="284.60001"

-        cy="172.60001"

-        r="6.5"

-        fx="284.60001"

-        fy="172.60001"

-        id="rg2020"

-        xlink:href="#XMLID_3448_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.513992,0,0,2.347576,-689.1621,-378.5717)" />

-     <linearGradient

-        x1="158.10001"

-        y1="123"

-        x2="164.2"

-        y2="126.6"

-        id="XMLID_3447_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#ecd600;stop-opacity:1"

-          offset="0"

-          id="stop8204" />

-       <stop

-          style="stop-color:#ffffb3;stop-opacity:1"

-          offset="0.30000001"

-          id="stop8206" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="1"

-          id="stop8208" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#ECD600" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#ECD600" />

-       <a:midPointstop

-          offset="0.3"

-          style="stop-color:#FFFFB3" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFFFB3" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#FFFFFF" />

-     </linearGradient>

-     <linearGradient

-        x1="158.10001"

-        y1="123"

-        x2="164.2"

-        y2="126.6"

-        id="lg2026"

-        xlink:href="#XMLID_3447_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.2,0,0,1.2,-175.9,-114.6)" />

-     <radialGradient

-        cx="280.89999"

-        cy="163.7"

-        r="10.1"

-        fx="280.89999"

-        fy="163.7"

-        id="XMLID_3446_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.4,0,0,1.4,-237.3,-126.8)">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="stop8197" />

-       <stop

-          style="stop-color:#fff95e;stop-opacity:1"

-          offset="1"

-          id="stop8199" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#FFFFFF" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFFFFF" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#FFF95E" />

-     </radialGradient>

-     <radialGradient

-        cx="280.89999"

-        cy="163.7"

-        r="10.1"

-        fx="280.89999"

-        fy="163.7"

-        id="rg2029"

-        xlink:href="#XMLID_3446_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.7,0,0,1.7,-457.5,-266.8)" />

-     <linearGradient

-        x1="156.5"

-        y1="122.7"

-        x2="180.10001"

-        y2="122.7"

-        id="XMLID_3445_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#ecb300;stop-opacity:1"

-          offset="0"

-          id="stop8184" />

-       <stop

-          style="stop-color:#ffe900;stop-opacity:1"

-          offset="0.2"

-          id="stop8186" />

-       <stop

-          style="stop-color:#ffffb3;stop-opacity:1"

-          offset="0.30000001"

-          id="stop8188" />

-       <stop

-          style="stop-color:#ffe900;stop-opacity:1"

-          offset="0.40000001"

-          id="stop8190" />

-       <stop

-          style="stop-color:#d68100;stop-opacity:1"

-          offset="1"

-          id="stop8192" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.2"

-          style="stop-color:#FFE900" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFE900" />

-       <a:midPointstop

-          offset="0.3"

-          style="stop-color:#FFFFB3" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFFFB3" />

-       <a:midPointstop

-          offset="0.4"

-          style="stop-color:#FFE900" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFE900" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#D68100" />

-     </linearGradient>

-     <linearGradient

-        x1="156.5"

-        y1="122.7"

-        x2="180.10001"

-        y2="122.7"

-        id="lg2032"

-        xlink:href="#XMLID_3445_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.2,0,0,1.2,-175.9,-114.6)" />

-     <linearGradient

-        x1="156.39999"

-        y1="115.4"

-        x2="180.10001"

-        y2="115.4"

-        id="XMLID_3444_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#ecb300;stop-opacity:1"

-          offset="0"

-          id="stop8171" />

-       <stop

-          style="stop-color:#ffe900;stop-opacity:1"

-          offset="0.2"

-          id="stop8173" />

-       <stop

-          style="stop-color:#ffffb3;stop-opacity:1"

-          offset="0.30000001"

-          id="stop8175" />

-       <stop

-          style="stop-color:#ffe900;stop-opacity:1"

-          offset="0.40000001"

-          id="stop8177" />

-       <stop

-          style="stop-color:#d68100;stop-opacity:1"

-          offset="1"

-          id="stop8179" />

-       <a:midPointstop

-          offset="0"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#ECB300" />

-       <a:midPointstop

-          offset="0.2"

-          style="stop-color:#FFE900" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFE900" />

-       <a:midPointstop

-          offset="0.3"

-          style="stop-color:#FFFFB3" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFFFB3" />

-       <a:midPointstop

-          offset="0.4"

-          style="stop-color:#FFE900" />

-       <a:midPointstop

-          offset="0.5"

-          style="stop-color:#FFE900" />

-       <a:midPointstop

-          offset="1"

-          style="stop-color:#D68100" />

-     </linearGradient>

-     <linearGradient

-        x1="156.39999"

-        y1="115.4"

-        x2="180.10001"

-        y2="115.4"

-        id="lg2035"

-        xlink:href="#XMLID_3444_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.2,0,0,1.2,-175.9,-114.6)" />

-     <linearGradient

-        x1="379.70001"

-        y1="167.89999"

-        x2="383.89999"

-        y2="172.89999"

-        id="lg4286_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.8,0.2,-0.2,0.8,78.8,38.1)">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="s16159" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0.1"

-          id="s16161" />

-       <stop

-          style="stop-color:#737373;stop-opacity:1"

-          offset="1"

-          id="s16163" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.1" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#737373"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="379.60001"

-        y1="167.8"

-        x2="383.79999"

-        y2="172"

-        id="lg6416"

-        xlink:href="#lg4286_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.622156,0.623859,-0.623859,2.62182,-882.9706,-673.7921)" />

-     <linearGradient

-        x1="384.20001"

-        y1="169.8"

-        x2="384.79999"

-        y2="170.39999"

-        id="lg4285_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.8,0.2,-0.2,0.8,78.8,38.1)">

-       <stop

-          style="stop-color:#737373;stop-opacity:1"

-          offset="0"

-          id="s16152" />

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="1"

-          id="s16154" />

-       <ns:midPointStop

-          style="stop-color:#737373"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#737373"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#D9D9D9"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="384.20001"

-        y1="169.8"

-        x2="384.79999"

-        y2="170.39999"

-        id="lg6453"

-        xlink:href="#lg4285_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.6,0.6,-0.6,2.6,-883,-673.8)" />

-     <linearGradient

-        x1="380.5"

-        y1="172.60001"

-        x2="382.79999"

-        y2="173.7"

-        id="lg4284_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.8,0.2,-0.2,0.8,78.8,38.1)">

-       <stop

-          style="stop-color:gray;stop-opacity:1"

-          offset="0"

-          id="s16145" />

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="1"

-          id="s16147" />

-       <ns:midPointStop

-          style="stop-color:#808080"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#808080"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#E5E5E5"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="380.5"

-        y1="172.60001"

-        x2="382.79999"

-        y2="173.7"

-        id="lg6456"

-        xlink:href="#lg4284_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.6,0.6,-0.6,2.6,-883,-673.8)" />

-     <radialGradient

-        cx="347.29999"

-        cy="244.5"

-        r="5.1999998"

-        fx="347.29999"

-        fy="244.5"

-        id="lg4282_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(3.4,0,0,3.4,-1148,-802)">

-       <stop

-          style="stop-color:#333;stop-opacity:1"

-          offset="0"

-          id="s16135" />

-       <stop

-          style="stop-color:#999;stop-opacity:1"

-          offset="1"

-          id="s16137" />

-       <ns:midPointStop

-          style="stop-color:#333333"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#333333"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#999999"

-          offset="1" />

-     </radialGradient>

-     <linearGradient

-        x1="310.39999"

-        y1="397.70001"

-        x2="310.89999"

-        y2="399.5"

-        id="lg4280_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.7,-0.7,0.7,0.7,-153.4,180.6)">

-       <stop

-          style="stop-color:#ffcd00;stop-opacity:1"

-          offset="0"

-          id="s16111" />

-       <stop

-          style="stop-color:#ffffb3;stop-opacity:1"

-          offset="0.60000002"

-          id="s16113" />

-       <stop

-          style="stop-color:#ffffb3;stop-opacity:1"

-          offset="1"

-          id="s16115" />

-       <ns:midPointStop

-          style="stop-color:#FFCD00"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#FFCD00"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="0.6" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="310.39999"

-        y1="397.70001"

-        x2="310.89999"

-        y2="399.5"

-        id="lg6467"

-        xlink:href="#lg4280_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.4,-2.4,2.4,2.4,-1663.6,-195)" />

-     <linearGradient

-        x1="310.89999"

-        y1="395.79999"

-        x2="313.29999"

-        y2="403.10001"

-        id="lg4279_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.7,-0.7,0.7,0.7,-153.4,180.6)">

-       <stop

-          style="stop-color:#ffffb3;stop-opacity:1"

-          offset="0"

-          id="s16100" />

-       <stop

-          style="stop-color:#ffffb3;stop-opacity:1"

-          offset="0.40000001"

-          id="s16102" />

-       <stop

-          style="stop-color:#ffcd00;stop-opacity:1"

-          offset="0.89999998"

-          id="s16104" />

-       <stop

-          style="stop-color:#ffcd00;stop-opacity:1"

-          offset="1"

-          id="s16106" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="0.4" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFCD00"

-          offset="0.9" />

-       <ns:midPointStop

-          style="stop-color:#FFCD00"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFCD00"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="310.89999"

-        y1="395.79999"

-        x2="313.29999"

-        y2="403.10001"

-        id="lg6465"

-        xlink:href="#lg4279_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.4,-2.4,2.4,2.4,-1663.6,-195)" />

-     <linearGradient

-        x1="307.79999"

-        y1="395.20001"

-        x2="313.79999"

-        y2="413.60001"

-        id="lg4278_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.7,-0.7,0.7,0.7,-153.4,180.6)">

-       <stop

-          style="stop-color:#ffffb3;stop-opacity:1"

-          offset="0"

-          id="s16091" />

-       <stop

-          style="stop-color:#fcd72f;stop-opacity:1"

-          offset="0.40000001"

-          id="s16093" />

-       <stop

-          style="stop-color:#ffcd00;stop-opacity:1"

-          offset="1"

-          id="s16095" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#FFFFB3"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FCD72F"

-          offset="0.4" />

-       <ns:midPointStop

-          style="stop-color:#FCD72F"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFCD00"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="306.5"

-        y1="393"

-        x2="309"

-        y2="404"

-        id="lg6400"

-        xlink:href="#lg4278_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.4,-2.4,2.4,2.4,-1663.6,-195)" />

-     <linearGradient

-        x1="352.10001"

-        y1="253.60001"

-        x2="348.5"

-        y2="237.8"

-        id="lg4276_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(3.4,0,0,3.4,-1148,-802)">

-       <stop

-          style="stop-color:#ffff87;stop-opacity:1"

-          offset="0"

-          id="s16077" />

-       <stop

-          style="stop-color:#ffad00;stop-opacity:1"

-          offset="1"

-          id="s16079" />

-       <ns:midPointStop

-          style="stop-color:#FFFF87"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#FFFF87"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFAD00"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="335.60001"

-        y1="354.79999"

-        x2="337.89999"

-        y2="354.79999"

-        id="lg4275_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.9,-0.5,0.5,0.9,-121.7,105.1)">

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="0"

-          id="s16057" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0.80000001"

-          id="s16059" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="1"

-          id="s16061" />

-       <ns:midPointStop

-          style="stop-color:#D9D9D9"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#D9D9D9"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.8" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="335.60001"

-        y1="354.79999"

-        x2="337.89999"

-        y2="354.79999"

-        id="lg6463"

-        xlink:href="#lg4275_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.9,-1.7,1.7,2.9,-1557,-448.7)" />

-     <linearGradient

-        x1="337.39999"

-        y1="353.10001"

-        x2="339.39999"

-        y2="357.10001"

-        id="lg4274_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.9,-0.5,0.5,0.9,-121.7,105.1)">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="s16048" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0.1"

-          id="s16050" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="s16052" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.1" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#CCCCCC"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="337.39999"

-        y1="353.10001"

-        x2="339.39999"

-        y2="357.10001"

-        id="lg6461"

-        xlink:href="#lg4274_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.9,-1.7,1.7,2.9,-1557,-448.7)" />

-     <linearGradient

-        x1="334.39999"

-        y1="355.5"

-        x2="335.5"

-        y2="356.79999"

-        id="lg4273_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.9,-0.5,0.5,0.9,-121.7,105.1)">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="s16041" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="s16043" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="5.6e-003" />

-       <ns:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#CCCCCC"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="334.39999"

-        y1="355.5"

-        x2="335.5"

-        y2="356.79999"

-        id="lg6381"

-        xlink:href="#lg4273_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(2.9,-1.7,1.7,2.9,-1557,-448.7)" />

-     <linearGradient

-        x1="348.39999"

-        y1="247.39999"

-        x2="354.10001"

-        y2="242"

-        id="lg4271_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(3.4,0,0,3.4,-1148,-802)">

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="0"

-          id="s16025" />

-       <stop

-          style="stop-color:#9e9e9e;stop-opacity:1"

-          offset="0.40000001"

-          id="s16027" />

-       <stop

-          style="stop-color:black;stop-opacity:1"

-          offset="1"

-          id="s16029" />

-       <ns:midPointStop

-          style="stop-color:#F2F2F2"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#F2F2F2"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#000000"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="351.29999"

-        y1="257.29999"

-        x2="346.29999"

-        y2="235.5"

-        id="lg4270_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#ffff87;stop-opacity:1"

-          offset="0"

-          id="s16007" />

-       <stop

-          style="stop-color:#ffad00;stop-opacity:1"

-          offset="1"

-          id="s16009" />

-       <ns:midPointStop

-          style="stop-color:#FFFF87"

-          offset="0" />

-       <ns:midPointStop

-          style="stop-color:#FFFF87"

-          offset="0.5" />

-       <ns:midPointStop

-          style="stop-color:#FFAD00"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="351.29999"

-        y1="257.29999"

-        x2="346.29999"

-        y2="235.5"

-        id="lg6459"

-        xlink:href="#lg4270_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(3.4,0,0,3.4,-1148,-802)" />

-     <linearGradient

-        x1="43.799999"

-        y1="32.5"

-        x2="63.299999"

-        y2="66.400002"

-        id="XMLID_2708_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="stop75318" />

-       <stop

-          style="stop-color:#fffcea;stop-opacity:1"

-          offset="1"

-          id="stop75320" />

-       <a:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#FFFCEA"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="43.799999"

-        y1="32.5"

-        x2="63.299999"

-        y2="66.400002"

-        id="lg1907"

-        xlink:href="#XMLID_2708_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="translate(-29,-22.6)" />

-     <linearGradient

-        x1="52.5"

-        y1="40.400002"

-        x2="58.200001"

-        y2="64"

-        id="XMLID_2707_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#ffdea0;stop-opacity:1"

-          offset="0"

-          id="stop75305" />

-       <stop

-          style="stop-color:#ffd89e;stop-opacity:1"

-          offset="0.30000001"

-          id="stop75307" />

-       <stop

-          style="stop-color:#ffd79e;stop-opacity:1"

-          offset="0.30000001"

-          id="stop75309" />

-       <stop

-          style="stop-color:#dbaf6d;stop-opacity:1"

-          offset="0.69999999"

-          id="stop75311" />

-       <stop

-          style="stop-color:#6f4c24;stop-opacity:1"

-          offset="1"

-          id="stop75313" />

-       <a:midPointStop

-          style="stop-color:#FFDEA0"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#FFDEA0"

-          offset="0.6" />

-       <a:midPointStop

-          style="stop-color:#FFD79E"

-          offset="0.3" />

-       <a:midPointStop

-          style="stop-color:#FFD79E"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#DBAF6D"

-          offset="0.7" />

-       <a:midPointStop

-          style="stop-color:#DBAF6D"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#6F4C24"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="52.5"

-        y1="40.400002"

-        x2="58.200001"

-        y2="64"

-        id="lg1910"

-        xlink:href="#XMLID_2707_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="translate(-29,-22.6)" />

-     <linearGradient

-        x1="58"

-        y1="73.199997"

-        x2="44.5"

-        y2="19"

-        id="XMLID_2704_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="translate(-29,-22.6)">

-       <stop

-          style="stop-color:#d4a96c;stop-opacity:1"

-          offset="0.5"

-          id="stop75284" />

-       <stop

-          style="stop-color:#dcb273;stop-opacity:1"

-          offset="0.60000002"

-          id="stop75286" />

-       <stop

-          style="stop-color:#f0ca87;stop-opacity:1"

-          offset="0.80000001"

-          id="stop75288" />

-       <stop

-          style="stop-color:#ffdc96;stop-opacity:1"

-          offset="0.69999999"

-          id="stop75290" />

-       <stop

-          style="stop-color:#c18a42;stop-opacity:1"

-          offset="1"

-          id="stop75292" />

-       <a:midPointStop

-          style="stop-color:#D4A96C"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#D4A96C"

-          offset="0.6" />

-       <a:midPointStop

-          style="stop-color:#FFDC96"

-          offset="0.7" />

-       <a:midPointStop

-          style="stop-color:#FFDC96"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#C18A42"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="53.700001"

-        y1="32"

-        x2="53.700001"

-        y2="64.599998"

-        id="XMLID_2703_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#e5c9b0;stop-opacity:1"

-          offset="0"

-          id="stop75268" />

-       <stop

-          style="stop-color:#e5c9b0;stop-opacity:1"

-          offset="0.40000001"

-          id="stop75270" />

-       <stop

-          style="stop-color:#c0aa94;stop-opacity:1"

-          offset="1"

-          id="stop75272" />

-       <a:midPointStop

-          style="stop-color:#E5C9B0"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#E5C9B0"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#E5C9B0"

-          offset="0.4" />

-       <a:midPointStop

-          style="stop-color:#E5C9B0"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#C0AA94"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="53.700001"

-        y1="32"

-        x2="53.700001"

-        y2="64.599998"

-        id="lg1916"

-        xlink:href="#XMLID_2703_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="translate(-29,-22.6)" />

-     <linearGradient

-        x1="224.31"

-        y1="19.450001"

-        x2="214.33"

-        y2="11.46"

-        id="XMLID_419_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#404040;stop-opacity:1"

-          offset="0"

-          id="s1903" />

-       <stop

-          style="stop-color:#6d6d6d;stop-opacity:1"

-          offset="0.33000001"

-          id="s1905" />

-       <stop

-          style="stop-color:#e9e9e9;stop-opacity:1"

-          offset="1"

-          id="s1907" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#404040" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#404040" />

-       <a:midPointStop

-          offset="0.33"

-          style="stop-color:#6D6D6D" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#6D6D6D" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#E9E9E9" />

-     </linearGradient>

-     <linearGradient

-        x1="221.84"

-        y1="32.779999"

-        x2="212.2"

-        y2="20.27"

-        id="lg1988"

-        xlink:href="#XMLID_419_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.33,0,0,1.31,-274.2,-5.2)" />

-     <linearGradient

-        x1="228.35001"

-        y1="33.279999"

-        x2="215.42999"

-        y2="33.279999"

-        id="lg1900"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="s1902" />

-       <stop

-          style="stop-color:white;stop-opacity:0"

-          offset="1"

-          id="s1906" />

-       <a:midPointStop

-          style="stop-color:#575757"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#575757"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#6D6D6D"

-          offset="0.33" />

-       <a:midPointStop

-          style="stop-color:#6D6D6D"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#D3D3D3"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="234.81"

-        y1="33.279999"

-        x2="228.27"

-        y2="33.279999"

-        id="lg1908"

-        xlink:href="#lg1900"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.33,0,0,1.31,-274.2,-5.2)" />

-     <linearGradient

-        x1="228.35001"

-        y1="33.279999"

-        x2="215.42999"

-        y2="33.279999"

-        id="XMLID_416_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#575757;stop-opacity:1"

-          offset="0"

-          id="s1874" />

-       <stop

-          style="stop-color:#6d6d6d;stop-opacity:1"

-          offset="0.33000001"

-          id="s1876" />

-       <stop

-          style="stop-color:#d3d3d3;stop-opacity:1"

-          offset="1"

-          id="s1878" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#575757" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#575757" />

-       <a:midPointStop

-          offset="0.33"

-          style="stop-color:#6D6D6D" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#6D6D6D" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#D3D3D3" />

-     </linearGradient>

-     <linearGradient

-        x1="228.35001"

-        y1="33.279999"

-        x2="215.42999"

-        y2="33.279999"

-        id="lg1991"

-        xlink:href="#XMLID_416_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.33,0,0,1.31,-274.2,-5.2)" />

-     <radialGradient

-        cx="603.19"

-        cy="230.77"

-        r="1.67"

-        fx="603.19"

-        fy="230.77"

-        id="x5010_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.1,0,0,1.1,-54.33,-75.4)">

-       <stop

-          style="stop-color:#c9ffc9;stop-opacity:1"

-          offset="0"

-          id="stop29201" />

-       <stop

-          style="stop-color:#23a11f;stop-opacity:1"

-          offset="1"

-          id="stop29203" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#C9FFC9" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#C9FFC9" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#23A11F" />

-     </radialGradient>

-     <radialGradient

-        cx="603.19"

-        cy="230.77"

-        r="1.67"

-        fx="603.19"

-        fy="230.77"

-        id="radialGradient5711"

-        xlink:href="#x5010_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.23,0,0,1.23,-709.93,-245.02)" />

-     <linearGradient

-        x1="592.31"

-        y1="162.60001"

-        x2="609.32001"

-        y2="145.59"

-        id="lg5722"

-        xlink:href="#x5003_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.12,0,0,1.12,-649.08,-160.62)" />

-     <linearGradient

-        x1="601.48999"

-        y1="170.16"

-        x2="613.84003"

-        y2="170.16"

-        id="x5002_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="0"

-          id="stop29134" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0.2"

-          id="stop29136" />

-       <stop

-          style="stop-color:#999;stop-opacity:1"

-          offset="1"

-          id="stop29138" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="0.20"

-          style="stop-color:#FFFFFF" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#FFFFFF" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#999999" />

-     </linearGradient>

-     <linearGradient

-        x1="601.48999"

-        y1="170.16"

-        x2="613.84003"

-        y2="170.16"

-        id="lg5725"

-        xlink:href="#x5002_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.12,0,0,1.12,-649.08,-160.62)" />

-     <linearGradient

-        x1="592.20001"

-        y1="156.45"

-        x2="609.98999"

-        y2="174.23"

-        id="x5004_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.12,0,0,1.12,-649.08,-160.62)">

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="0"

-          id="stop29157" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="1"

-          id="stop29159" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#FFFFFF" />

-     </linearGradient>

-     <linearGradient

-        x1="592.20001"

-        y1="156.45"

-        x2="609.98999"

-        y2="174.23"

-        id="lg5728"

-        xlink:href="#x5004_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.12,0,0,1.12,-649.08,-160.62)" />

-     <linearGradient

-        x1="592.31"

-        y1="162.60001"

-        x2="609.32001"

-        y2="145.59"

-        id="x5003_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="0"

-          id="stop29143" />

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="1"

-          id="stop29145" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#F2F2F2" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#F2F2F2" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#E5E5E5" />

-     </linearGradient>

-     <linearGradient

-        x1="592.31"

-        y1="162.60001"

-        x2="609.32001"

-        y2="145.59"

-        id="lg5732"

-        xlink:href="#x5003_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.12,0,0,1.12,-649.08,-160.62)" />

-     <linearGradient

-        x1="592.20001"

-        y1="156.45"

-        x2="609.98999"

-        y2="174.24001"

-        id="x5000_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.12,0,0,1.12,-649.08,-160.62)">

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="0"

-          id="stop29124" />

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="1"

-          id="stop29126" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#FFFFFF" />

-     </linearGradient>

-     <linearGradient

-        x1="592.20001"

-        y1="156.45"

-        x2="609.98999"

-        y2="174.24001"

-        id="lg5735"

-        xlink:href="#x5000_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.12,0,0,1.12,-649.08,-160.62)" />

-     <linearGradient

-        x1="308.54999"

-        y1="149.89999"

-        x2="299.72"

-        y2="148.83"

-        id="XMLID_2433_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#d6d6d6;stop-opacity:1"

-          offset="0"

-          id="71615" />

-       <stop

-          style="stop-color:#a5a5a5;stop-opacity:1"

-          offset="1"

-          id="71617" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#D6D6D6" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#D6D6D6" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#A5A5A5" />

-     </linearGradient>

-     <linearGradient

-        x1="308.54999"

-        y1="149.89999"

-        x2="299.72"

-        y2="148.83"

-        id="lg1952"

-        xlink:href="#XMLID_2433_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.03,0,0,1.03,-279.57,-124.36)" />

-     <radialGradient

-        cx="307.39999"

-        cy="121"

-        r="23.35"

-        fx="307.39999"

-        fy="121"

-        id="XMLID_2432_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.98,0,0,0.98,2.88,2.75)">

-       <stop

-          style="stop-color:#d2d2d2;stop-opacity:1"

-          offset="0.19"

-          id="71592" />

-       <stop

-          style="stop-color:#cfcfcf;stop-opacity:1"

-          offset="0.44999999"

-          id="71594" />

-       <stop

-          style="stop-color:#c7c7c7;stop-opacity:1"

-          offset="0.60000002"

-          id="71596" />

-       <stop

-          style="stop-color:#b9b9b9;stop-opacity:1"

-          offset="0.74000001"

-          id="71598" />

-       <stop

-          style="stop-color:#a4a4a4;stop-opacity:1"

-          offset="0.86000001"

-          id="71600" />

-       <stop

-          style="stop-color:#8a8a8a;stop-opacity:1"

-          offset="0.95999998"

-          id="71602" />

-       <stop

-          style="stop-color:gray;stop-opacity:1"

-          offset="1"

-          id="71604" />

-       <a:midPointStop

-          offset="0.19"

-          style="stop-color:#D2D2D2" />

-       <a:midPointStop

-          offset="0.8"

-          style="stop-color:#D2D2D2" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#808080" />

-     </radialGradient>

-     <radialGradient

-        cx="307.39999"

-        cy="121"

-        r="23.35"

-        fx="307.39999"

-        fy="121"

-        id="radialGradient2331"

-        xlink:href="#XMLID_2432_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="translate(-276.62,-121.54)" />

-     <linearGradient

-        x1="294.13"

-        y1="127.07"

-        x2="294.13"

-        y2="142.2"

-        id="XMLID_2430_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#b5d8ff;stop-opacity:1"

-          offset="0"

-          id="71582" />

-       <stop

-          style="stop-color:black;stop-opacity:1"

-          offset="1"

-          id="71584" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#B5D8FF" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#B5D8FF" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#000000" />

-     </linearGradient>

-     <linearGradient

-        x1="294.13"

-        y1="127.07"

-        x2="294.13"

-        y2="142.2"

-        id="lg2820"

-        xlink:href="#XMLID_2430_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.03,0,0,1.03,-279.57,-124.36)" />

-     <linearGradient

-        x1="279.10999"

-        y1="148.03"

-        x2="309.16"

-        y2="148.03"

-        id="XMLID_2429_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#e1e1e1;stop-opacity:1"

-          offset="0"

-          id="71564" />

-       <stop

-          style="stop-color:#e1e1e1;stop-opacity:1"

-          offset="0.25"

-          id="71566" />

-       <stop

-          style="stop-color:#a5a5a5;stop-opacity:1"

-          offset="0.44"

-          id="71568" />

-       <stop

-          style="stop-color:#a5a5a5;stop-opacity:1"

-          offset="1"

-          id="71570" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#E1E1E1" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E1E1E1" />

-       <a:midPointStop

-          offset="0.25"

-          style="stop-color:#E1E1E1" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E1E1E1" />

-       <a:midPointStop

-          offset="0.44"

-          style="stop-color:#A5A5A5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#A5A5A5" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#A5A5A5" />

-     </linearGradient>

-     <linearGradient

-        x1="279.10999"

-        y1="148.03"

-        x2="309.16"

-        y2="148.03"

-        id="lg2818"

-        xlink:href="#XMLID_2429_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.03,0,0,1.03,-279.57,-124.36)" />

-     <radialGradient

-        cx="622.34302"

-        cy="14.449"

-        r="26.496"

-        fx="622.34302"

-        fy="14.449"

-        id="lg3499_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.851,0,0,0.849,69.297,51.658)">

-       <stop

-          style="stop-color:#23468e;stop-opacity:1"

-          offset="0"

-          id="stop10972" />

-       <stop

-          style="stop-color:#012859;stop-opacity:1"

-          offset="1"

-          id="stop10974" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#23468E" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#23468E" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#012859" />

-     </radialGradient>

-     <radialGradient

-        cx="622.34302"

-        cy="14.449"

-        r="26.496"

-        fx="622.34302"

-        fy="14.449"

-        id="rg5791"

-        xlink:href="#lg3499_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.858,0,0,0.857,-511.7,9.02)" />

-     <linearGradient

-        x1="616.112"

-        y1="76.247002"

-        x2="588.14099"

-        y2="60.742001"

-        id="lg3497_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#01326e;stop-opacity:1"

-          offset="0"

-          id="stop10962" />

-       <stop

-          style="stop-color:#012859;stop-opacity:1"

-          offset="1"

-          id="stop10964" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#01326E" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#01326E" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#012859" />

-     </linearGradient>

-     <linearGradient

-        x1="617.698"

-        y1="82.445999"

-        x2="585.95203"

-        y2="54.848999"

-        id="lg3496_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0"

-          id="stop10950" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="stop10952" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#E5E5E5" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#CCCCCC" />

-     </linearGradient>

-     <linearGradient

-        x1="617.698"

-        y1="82.445999"

-        x2="585.95203"

-        y2="54.848999"

-        id="lg5794"

-        xlink:href="#lg3496_"

-        gradientUnits="userSpaceOnUse" />

-     <linearGradient

-        x1="601.39001"

-        y1="55.341"

-        x2="588.29199"

-        y2="71.515999"

-        id="lg3495_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="0"

-          id="stop10941" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="0.52200001"

-          id="stop10943" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="stop10945" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="0.522"

-          style="stop-color:#F2F2F2" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#F2F2F2" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#CCCCCC" />

-     </linearGradient>

-     <linearGradient

-        x1="601.39001"

-        y1="55.341"

-        x2="588.29199"

-        y2="71.515999"

-        id="lg5771"

-        xlink:href="#lg3495_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.009,0,0,1.009,-581.615,-43.098)" />

-     <linearGradient

-        x1="611.34601"

-        y1="55.279999"

-        x2="590.39001"

-        y2="81.157997"

-        id="lg3494_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="0"

-          id="stop10932" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="0.52200001"

-          id="stop10934" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="stop10936" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#D9D9D9" />

-       <a:midPointStop

-          offset="0.522"

-          style="stop-color:#F2F2F2" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#F2F2F2" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#CCCCCC" />

-     </linearGradient>

-     <linearGradient

-        x1="611.34601"

-        y1="55.279999"

-        x2="590.39001"

-        y2="81.157997"

-        id="lg5774"

-        xlink:href="#lg3494_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.009,0,0,1.009,-581.616,-43.098)" />

-     <linearGradient

-        x1="798.72998"

-        y1="69.839996"

-        x2="799.04999"

-        y2="70.709999"

-        id="g3302_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#005e00;stop-opacity:1"

-          offset="0"

-          id="s6504" />

-       <stop

-          style="stop-color:#23a11f;stop-opacity:1"

-          offset="1"

-          id="s6506" />

-       <a:midPointstop

-          style="stop-color:#005E00"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#005E00"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#23A11F"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="798.72998"

-        y1="69.839996"

-        x2="799.04999"

-        y2="70.709999"

-        id="lg5851"

-        xlink:href="#g3302_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.204,0,0,1.263,-926.036,-60.001)" />

-     <linearGradient

-        x1="779.19"

-        y1="122.73"

-        x2="811.69"

-        y2="149.74001"

-        id="g3301_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1,-0.25,0,1,0,129.19)">

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="0"

-          id="s6483" />

-       <stop

-          style="stop-color:#eee;stop-opacity:1"

-          offset="0.17"

-          id="s6485" />

-       <stop

-          style="stop-color:#e3e3e3;stop-opacity:1"

-          offset="0.34"

-          id="s6487" />

-       <stop

-          style="stop-color:#cfcfcf;stop-opacity:1"

-          offset="0.50999999"

-          id="s6489" />

-       <stop

-          style="stop-color:#b4b4b4;stop-opacity:1"

-          offset="0.67000002"

-          id="s6491" />

-       <stop

-          style="stop-color:#919191;stop-opacity:1"

-          offset="0.83999997"

-          id="s6493" />

-       <stop

-          style="stop-color:#666;stop-opacity:1"

-          offset="1"

-          id="s6495" />

-       <a:midPointstop

-          style="stop-color:#F2F2F2"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#F2F2F2"

-          offset="0.71" />

-       <a:midPointstop

-          style="stop-color:#666666"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="779.19"

-        y1="122.73"

-        x2="811.69"

-        y2="149.74001"

-        id="lg5855"

-        xlink:href="#g3301_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.204,-0.316,0,1.263,-926.036,103.123)" />

-     <clipPath

-        id="g3299_">

-       <use

-          id="use6469"

-          x="0"

-          y="0"

-          width="1005.92"

-          height="376.97"

-          xlink:href="#g101_" />

-     </clipPath>

-     <radialGradient

-        cx="1189.9301"

-        cy="100.05"

-        r="40.400002"

-        fx="1189.9301"

-        fy="100.05"

-        id="g3300_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.34,-8.46e-2,0,0.34,394.16,137.13)">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="s6472" />

-       <stop

-          style="stop-color:white;stop-opacity:0"

-          offset="1"

-          id="s6474" />

-       <a:midPointstop

-          style="stop-color:#FFFFFF"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#000000"

-          offset="1" />

-     </radialGradient>

-     <radialGradient

-        cx="1199.74"

-        cy="97.150002"

-        r="40.400002"

-        fx="1199.74"

-        fy="97.150002"

-        id="rg5860"

-        xlink:href="#g3300_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.409,-0.107,0,0.429,-451.489,113.149)" />

-     <linearGradient

-        x1="796.38"

-        y1="67.580002"

-        x2="781.28003"

-        y2="58.549999"

-        id="g3298_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#4c8bca;stop-opacity:1"

-          offset="0"

-          id="s6462" />

-       <stop

-          style="stop-color:#b7e9ff;stop-opacity:1"

-          offset="1"

-          id="s6464" />

-       <a:midPointstop

-          style="stop-color:#4C8BCA"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#4C8BCA"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#B7E9FF"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="800.97998"

-        y1="140.72"

-        x2="777.71997"

-        y2="121.76"

-        id="g3297_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1,-0.25,0,1,0,129.19)">

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0"

-          id="s6448" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="s6450" />

-       <a:midPointstop

-          style="stop-color:#E5E5E5"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#E5E5E5"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#CCCCCC"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="800.97998"

-        y1="140.72"

-        x2="777.71997"

-        y2="121.76"

-        id="lg5890"

-        xlink:href="#g3297_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1,-0.25,0,1,0,129.19)" />

-     <linearGradient

-        x1="790.03998"

-        y1="-16.33"

-        x2="779.84003"

-        y2="-3.73"

-        id="g3296_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="translate(0,70.17)">

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="0"

-          id="s6439" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="0.51999998"

-          id="s6441" />

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="1"

-          id="s6443" />

-       <a:midPointstop

-          style="stop-color:#D9D9D9"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#D9D9D9"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#F2F2F2"

-          offset="0.52" />

-       <a:midPointstop

-          style="stop-color:#F2F2F2"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#CCCCCC"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="790.03998"

-        y1="-16.33"

-        x2="779.84003"

-        y2="-3.73"

-        id="lg5866"

-        xlink:href="#g3296_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.204,0,0,1.263,-926.036,28.6)" />

-     <linearGradient

-        x1="785.84003"

-        y1="72.989998"

-        x2="785.26001"

-        y2="76.279999"

-        id="g3293_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="s6412" />

-       <stop

-          style="stop-color:#737373;stop-opacity:1"

-          offset="1"

-          id="s6414" />

-       <a:midPointstop

-          style="stop-color:#FFFFFF"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#737373"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="785.84003"

-        y1="72.989998"

-        x2="785.26001"

-        y2="76.279999"

-        id="lg5871"

-        xlink:href="#g3293_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.204,0,0,1.263,-926.036,-60.001)" />

-     <linearGradient

-        x1="789.37"

-        y1="69.879997"

-        x2="791.03998"

-        y2="77.120003"

-        id="g3292_"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#999;stop-opacity:1"

-          offset="0"

-          id="s6403" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="0.28"

-          id="s6405" />

-       <stop

-          style="stop-color:#666;stop-opacity:1"

-          offset="1"

-          id="s6407" />

-       <a:midPointstop

-          style="stop-color:#999999"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#999999"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#F2F2F2"

-          offset="0.28" />

-       <a:midPointstop

-          style="stop-color:#F2F2F2"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#666666"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="789.37"

-        y1="69.879997"

-        x2="791.03998"

-        y2="77.120003"

-        id="lg5874"

-        xlink:href="#g3292_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.204,0,0,1.263,-926.036,-60.001)" />

-     <linearGradient

-        x1="786.65997"

-        y1="136.12"

-        x2="786.71002"

-        y2="134.33"

-        id="g3290_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1,-0.25,0,1,0,137.29)">

-       <stop

-          style="stop-color:#d9d9d9;stop-opacity:1"

-          offset="0"

-          id="s6380" />

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="1"

-          id="s6382" />

-       <a:midPointstop

-          style="stop-color:#D9D9D9"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#D9D9D9"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#B2B2B2"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="786.65997"

-        y1="136.12"

-        x2="786.71002"

-        y2="134.33"

-        id="lg5878"

-        xlink:href="#g3290_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(1.204,-0.316,0,1.263,-926.036,113.351)" />

-     <radialGradient

-        cx="1458.77"

-        cy="-5.0999999"

-        r="35.130001"

-        fx="1458.77"

-        fy="-5.0999999"

-        id="g3289_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.42,0,0,0.42,167.09,79.84)">

-       <stop

-          style="stop-color:white;stop-opacity:1"

-          offset="0"

-          id="s6371" />

-       <stop

-          style="stop-color:#999;stop-opacity:1"

-          offset="1"

-          id="s6373" />

-       <a:midPointstop

-          style="stop-color:#FFFFFF"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#FFFFFF"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#999999"

-          offset="1" />

-     </radialGradient>

-     <radialGradient

-        cx="1458.77"

-        cy="-5.0999999"

-        r="35.130001"

-        fx="1458.77"

-        fy="-5.0999999"

-        id="rg5881"

-        xlink:href="#g3289_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.505,0,0,0.53,-724.957,40.636)" />

-     <radialGradient

-        cx="1612.98"

-        cy="-4.4699998"

-        r="36.580002"

-        fx="1612.98"

-        fy="-4.4699998"

-        id="g3288_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.34,0,0,0.36,238.56,86.87)">

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0"

-          id="s6362" />

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="0.63999999"

-          id="s6364" />

-       <stop

-          style="stop-color:#737373;stop-opacity:1"

-          offset="1"

-          id="s6366" />

-       <a:midPointstop

-          style="stop-color:#E5E5E5"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#E5E5E5"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#B2B2B2"

-          offset="0.64" />

-       <a:midPointstop

-          style="stop-color:#B2B2B2"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#737373"

-          offset="1" />

-     </radialGradient>

-     <radialGradient

-        cx="1612.98"

-        cy="-4.4699998"

-        r="36.580002"

-        fx="1612.98"

-        fy="-4.4699998"

-        id="rg5884"

-        xlink:href="#g3288_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.408,0,0,0.448,-638.943,49.495)" />

-     <radialGradient

-        cx="1470.5"

-        cy="-10.21"

-        r="33.290001"

-        fx="1470.5"

-        fy="-10.21"

-        id="g3287_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.42,0,0,0.42,167.09,79.84)">

-       <stop

-          style="stop-color:#e5e5e5;stop-opacity:1"

-          offset="0"

-          id="s6347" />

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="0.38999999"

-          id="s6349" />

-       <stop

-          style="stop-color:#b1b1b1;stop-opacity:1"

-          offset="0.75"

-          id="s6351" />

-       <stop

-          style="stop-color:#aaa;stop-opacity:1"

-          offset="0.88"

-          id="s6353" />

-       <stop

-          style="stop-color:#9e9e9e;stop-opacity:1"

-          offset="0.97000003"

-          id="s6355" />

-       <stop

-          style="stop-color:#999;stop-opacity:1"

-          offset="1"

-          id="s6357" />

-       <a:midPointstop

-          style="stop-color:#E5E5E5"

-          offset="0" />

-       <a:midPointstop

-          style="stop-color:#E5E5E5"

-          offset="0.5" />

-       <a:midPointstop

-          style="stop-color:#B2B2B2"

-          offset="0.39" />

-       <a:midPointstop

-          style="stop-color:#B2B2B2"

-          offset="0.87" />

-       <a:midPointstop

-          style="stop-color:#999999"

-          offset="1" />

-     </radialGradient>

-     <radialGradient

-        cx="1470.5"

-        cy="-10.21"

-        r="33.290001"

-        fx="1470.5"

-        fy="-10.21"

-        id="rg5887"

-        xlink:href="#g3287_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.505,0,0,0.53,-724.957,40.636)" />

-     <pattern

-        patternTransform="matrix(0.592927,0,0,0.592927,78,462)"

-        id="cream-spots"

-        height="32"

-        width="32"

-        patternUnits="userSpaceOnUse">

-       <g

-          transform="translate(-365.3146,-513.505)"

-          id="g3047">

-            id=&quot;path2858&quot; /&gt;

-         <path

-    inkscape:label="#path2854"

-    sodipodi:nodetypes="czzzz"

-    style="fill:#e3dcc0"

-    id="path3060"

-    d="M 390.31462,529.50504 C 390.31462,534.47304 386.28262,538.50504 381.31462,538.50504 C 376.34662,538.50504 372.31462,534.47304 372.31462,529.50504 C 372.31462,524.53704 376.34662,520.50504 381.31462,520.50504 C 386.28262,520.50504 390.31462,524.53704 390.31462,529.50504 z " />

- </g>

-     </pattern>

-     <pattern

-        patternTransform="matrix(0.733751,0,0,0.733751,67,367)"

-        id="dark-cream-spots"

-        height="32"

-        width="32"

-        patternUnits="userSpaceOnUse">

-       <g

-          transform="translate(-408.0946,-513.505)"

-          id="dark-cream-spot"

-          inkscape:label="#g3043">

-         <path

-            sodipodi:nodetypes="czzzz"

-            style="fill:#c8c5ac"

-            d="M 433.09458,529.50504 C 433.09458,534.47304 429.06258,538.50504 424.09458,538.50504 C 419.12658,538.50504 415.09458,534.47304 415.09458,529.50504 C 415.09458,524.53704 419.12658,520.50504 424.09458,520.50504 C 429.06258,520.50504 433.09458,524.53704 433.09458,529.50504 z "

-            id="path2953" />

-       </g>

-     </pattern>

-     <pattern

-        patternTransform="matrix(0.375,0,0,0.375,379,400)"

-        id="white-spots"

-        height="32"

-        width="32"

-        patternUnits="userSpaceOnUse">

-       <g

-          transform="translate(-484.3997,-513.505)"

-          id="white-spot"

-          inkscape:label="#g3035">

-         <path

-            style="opacity:0.25;fill:white"

-            id="path3033"

-            d="M 509.39967,529.50504 C 509.39967,534.47304 505.36767,538.50504 500.39967,538.50504 C 495.43167,538.50504 491.39967,534.47304 491.39967,529.50504 C 491.39967,524.53704 495.43167,520.50504 500.39967,520.50504 C 505.36767,520.50504 509.39967,524.53704 509.39967,529.50504 z "

-            sodipodi:nodetypes="czzzz" />

-       </g>

-     </pattern>

-     <pattern

-        patternTransform="matrix(0.455007,0,0,0.455007,-5e-5,1.9e-5)"

-        id="black-spots"

-        height="32"

-        width="32"

-        patternUnits="userSpaceOnUse">

-       <g

-          transform="translate(-448.3997,-513.505)"

-          id="black-spot"

-          inkscape:label="#g3039">

-         <path

-            sodipodi:nodetypes="czzzz"

-            d="M 473.39967,529.50504 C 473.39967,534.47304 469.36767,538.50504 464.39967,538.50504 C 459.43167,538.50504 455.39967,534.47304 455.39967,529.50504 C 455.39967,524.53704 459.43167,520.50504 464.39967,520.50504 C 469.36767,520.50504 473.39967,524.53704 473.39967,529.50504 z "

-            id="path2961"

-            style="opacity:0.25;fill:black" />

-       </g>

-     </pattern>

-     <linearGradient

-        x1="501.0903"

-        y1="-19.2544"

-        x2="531.85413"

-        y2="0.72390002"

-        id="linearGradient17334"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0"

-          id="stop17336" />

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0.51120001"

-          id="stop17338" />

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0.64609998"

-          id="stop17340" />

-       <stop

-          style="stop-color:#16336e;stop-opacity:1"

-          offset="1"

-          id="stop17342" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#B4DAEA" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#B4DAEA" />

-       <a:midPointStop

-          offset="0.5112"

-          style="stop-color:#B4DAEA" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#B4DAEA" />

-       <a:midPointStop

-          offset="0.6461"

-          style="stop-color:#5387BA" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#5387BA" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#16336E" />

-     </linearGradient>

-     <linearGradient

-        x1="415.73831"

-        y1="11.854"

-        x2="418.13361"

-        y2="18.8104"

-        id="linearGradient17426"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.8362,0.5206,-1.1904,0.992,147.62,-30.9374)">

-       <stop

-          style="stop-color:#ccc;stop-opacity:1"

-          offset="0"

-          id="stop17428" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="1"

-          id="stop17430" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#CCCCCC" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#CCCCCC" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#F2F2F2" />

-     </linearGradient>

-     <linearGradient

-        x1="478.21341"

-        y1="-131.9297"

-        x2="469.85818"

-        y2="-140.28481"

-        id="linearGradient17434"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.5592,0.829,-0.829,0.5592,101.3357,-104.791)">

-       <stop

-          style="stop-color:#f3403f;stop-opacity:1"

-          offset="0"

-          id="stop17436" />

-       <stop

-          style="stop-color:#d02a28;stop-opacity:1"

-          offset="0.37889999"

-          id="stop17438" />

-       <stop

-          style="stop-color:#b21714;stop-opacity:1"

-          offset="0.77649999"

-          id="stop17440" />

-       <stop

-          style="stop-color:#a6100c;stop-opacity:1"

-          offset="1"

-          id="stop17442" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#F3403F" />

-       <a:midPointStop

-          offset="0.4213"

-          style="stop-color:#F3403F" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#A6100C" />

-     </linearGradient>

-     <linearGradient

-        x1="502.70749"

-        y1="115.3013"

-        x2="516.39001"

-        y2="127.1953"

-        id="linearGradient17709"

-        xlink:href="#XMLID_1749_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.9703,0.2419,-0.2419,0.9703,11.0227,-35.6159)" />

-     <linearGradient

-        x1="506.09909"

-        y1="-11.5137"

-        x2="527.99609"

-        y2="2.7063999"

-        id="linearGradient17711"

-        xlink:href="#XMLID_1752_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <linearGradient

-        x1="516.57672"

-        y1="-15.769"

-        x2="516.57672"

-        y2="0.84280002"

-        id="linearGradient17713"

-        xlink:href="#XMLID_1753_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <linearGradient

-        x1="505.62939"

-        y1="-14.9526"

-        x2="527.49402"

-        y2="-0.7536"

-        id="linearGradient17715"

-        xlink:href="#XMLID_1756_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <linearGradient

-        x1="500.70749"

-        y1="-13.2441"

-        x2="513.46442"

-        y2="-2.1547"

-        id="linearGradient17717"

-        xlink:href="#XMLID_1757_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <linearGradient

-        x1="473.7681"

-        y1="209.17529"

-        x2="486.98099"

-        y2="213.2001"

-        id="linearGradient17721"

-        xlink:href="#XMLID_2274_"

-        gradientUnits="userSpaceOnUse" />

-     <linearGradient

-        x1="481.23969"

-        y1="212.5742"

-        x2="472.92981"

-        y2="207.4967"

-        id="linearGradient17723"

-        xlink:href="#XMLID_2275_"

-        gradientUnits="userSpaceOnUse" />

-     <linearGradient

-        x1="500.70749"

-        y1="-13.2441"

-        x2="513.46442"

-        y2="-2.1547"

-        id="linearGradient17416"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0"

-          id="stop17418" />

-       <stop

-          style="stop-color:#96bad6;stop-opacity:1"

-          offset="1"

-          id="stop17420" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#96BAD6"

-          offset="1" />

-     </linearGradient>

-     <defs

-        id="defs9929">

-       <path

-          d="M 489.21,209.35 L 485.35,203.63 C 483.63,204.25 473.47,208.93 471.5,210.18 C 470.57,210.77 470.17,211.16 469.72,212.48 C 470.93,212.31 471.72,212.49 473.42,213.04 C 473.26,214.77 473.24,215.74 473.57,218.2 C 474.01,216.88 474.41,216.49 475.34,215.9 C 477.33,214.65 487.49,209.97 489.21,209.35 z "

-          id="XMLID_960_" />

-     </defs>

-     <clipPath

-        id="clipPath17448">

-       <use

-          id="use17450"

-          x="0"

-          y="0"

-          width="744.09448"

-          height="600"

-          xlink:href="#XMLID_960_" />

-     </clipPath>

-     <linearGradient

-        x1="473.7681"

-        y1="209.17529"

-        x2="486.98099"

-        y2="213.2001"

-        id="linearGradient17452"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#f3403f;stop-opacity:1"

-          offset="0"

-          id="stop17454" />

-       <stop

-          style="stop-color:#d02a28;stop-opacity:1"

-          offset="0.37889999"

-          id="stop17456" />

-       <stop

-          style="stop-color:#b21714;stop-opacity:1"

-          offset="0.77649999"

-          id="stop17458" />

-       <stop

-          style="stop-color:#a6100c;stop-opacity:1"

-          offset="1"

-          id="stop17460" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0.4213" />

-       <a:midPointStop

-          style="stop-color:#A6100C"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="481.23969"

-        y1="212.5742"

-        x2="472.92981"

-        y2="207.4967"

-        id="linearGradient17463"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#f3403f;stop-opacity:1"

-          offset="0"

-          id="stop17465" />

-       <stop

-          style="stop-color:#d02a28;stop-opacity:1"

-          offset="0.37889999"

-          id="stop17467" />

-       <stop

-          style="stop-color:#b21714;stop-opacity:1"

-          offset="0.77649999"

-          id="stop17469" />

-       <stop

-          style="stop-color:#a6100c;stop-opacity:1"

-          offset="1"

-          id="stop17471" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#F3403F"

-          offset="0.4213" />

-       <a:midPointStop

-          style="stop-color:#A6100C"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="481.23969"

-        y1="212.5742"

-        x2="472.92981"

-        y2="207.4967"

-        id="linearGradient17807"

-        xlink:href="#XMLID_2275_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="translate(-177.1654,35.43307)" />

-     <linearGradient

-        x1="473.7681"

-        y1="209.17529"

-        x2="486.98099"

-        y2="213.2001"

-        id="linearGradient17810"

-        xlink:href="#XMLID_2274_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="translate(-177.1654,35.43307)" />

-     <linearGradient

-        x1="502.70749"

-        y1="115.3013"

-        x2="516.39001"

-        y2="127.1953"

-        id="linearGradient17812"

-        xlink:href="#XMLID_1749_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.9703,0.2419,-0.2419,0.9703,11.0227,-35.6159)" />

-     <linearGradient

-        x1="506.09909"

-        y1="-11.5137"

-        x2="527.99609"

-        y2="2.7063999"

-        id="linearGradient17814"

-        xlink:href="#XMLID_1752_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <linearGradient

-        x1="516.57672"

-        y1="-15.769"

-        x2="516.57672"

-        y2="0.84280002"

-        id="linearGradient17816"

-        xlink:href="#XMLID_1753_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <linearGradient

-        x1="505.62939"

-        y1="-14.9526"

-        x2="527.49402"

-        y2="-0.7536"

-        id="linearGradient17818"

-        xlink:href="#XMLID_1756_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <linearGradient

-        x1="502.70749"

-        y1="115.3013"

-        x2="516.39001"

-        y2="127.1953"

-        id="linearGradient17347"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.9703,0.2419,-0.2419,0.9703,11.0227,-35.6159)">

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0"

-          id="stop17349" />

-       <stop

-          style="stop-color:#96bad6;stop-opacity:1"

-          offset="1"

-          id="stop17351" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#5387BA" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#5387BA" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#96BAD6" />

-     </linearGradient>

-     <linearGradient

-        x1="516.57672"

-        y1="-15.769"

-        x2="516.57672"

-        y2="0.84280002"

-        id="linearGradient17379"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#b2b2b2;stop-opacity:1"

-          offset="0"

-          id="stop17381" />

-       <stop

-          style="stop-color:#f2f2f2;stop-opacity:1"

-          offset="1"

-          id="stop17383" />

-       <a:midPointStop

-          offset="0"

-          style="stop-color:#B2B2B2" />

-       <a:midPointStop

-          offset="0.5"

-          style="stop-color:#B2B2B2" />

-       <a:midPointStop

-          offset="1"

-          style="stop-color:#F2F2F2" />

-     </linearGradient>

-     <linearGradient

-        x1="502.70749"

-        y1="115.3013"

-        x2="516.39001"

-        y2="127.1953"

-        id="linearGradient17862"

-        xlink:href="#XMLID_1749_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.9703,0.2419,-0.2419,0.9703,-166.1427,-0.18283)" />

-     <linearGradient

-        x1="505.62939"

-        y1="-14.9526"

-        x2="527.49402"

-        y2="-0.7536"

-        id="linearGradient17864"

-        xlink:href="#XMLID_1756_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <defs

-        id="defs3859">

-       <polygon

-          points="465.54,213.52 481.94,217.46 482.74,216.71 487.46,198.05 471.08,194.07 470.26,194.83 465.54,213.52 "

-          id="XMLID_343_" />

-     </defs>

-     <linearGradient

-        x1="471.0806"

-        y1="201.07761"

-        x2="481.91711"

-        y2="210.4977"

-        id="linearGradient17389"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#6498c1;stop-opacity:1"

-          offset="0.005618"

-          id="stop17391" />

-       <stop

-          style="stop-color:#79a9cc;stop-opacity:1"

-          offset="0.2332"

-          id="stop17393" />

-       <stop

-          style="stop-color:#a4cde2;stop-opacity:1"

-          offset="0.74049997"

-          id="stop17395" />

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="1"

-          id="stop17397" />

-       <a:midPointStop

-          style="stop-color:#6498C1"

-          offset="5.618000e-003" />

-       <a:midPointStop

-          style="stop-color:#6498C1"

-          offset="0.4438" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="1" />

-     </linearGradient>

-     <clipPath

-        id="clipPath17400">

-       <use

-          id="use17402"

-          x="0"

-          y="0"

-          width="744.09448"

-          height="600"

-          xlink:href="#XMLID_343_" />

-     </clipPath>

-     <linearGradient

-        x1="505.62939"

-        y1="-14.9526"

-        x2="527.49402"

-        y2="-0.7536"

-        id="linearGradient17404"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0"

-          id="stop17406" />

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0.51120001"

-          id="stop17408" />

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0.64609998"

-          id="stop17410" />

-       <stop

-          style="stop-color:#16336e;stop-opacity:1"

-          offset="1"

-          id="stop17412" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5112" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.6461" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#16336E"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="506.09909"

-        y1="-11.5137"

-        x2="527.99609"

-        y2="2.7063999"

-        id="linearGradient17882"

-        xlink:href="#XMLID_1752_"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)" />

-     <defs

-        id="defs3826">

-       <polygon

-          points="463.52,216.14 480.56,220.24 481.36,219.5 483.03,202.04 469.05,196.69 468.24,197.45 463.52,216.14 "

-          id="XMLID_338_" />

-     </defs>

-     <linearGradient

-        x1="468.2915"

-        y1="204.7612"

-        x2="479.39871"

-        y2="214.4166"

-        id="linearGradient17357"

-        gradientUnits="userSpaceOnUse">

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0"

-          id="stop17359" />

-       <stop

-          style="stop-color:#96bad6;stop-opacity:1"

-          offset="1"

-          id="stop17361" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#96BAD6"

-          offset="1" />

-     </linearGradient>

-     <clipPath

-        id="clipPath17364">

-       <use

-          id="use17366"

-          x="0"

-          y="0"

-          width="744.09448"

-          height="600"

-          xlink:href="#XMLID_338_" />

-     </clipPath>

-     <linearGradient

-        x1="506.09909"

-        y1="-11.5137"

-        x2="527.99609"

-        y2="2.7063999"

-        id="linearGradient17368"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.6868,0.4269,-0.9821,0.821,111.6149,-5.7901)">

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0"

-          id="stop17370" />

-       <stop

-          style="stop-color:#b4daea;stop-opacity:1"

-          offset="0.51120001"

-          id="stop17372" />

-       <stop

-          style="stop-color:#5387ba;stop-opacity:1"

-          offset="0.64609998"

-          id="stop17374" />

-       <stop

-          style="stop-color:#16336e;stop-opacity:1"

-          offset="1"

-          id="stop17376" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5112" />

-       <a:midPointStop

-          style="stop-color:#B4DAEA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.6461" />

-       <a:midPointStop

-          style="stop-color:#5387BA"

-          offset="0.5" />

-       <a:midPointStop

-          style="stop-color:#16336E"

-          offset="1" />

-     </linearGradient>

-     <linearGradient

-        x1="296.4996"

-        y1="188.81061"

-        x2="317.32471"

-        y2="209.69398"

-        id="linearGradient2387"

-        xlink:href="#linearGradient2381"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.90776,0,0,0.90776,24.35648,49.24131)" />

-     <linearGradient

-        x1="296.4996"

-        y1="188.81061"

-        x2="317.32471"

-        y2="209.69398"

-        id="linearGradient5105"

-        xlink:href="#linearGradient2381"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.90776,0,0,0.90776,24.35648,49.24131)" />

-     <linearGradient

-        x1="296.4996"

-        y1="188.81061"

-        x2="317.32471"

-        y2="209.69398"

-        id="linearGradient5145"

-        xlink:href="#linearGradient2381"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.90776,0,0,0.90776,24.35648,49.24131)" />

-     <linearGradient

-        inkscape:collect="always"

-        xlink:href="#linearGradient2381"

-        id="linearGradient2371"

-        gradientUnits="userSpaceOnUse"

-        gradientTransform="matrix(0.90776,0,0,0.90776,24.35648,49.24131)"

-        x1="296.4996"

-        y1="188.81061"

-        x2="317.32471"

-        y2="209.69398" />

-   </defs>

-   <g

-      transform="matrix(0.437808,-0.437808,0.437808,0.437808,-220.8237,43.55311)"

-      id="g5089">

-     <path

-        d="M 8.4382985,-6.28125 C 7.8309069,-6.28125 4.125,-0.33238729 4.125,1.96875 L 4.125,28.6875 C 4.125,29.533884 4.7068159,29.8125 5.28125,29.8125 L 30.84375,29.8125 C 31.476092,29.8125 31.968751,29.319842 31.96875,28.6875 L 31.96875,23.46875 L 32.25,23.46875 C 32.74684,23.46875 33.156249,23.059339 33.15625,22.5625 L 33.15625,-5.375 C 33.15625,-5.8718398 32.74684,-6.28125 32.25,-6.28125 L 8.4382985,-6.28125 z "

-        transform="translate(282.8327,227.1903)"

-        style="fill:#5c5c4f;stroke:black;stroke-width:3.23021388;stroke-miterlimit:4;stroke-dasharray:none"

-        id="path5091" />

-     <rect

-        width="27.85074"

-        height="29.369793"

-        rx="1.1414107"

-        ry="1.1414107"

-        x="286.96509"

-        y="227.63805"

-        style="fill:#032c87"

-        id="rect5093" />

-     <path

-        d="M 288.43262,225.43675 L 313.67442,225.43675 L 313.67442,254.80655 L 287.29827,254.83069 L 288.43262,225.43675 z "

-        style="fill:white"

-        id="rect5095" />

-     <path

-        d="M 302.44536,251.73726 C 303.83227,259.59643 301.75225,263.02091 301.75225,263.02091 C 303.99609,261.41329 305.71651,259.54397 306.65747,257.28491 C 307.62455,259.47755 308.49041,261.71357 310.9319,263.27432 C 310.9319,263.27432 309.33686,256.07392 309.22047,251.73726 L 302.44536,251.73726 z "

-        style="fill:#a70000;fill-opacity:1;stroke-width:2"

-        id="path5097" />

-     <rect

-        width="25.241802"

-        height="29.736675"

-        rx="0.89682275"

-        ry="0.89682275"

-        x="290.73544"

-        y="220.92249"

-        style="fill:#809cc9"

-        id="rect5099" />

-     <path

-        d="M 576.47347,725.93939 L 582.84431,726.35441 L 583.25121,755.8725 C 581.35919,754.55465 576.39694,752.1117 574.98889,754.19149 L 574.98889,727.42397 C 574.98889,726.60151 575.65101,725.93939 576.47347,725.93939 z "

-        transform="matrix(0.499065,-0.866565,0,1,0,0)"

-        style="fill:#4573b3;fill-opacity:1"

-        id="rect5101" />

-     <path

-        d="M 293.2599,221.89363 L 313.99908,221.89363 C 314.45009,221.89363 314.81318,222.25673 314.81318,222.70774 C 315.02865,229.0361 295.44494,244.47124 292.44579,240.30491 L 292.44579,222.70774 C 292.44579,222.25673 292.80889,221.89363 293.2599,221.89363 z "

-        style="opacity:0.65536726;fill:url(#linearGradient2371);fill-opacity:1"

-        id="path5103" />

-   </g>

- </svg>

en-US/master-docinfo.xml en-US/Book_Info.xml
file renamed
+6 -22
@@ -1,14 +1,4 @@

- <?xml version='1.0' encoding='UTF-8' ?>

- <!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <bookinfo id="book-Defensive_Coding">

- 	<title>Defensive Coding</title>

- 	<subtitle>A Guide to Improving Software Security</subtitle>

- 	<edition>1</edition>

- 	<pubsnumber>1</pubsnumber>

- 	<productname>Fedora Security Team</productname>

- 	<productnumber></productnumber>

- 	<abstract>

+ <abstract>

  	  <para>

  	    This document provides guidelines for improving software

  	    security through secure coding.  It covers common
@@ -16,14 +6,8 @@

  	    concrete recommendations.

  	  </para>

  	</abstract>

- 	<corpauthor>

- 		<inlinemediaobject>

- 			<imageobject>

- 				<imagedata fileref="Common_Content/images/title_logo.svg" format="SVG" />

- 			</imageobject>

- 		</inlinemediaobject>

- 	</corpauthor>

- 	<xi:include href="Common_Content/Legal_Notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

-         <xi:include href="Author_Group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

- </bookinfo>

- 

+ <edition>1</edition>

+ <productname>Fedora Security Team</productname>

+ <productnumber></productnumber>

+ <pubsnumber>1</pubsnumber>

+ <subtitle>A Guide to Improving Software Security</subtitle> 

\ No newline at end of file

en-US/master.adoc
file added
+54
@@ -0,0 +1,54 @@

+ :doctype: book

+ :toc: left

+ :toclevels: 3

+ :source-highlighter: pygments

+ :pygments-style: friendly

+ :pygments-linenums-mode: inline

+ 

+ = Defensive Coding Guide

+ 

+ include::Book_Info.adoc[]

+ 

+ == Programming Languages

+ 

+ include::C.adoc[]

+ 

+ include::CXX.adoc[]

+ 

+ include::Java.adoc[]

+ 

+ include::Python.adoc[]

+ 

+ include::Shell.adoc[]

+ 

+ include::Go.adoc[]

+ 

+ include::Vala.adoc[]

+ 

+ == Specific Programming Tasks

+ 

+ include::Tasks-Library_Design.adoc[]

+ 

+ include::Tasks-Descriptors.adoc[]

+ 

+ include::Tasks-File_System.adoc[]

+ 

+ include::Tasks-Temporary_Files.adoc[]

+ 

+ include::Tasks-Processes.adoc[]

+ 

+ include::Tasks-Serialization.adoc[]

+ 

+ include::Tasks-Cryptography.adoc[]

+ 

+ include::Tasks-Packaging.adoc[]

+ 

+ == Implementing Security Features

+ 

+ include::Features-Authentication.adoc[]

+ 

+ include::Features-TLS.adoc[]

+ 

+ include::Features-HSM.adoc[]

+ 

+ include::Revision_History.adoc[]

en-US/schemas.xml
file removed
-4
@@ -1,4 +0,0 @@

- <?xml version="1.0"?>

- <locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">

-   <include rules="../schemas.xml"/>

- </locatingRules>

en-US/snippets/C-Arithmetic-add.xml
file removed
-21
@@ -1,21 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- void report_overflow(void);

- 

- int

- add(int a, int b)

- {

-   int result = a + b;

-   if (a &#60; 0 || b &#60; 0) {

-     return -1;

-   }

-   // The compiler can optimize away the following if statement.

-   if (result &#60; 0) {

-     report_overflow();

-   }

-   return result;

- }

- </programlisting>

en-US/snippets/C-Arithmetic-add_unsigned.xml
file removed
-17
@@ -1,17 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- void report_overflow(void);

- 

- unsigned

- add_unsigned(unsigned a, unsigned b)

- {

-   unsigned sum = a + b;

-   if (sum &#60; a) { // or sum &#60; b

-     report_overflow();

-   }

-   return sum;

- }

- </programlisting>

en-US/snippets/C-Arithmetic-mult.xml
file removed
-14
@@ -1,14 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- unsigned

- mul(unsigned a, unsigned b)

- {

-   if (b &#38;&#38; a &#62; ((unsigned)-1) / b) {

-     report_overflow();

-   }

-   return a * b;

- }

- </programlisting>

en-US/snippets/C-Globals-String_Array.xml
file removed
-12
@@ -1,12 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- static const char *const string_list[] = {

-   "first",

-   "second",

-   "third",

-   NULL

- };

- </programlisting>

en-US/snippets/C-Pointers-remaining.xml
file removed
-49
@@ -1,49 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- ssize_t

- extract_strings(const char *in, size_t inlen, char **out, size_t outlen)

- {

-   const char *inp = in;

-   const char *inend = in + inlen;

-   char **outp = out;

-   char **outend = out + outlen;

- 

-   while (inp != inend) {

-     size_t len;

-     char *s;

-     if (outp == outend) {

-       errno = ENOSPC;

-       goto err;

-     }

-     len = (unsigned char)*inp;

-     ++inp;

-     if (len &#62; (size_t)(inend - inp)) {

-       errno = EINVAL;

-       goto err;

-     }

-     s = malloc(len + 1);

-     if (s == NULL) {

-       goto err;

-     }

-     memcpy(s, inp, len);

-     inp += len;

-     s[len] = '\0';

-     *outp = s;

-     ++outp;

-   }

-   return outp - out;

- err:

-   {

-     int errno_old = errno;

-     while (out != outp) {

-       free(*out);

-       ++out;

-     }

-     errno = errno_old;

-   }

-   return -1;

- }

- </programlisting>

en-US/snippets/C-String-Functions-format.xml
file removed
-18
@@ -1,18 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- void log_format(const char *format, ...) __attribute__((format(printf, 1, 2)));

- 

- void

- log_format(const char *format, ...)

- {

-   char buf[1000];

-   va_list ap;

-   va_start(ap, format);

-   vsnprintf(buf, sizeof(buf), format, ap);

-   va_end(ap);

-   log_string(buf);

- }

- </programlisting>

en-US/snippets/C-String-Functions-snprintf-incremental.xml
file removed
-14
@@ -1,14 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- char buf[512];

- char *current = buf;

- const char *const end = buf + sizeof(buf);

- for (struct item *it = data; it-&#62;key; ++it) {

-   snprintf(current, end - current, "%s%s=%d",

- 	       current == buf ? "" : ", ", it-&#62;key, it-&#62;value);

-   current += strlen(current);

- }

- </programlisting>

en-US/snippets/C-String-Functions-snprintf.xml
file removed
-8
@@ -1,8 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- char fraction[30];

- snprintf(fraction, sizeof(fraction), "%d/%d", numerator, denominator);

- </programlisting>

en-US/snippets/C-String-Functions-strncat-as-strncpy.xml
file removed
-8
@@ -1,8 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- buf[0] = '\0';

- strncat(buf, data, sizeof(buf) - 1);

- </programlisting>

en-US/snippets/C-String-Functions-strncat-emulation.xml
file removed
-9
@@ -1,9 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- char buf[10];

- snprintf(buf, sizeof(buf), "%s", prefix);

- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s", data);

- </programlisting>

en-US/snippets/C-String-Functions-strncat-merged.xml
file removed
-7
@@ -1,7 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- snprintf(buf, sizeof(buf), "%s%s", prefix, data);

- </programlisting>

en-US/snippets/C-String-Functions-strncpy.xml
file removed
-9
@@ -1,9 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- char buf[10];

- strncpy(buf, data, sizeof(buf));

- buf[sizeof(buf) - 1] = '\0';

- </programlisting>

en-US/snippets/Features-TLS-Client-GNUTLS-Connect.xml
file removed
-50
@@ -1,50 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Create the session object.

- gnutls_session_t session;

- ret = gnutls_init(&#38;session, GNUTLS_CLIENT);

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_init: %s\n",

- 	    gnutls_strerror(ret));

-   exit(1);

- }

- 

- // Configure the cipher preferences.

- const char *errptr = NULL;

- ret = gnutls_priority_set_direct(session, "NORMAL", &#38;errptr);

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_priority_set_direct: %s\n"

- 	    "error: at: \"%s\"\n", gnutls_strerror(ret), errptr);

-   exit(1);

- }

- 

- // Install the trusted certificates.

- ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_credentials_set: %s\n",

- 	    gnutls_strerror(ret));

-   exit(1);

- }

- 

- // Associate the socket with the session object and set the server

- // name.

- gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)(uintptr_t)sockfd);

- ret = gnutls_server_name_set(session, GNUTLS_NAME_DNS,

- 			       host, strlen(host));

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_server_name_set: %s\n",

- 	    gnutls_strerror(ret));

-   exit(1);

- }

- 

- // Establish the session.

- ret = gnutls_handshake(session);

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_handshake: %s\n",

- 	    gnutls_strerror(ret));

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-Client-GNUTLS-Credentials.xml
file removed
-29
@@ -1,29 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Load the trusted CA certificates.

- gnutls_certificate_credentials_t cred = NULL;

- int ret = gnutls_certificate_allocate_credentials (&#38;cred);

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_certificate_allocate_credentials: %s\n",

- 	    gnutls_strerror(ret));

-   exit(1);

- }

- // gnutls_certificate_set_x509_system_trust needs GNUTLS version 3.0

- // or newer, so we hard-code the path to the certificate store

- // instead.

- static const char ca_bundle[] = "/etc/ssl/certs/ca-bundle.crt";

- ret = gnutls_certificate_set_x509_trust_file

-   (cred, ca_bundle, GNUTLS_X509_FMT_PEM);

- if (ret == 0) {

-   fprintf(stderr, "error: no certificates found in: %s\n", ca_bundle);

-   exit(1);

- }

- if (ret &#60; 0) {

-   fprintf(stderr, "error: gnutls_certificate_set_x509_trust_files(%s): %s\n",

- 	    ca_bundle, gnutls_strerror(ret));

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-Client-GNUTLS-Match.xml
file removed
-30
@@ -1,30 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Match the peer certificate against the host name.

- // We can only obtain a set of DER-encoded certificates from the

- // session object, so we have to re-parse the peer certificate into

- // a certificate object.

- gnutls_x509_crt_t cert;

- ret = gnutls_x509_crt_init(&#38;cert);

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_x509_crt_init: %s\n",

- 	    gnutls_strerror(ret));

-   exit(1);

- }

- // The peer certificate is the first certificate in the list.

- ret = gnutls_x509_crt_import(cert, certs, GNUTLS_X509_FMT_DER);

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_x509_crt_import: %s\n",

- 	    gnutls_strerror(ret));

-   exit(1);

- }

- ret = gnutls_x509_crt_check_hostname(cert, host);

- if (ret == 0 &#38;&#38; !certificate_host_name_override(certs[0], host)) {

-   fprintf(stderr, "error: host name does not match certificate\n");

-   exit(1);

- }

- gnutls_x509_crt_deinit(cert);

- </programlisting>

en-US/snippets/Features-TLS-Client-GNUTLS-Verify.xml
file removed
-42
@@ -1,42 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Obtain the server certificate chain.  The server certificate

- // itself is stored in the first element of the array.

- unsigned certslen = 0;

- const gnutls_datum_t *const certs =

-   gnutls_certificate_get_peers(session, &#38;certslen);

- if (certs == NULL || certslen == 0) {

-   fprintf(stderr, "error: could not obtain peer certificate\n");

-   exit(1);

- }

- 

- // Validate the certificate chain.

- unsigned status = (unsigned)-1;

- ret = gnutls_certificate_verify_peers2(session, &#38;status);

- if (ret != GNUTLS_E_SUCCESS) {

-   fprintf(stderr, "error: gnutls_certificate_verify_peers2: %s\n",

- 	    gnutls_strerror(ret));

-   exit(1);

- }

- if (status != 0 &#38;&#38; !certificate_validity_override(certs[0])) {

-   gnutls_datum_t msg;

- #if GNUTLS_VERSION_AT_LEAST_3_1_4

-   int type = gnutls_certificate_type_get (session);

-   ret = gnutls_certificate_verification_status_print(status, type, &#38;out, 0);

- #else

-   ret = -1;

- #endif

-   if (ret == 0) {

-     fprintf(stderr, "error: %s\n", msg.data);

-     gnutls_free(msg.data);

-     exit(1);

-   } else {

-     fprintf(stderr, "error: certificate validation failed with code 0x%x\n",

- 	      status);

-     exit(1);

-   }

- }

- </programlisting>

en-US/snippets/Features-TLS-Client-NSS-Close.xml
file removed
-15
@@ -1,15 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Send close_notify alert.

- if (PR_Shutdown(nspr, PR_SHUTDOWN_BOTH) != PR_SUCCESS) {

-   const PRErrorCode err = PR_GetError();

-   fprintf(stderr, "error: PR_Read error %d: %s\n",

- 	    err, PR_ErrorToName(err));

-   exit(1);

- }

- // Closes the underlying POSIX file descriptor, too.

- PR_Close(nspr);

- </programlisting>

en-US/snippets/Features-TLS-Client-NSS-Connect.xml
file removed
-80
@@ -1,80 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Wrap the POSIX file descriptor.  This is an internal NSPR

- // function, but it is very unlikely to change.

- PRFileDesc* nspr = PR_ImportTCPSocket(sockfd);

- sockfd = -1; // Has been taken over by NSPR.

- 

- // Add the SSL layer.

- {

-   PRFileDesc *model = PR_NewTCPSocket();

-   PRFileDesc *newfd = SSL_ImportFD(NULL, model);

-   if (newfd == NULL) {

-     const PRErrorCode err = PR_GetError();

-     fprintf(stderr, "error: NSPR error code %d: %s\n",

- 	      err, PR_ErrorToName(err));

-     exit(1);

-   }

-   model = newfd;

-   newfd = NULL;

-   if (SSL_OptionSet(model, SSL_ENABLE_SSL2, PR_FALSE) != SECSuccess) {

-     const PRErrorCode err = PR_GetError();

-     fprintf(stderr, "error: set SSL_ENABLE_SSL2 error %d: %s\n",

- 	      err, PR_ErrorToName(err));

-     exit(1);

-   }

-   if (SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, PR_FALSE) != SECSuccess) {

-     const PRErrorCode err = PR_GetError();

-     fprintf(stderr, "error: set SSL_V2_COMPATIBLE_HELLO error %d: %s\n",

- 	      err, PR_ErrorToName(err));

-     exit(1);

-   }

-   if (SSL_OptionSet(model, SSL_ENABLE_DEFLATE, PR_FALSE) != SECSuccess) {

-     const PRErrorCode err = PR_GetError();

-     fprintf(stderr, "error: set SSL_ENABLE_DEFLATE error %d: %s\n",

- 	      err, PR_ErrorToName(err));

-     exit(1);

-   }

- 

-   // Allow overriding invalid certificate.

-   if (SSL_BadCertHook(model, bad_certificate, (char *)host) != SECSuccess) {

-     const PRErrorCode err = PR_GetError();

-     fprintf(stderr, "error: SSL_BadCertHook error %d: %s\n",

- 	      err, PR_ErrorToName(err));

-     exit(1);

-   }

- 

-   newfd = SSL_ImportFD(model, nspr);

-   if (newfd == NULL) {

-     const PRErrorCode err = PR_GetError();

-     fprintf(stderr, "error: SSL_ImportFD error %d: %s\n",

- 	      err, PR_ErrorToName(err));

-     exit(1);

-   }

-   nspr = newfd;

-   PR_Close(model);

- }

- 

- // Perform the handshake.

- if (SSL_ResetHandshake(nspr, PR_FALSE) != SECSuccess) {

-   const PRErrorCode err = PR_GetError();

-   fprintf(stderr, "error: SSL_ResetHandshake error %d: %s\n",

- 	    err, PR_ErrorToName(err));

-   exit(1);

- }

- if (SSL_SetURL(nspr, host) != SECSuccess) {

-   const PRErrorCode err = PR_GetError();

-   fprintf(stderr, "error: SSL_SetURL error %d: %s\n",

- 	    err, PR_ErrorToName(err));

-   exit(1);

- }

- if (SSL_ForceHandshake(nspr) != SECSuccess) {

-   const PRErrorCode err = PR_GetError();

-   fprintf(stderr, "error: SSL_ForceHandshake error %d: %s\n",

- 	    err, PR_ErrorToName(err));

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenJDK-Connect.xml
file removed
-26
@@ -1,26 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- // Create the socket and connect it at the TCP layer.

- SSLSocket socket = (SSLSocket) ctx.getSocketFactory()

-     .createSocket(host, port);

- 

- // Disable the Nagle algorithm.

- socket.setTcpNoDelay(true);

- 

- // Adjust ciphers and protocols.

- socket.setSSLParameters(params);

- 

- // Perform the handshake.

- socket.startHandshake();

- 

- // Validate the host name.  The match() method throws

- // CertificateException on failure.

- X509Certificate peer = (X509Certificate)

-     socket.getSession().getPeerCertificates()[0];

- // This is the only way to perform host name checking on OpenJDK 6.

- HostnameChecker.getInstance(HostnameChecker.TYPE_TLS).match(

-     host, peer);

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenJDK-Context.xml
file removed
-26
@@ -1,26 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- // Create the context.  Specify the SunJSSE provider to avoid

- // picking up third-party providers.  Try the TLS 1.2 provider

- // first, then fall back to TLS 1.0.

- SSLContext ctx;

- try {

-     ctx = SSLContext.getInstance("TLSv1.2", "SunJSSE");

- } catch (NoSuchAlgorithmException e) {

-     try {

-         ctx = SSLContext.getInstance("TLSv1", "SunJSSE");

-     } catch (NoSuchAlgorithmException e1) {

-         // The TLS 1.0 provider should always be available.

-         throw new AssertionError(e1);

-     } catch (NoSuchProviderException e1) {

-         throw new AssertionError(e1);

-     } 

- } catch (NoSuchProviderException e) {

-     // The SunJSSE provider should always be available.

-     throw new AssertionError(e);

- }

- ctx.init(null, null, null);

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenJDK-Context_For_Cert.xml
file removed
-22
@@ -1,22 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- SSLContext ctx;

- try {

-     ctx = SSLContext.getInstance("TLSv1.2", "SunJSSE");

- } catch (NoSuchAlgorithmException e) {

-     try {

-         ctx = SSLContext.getInstance("TLSv1", "SunJSSE");

-     } catch (NoSuchAlgorithmException e1) {

-         throw new AssertionError(e1);

-     } catch (NoSuchProviderException e1) {

-         throw new AssertionError(e1);

-     }

- } catch (NoSuchProviderException e) {

-     throw new AssertionError(e);

- }

- MyTrustManager tm = new MyTrustManager(certHash);

- ctx.init(null, new TrustManager[] {tm}, null);

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenJDK-Hostname.xml
file removed
-7
@@ -1,7 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- params.setEndpointIdentificationAlgorithm("HTTPS");

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenJDK-Import.xml
file removed
-18
@@ -1,18 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- import java.security.NoSuchAlgorithmException;

- import java.security.NoSuchProviderException;

- import java.security.cert.CertificateEncodingException;

- import java.security.cert.CertificateException;

- import java.security.cert.X509Certificate;

- import javax.net.ssl.SSLContext;

- import javax.net.ssl.SSLParameters;

- import javax.net.ssl.SSLSocket;

- import javax.net.ssl.TrustManager;

- import javax.net.ssl.X509TrustManager;

- 

- import sun.security.util.HostnameChecker;

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenJDK-MyTrustManager.xml
file removed
-38
@@ -1,38 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- public class MyTrustManager implements X509TrustManager {

-     private final byte[] certHash;

- 

-     public MyTrustManager(byte[] certHash) throws Exception {

-         this.certHash = certHash;

-     }

- 

-     @Override

-     public void checkClientTrusted(X509Certificate[] chain, String authType)

-             throws CertificateException {

-         throw new UnsupportedOperationException();

-     }

- 

-     @Override

-     public void checkServerTrusted(X509Certificate[] chain,

-             String authType) throws CertificateException {

-         byte[] digest = getCertificateDigest(chain[0]);

-         String digestHex = formatHex(digest);

- 

-         if (Arrays.equals(digest, certHash)) {

-             System.err.println("info: accepting certificate: " + digestHex);

-         } else {

-             throw new CertificateException("certificate rejected: "  +

-                     digestHex);

-         }

-     }

- 

-     @Override

-     public X509Certificate[] getAcceptedIssuers() {

-         return new X509Certificate[0];

-     }

- }

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenJDK-Use.xml
file removed
-11
@@ -1,11 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- socket.getOutputStream().write("GET / HTTP/1.0\r\n\r\n"

-     .getBytes(Charset.forName("UTF-8")));

- byte[] buffer = new byte[4096];

- int count = socket.getInputStream().read(buffer);

- System.out.write(buffer, 0, count);

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenSSL-CTX.xml
file removed
-71
@@ -1,71 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Configure a client connection context.  Send a hendshake for the

- // highest supported TLS version, and disable compression.

- const SSL_METHOD *const req_method = SSLv23_client_method();

- SSL_CTX *const ctx = SSL_CTX_new(req_method);

- if (ctx == NULL) {

-   ERR_print_errors(bio_err);

-   exit(1);

- }

- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION);

- 

- // Adjust the ciphers list based on a whitelist.  First enable all

- // ciphers of at least medium strength, to get the list which is

- // compiled into OpenSSL.

- if (SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM") != 1) {

-   ERR_print_errors(bio_err);

-   exit(1);

- }

- {

-   // Create a dummy SSL session to obtain the cipher list.

-   SSL *ssl = SSL_new(ctx);

-   if (ssl == NULL) {

-     ERR_print_errors(bio_err);

-     exit(1);

-   }

-   STACK_OF(SSL_CIPHER) *active_ciphers = SSL_get_ciphers(ssl);

-   if (active_ciphers == NULL) {

-     ERR_print_errors(bio_err);

-     exit(1);

-   }

-   // Whitelist of candidate ciphers.

-   static const char *const candidates[] =  {

-     "AES128-GCM-SHA256", "AES128-SHA256", "AES256-SHA256", // strong ciphers

-     "AES128-SHA", "AES256-SHA", // strong ciphers, also in older versions

-     "RC4-SHA", "RC4-MD5", // backwards compatibility, supposed to be weak

-     "DES-CBC3-SHA", "DES-CBC3-MD5", // more backwards compatibility

-     NULL

-   };

-   // Actually selected ciphers.

-   char ciphers[300];

-   ciphers[0] = '\0';

-   for (const char *const *c = candidates; *c; ++c) {

-     for (int i = 0; i &#60; sk_SSL_CIPHER_num(active_ciphers); ++i) {

- 	if (strcmp(SSL_CIPHER_get_name(sk_SSL_CIPHER_value(active_ciphers, i)),

- 		   *c) == 0) {

- 	  if (*ciphers) {

- 	    strcat(ciphers, ":");

- 	  }

- 	  strcat(ciphers, *c);

- 	  break;

- 	}

-     }

-   }

-   SSL_free(ssl);

-   // Apply final cipher list.

-   if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1) {

-     ERR_print_errors(bio_err);

-     exit(1);

-   }

- }

- 

- // Load the set of trusted root certificates.

- if (!SSL_CTX_set_default_verify_paths(ctx)) {

-   ERR_print_errors(bio_err);

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenSSL-Connect.xml
file removed
-55
@@ -1,55 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Create the connection object.

- SSL *ssl = SSL_new(ctx);

- if (ssl == NULL) {

-   ERR_print_errors(bio_err);

-   exit(1);

- }

- SSL_set_fd(ssl, sockfd);

- 

- // Enable the ServerNameIndication extension

- if (!SSL_set_tlsext_host_name(ssl, host)) {

-   ERR_print_errors(bio_err);

-   exit(1);

- }

- 

- // Perform the TLS handshake with the server.

- ret = SSL_connect(ssl);

- if (ret != 1) {

-   // Error status can be 0 or negative.

-   ssl_print_error_and_exit(ssl, "SSL_connect", ret);

- }

- 

- // Obtain the server certificate.

- X509 *peercert = SSL_get_peer_certificate(ssl);

- if (peercert == NULL) {

-   fprintf(stderr, "peer certificate missing");

-   exit(1);

- }

- 

- // Check the certificate verification result.  Allow an explicit

- // certificate validation override in case verification fails.

- int verifystatus = SSL_get_verify_result(ssl);

- if (verifystatus != X509_V_OK &#38;&#38; !certificate_validity_override(peercert)) {

-   fprintf(stderr, "SSL_connect: verify result: %s\n",

- 	    X509_verify_cert_error_string(verifystatus));

-   exit(1);

- }

- 

- // Check if the server certificate matches the host name used to

- // establish the connection.

- // FIXME: Currently needs OpenSSL 1.1.

- if (X509_check_host(peercert, (const unsigned char *)host, strlen(host),

- 		      0) != 1

-     &#38;&#38; !certificate_host_name_override(peercert, host)) {

-   fprintf(stderr, "SSL certificate does not match host name\n");

-   exit(1);

- }

- 

- X509_free(peercert);

- 

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenSSL-Connection-Use.xml
file removed
-15
@@ -1,15 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- const char *const req = "GET / HTTP/1.0\r\n\r\n";

- if (SSL_write(ssl, req, strlen(req)) &#60; 0) {

-   ssl_print_error_and_exit(ssl, "SSL_write", ret);

- }

- char buf[4096];

- ret = SSL_read(ssl, buf, sizeof(buf));

- if (ret &#60; 0) {

-   ssl_print_error_and_exit(ssl, "SSL_read", ret);

- }

- </programlisting>

en-US/snippets/Features-TLS-Client-OpenSSL-Init.xml
file removed
-13
@@ -1,13 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // The following call prints an error message and calls exit() if

- // the OpenSSL configuration file is unreadable.

- OPENSSL_config(NULL);

- // Provide human-readable error messages.

- SSL_load_error_strings();

- // Register ciphers.

- SSL_library_init();

- </programlisting>

en-US/snippets/Features-TLS-Client-Python-Connect.xml
file removed
-14
@@ -1,14 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Python">

- sock = ssl.wrap_socket(sock,

-                        ciphers="HIGH:-aNULL:-eNULL:-PSK:RC4-SHA:RC4-MD5",

-                        ssl_version=ssl.PROTOCOL_TLSv1,

-                        cert_reqs=ssl.CERT_REQUIRED,

-                        ca_certs='/etc/ssl/certs/ca-bundle.crt')

- # getpeercert() triggers the handshake as a side effect.

- if not check_host_name(sock.getpeercert(), host):

-     raise IOError("peer certificate does not match host name")

- </programlisting>

en-US/snippets/Features-TLS-Client-Python-check_host_name.xml
file removed
-29
@@ -1,29 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Python">

- def check_host_name(peercert, name):

-     """Simple certificate/host name checker.  Returns True if the

-     certificate matches, False otherwise.  Does not support

-     wildcards."""

-     # Check that the peer has supplied a certificate.

-     # None/{} is not acceptable.

-     if not peercert:

-         return False

-     if peercert.has_key("subjectAltName"):

-         for typ, val in peercert["subjectAltName"]:

-             if typ == "DNS" and val == name:

-                 return True

-     else:

-         # Only check the subject DN if there is no subject alternative

-         # name.

-         cn = None

-         for attr, val in peercert["subject"]:

-             # Use most-specific (last) commonName attribute.

-             if attr == "commonName":

-                 cn = val

-         if cn is not None:

-             return cn == name

-     return False

- </programlisting>

en-US/snippets/Features-TLS-GNUTLS-Credentials-Close.xml
file removed
-7
@@ -1,7 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- gnutls_certificate_free_credentials(cred);

- </programlisting>

en-US/snippets/Features-TLS-GNUTLS-Disconnect.xml
file removed
-14
@@ -1,14 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Initiate an orderly connection shutdown.

- ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);

- if (ret &#60; 0) {

-   fprintf(stderr, "error: gnutls_bye: %s\n", gnutls_strerror(ret));

-   exit(1);

- }

- // Free the session object.

- gnutls_deinit(session);

- </programlisting>

en-US/snippets/Features-TLS-GNUTLS-Init.xml
file removed
-7
@@ -1,7 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- gnutls_global_init();

- </programlisting>

en-US/snippets/Features-TLS-GNUTLS-Use.xml
file removed
-18
@@ -1,18 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- char buf[4096];

- snprintf(buf, sizeof(buf), "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", host);

- ret = gnutls_record_send(session, buf, strlen(buf));

- if (ret &#60; 0) {

-   fprintf(stderr, "error: gnutls_record_send: %s\n", gnutls_strerror(ret));

-   exit(1);

- }

- ret = gnutls_record_recv(session, buf, sizeof(buf));

- if (ret &#60; 0) {

-   fprintf(stderr, "error: gnutls_record_recv: %s\n", gnutls_strerror(ret));

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-NSS-Close.xml
file removed
-8
@@ -1,8 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- SECMOD_DestroyModule(module);

- NSS_ShutdownContext(ctx);

- </programlisting>

en-US/snippets/Features-TLS-NSS-Includes.xml
file removed
-20
@@ -1,20 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // NSPR include files

- #include &#60;prerror.h&#62;

- #include &#60;prinit.h&#62;

- 

- // NSS include files

- #include &#60;nss.h&#62;

- #include &#60;pk11pub.h&#62;

- #include &#60;secmod.h&#62;

- #include &#60;ssl.h&#62;

- #include &#60;sslproto.h&#62;

- 

- // Private API, no other way to turn a POSIX file descriptor into an

- // NSPR handle.

- NSPR_API(PRFileDesc*) PR_ImportTCPSocket(int);

- </programlisting>

en-US/snippets/Features-TLS-NSS-Init.xml
file removed
-63
@@ -1,63 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);

- NSSInitContext *const ctx =

-   NSS_InitContext("sql:/etc/pki/nssdb", "", "", "", NULL,

- 		    NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);

- if (ctx == NULL) {

-   const PRErrorCode err = PR_GetError();

-   fprintf(stderr, "error: NSPR error code %d: %s\n",

- 	    err, PR_ErrorToName(err));

-   exit(1);

- }

- 

- // Ciphers to enable.

- static const PRUint16 good_ciphers[] = {

-   TLS_RSA_WITH_AES_128_CBC_SHA,

-   TLS_RSA_WITH_AES_256_CBC_SHA,

-   SSL_RSA_WITH_3DES_EDE_CBC_SHA,

-   SSL_NULL_WITH_NULL_NULL // sentinel

- };

- 

- // Check if the current policy allows any strong ciphers.  If it

- // doesn't, set the cipher suite policy.  This is not thread-safe

- // and has global impact.  Consequently, we only do it if absolutely

- // necessary.

- int found_good_cipher = 0;

- for (const PRUint16 *p = good_ciphers; *p != SSL_NULL_WITH_NULL_NULL;

-      ++p) {

-   PRInt32 policy;

-   if (SSL_CipherPolicyGet(*p, &#38;policy) != SECSuccess) {

-     const PRErrorCode err = PR_GetError();

-     fprintf(stderr, "error: policy for cipher %u: error %d: %s\n",

- 	      (unsigned)*p, err, PR_ErrorToName(err));

-     exit(1);

-   }

-   if (policy == SSL_ALLOWED) {

-     fprintf(stderr, "info: found cipher %x\n", (unsigned)*p);

-     found_good_cipher = 1;

-     break;

-   }

- }

- if (!found_good_cipher) {

-   if (NSS_SetDomesticPolicy() != SECSuccess) {

-     const PRErrorCode err = PR_GetError();

-     fprintf(stderr, "error: NSS_SetDomesticPolicy: error %d: %s\n",

- 	      err, PR_ErrorToName(err));

-     exit(1);

-   }

- }

- 

- // Initialize the trusted certificate store.

- char module_name[] = "library=libnssckbi.so name=\"Root Certs\"";

- SECMODModule *module = SECMOD_LoadUserModule(module_name, NULL, PR_FALSE);

- if (module == NULL || !module-&#62;loaded) {

-   const PRErrorCode err = PR_GetError();

-   fprintf(stderr, "error: NSPR error code %d: %s\n",

- 	    err, PR_ErrorToName(err));

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-NSS-Use.xml
file removed
-22
@@ -1,22 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- char buf[4096];

- snprintf(buf, sizeof(buf), "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", host);

- PRInt32 ret = PR_Write(nspr, buf, strlen(buf));

- if (ret &#60; 0) {

-   const PRErrorCode err = PR_GetError();

-   fprintf(stderr, "error: PR_Write error %d: %s\n",

- 	    err, PR_ErrorToName(err));

-   exit(1);

- }

- ret = PR_Read(nspr, buf, sizeof(buf));

- if (ret &#60; 0) {

-   const PRErrorCode err = PR_GetError();

-   fprintf(stderr, "error: PR_Read error %d: %s\n",

- 	    err, PR_ErrorToName(err));

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-Nagle.xml
file removed
-12
@@ -1,12 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- const int val = 1;

- int ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &#38;val, sizeof(val));

- if (ret &#60; 0) {

-   perror("setsockopt(TCP_NODELAY)");

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-OpenJDK-Parameters.xml
file removed
-27
@@ -1,27 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- // Prepare TLS parameters.  These have to applied to every TLS

- // socket before the handshake is triggered.

- SSLParameters params = ctx.getDefaultSSLParameters();

- // Do not send an SSL-2.0-compatible Client Hello.

- ArrayList&#60;String&#62; protocols = new ArrayList&#60;String&#62;(

-     Arrays.asList(params.getProtocols()));

- protocols.remove("SSLv2Hello");

- params.setProtocols(protocols.toArray(new String[protocols.size()]));

- // Adjust the supported ciphers.

- ArrayList&#60;String&#62; ciphers = new ArrayList&#60;String&#62;(

-     Arrays.asList(params.getCipherSuites()));

- ciphers.retainAll(Arrays.asList(

-     "TLS_RSA_WITH_AES_128_CBC_SHA256",

-     "TLS_RSA_WITH_AES_256_CBC_SHA256",

-     "TLS_RSA_WITH_AES_256_CBC_SHA",

-     "TLS_RSA_WITH_AES_128_CBC_SHA",

-     "SSL_RSA_WITH_3DES_EDE_CBC_SHA",

-     "SSL_RSA_WITH_RC4_128_SHA1",

-     "SSL_RSA_WITH_RC4_128_MD5",

-     "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"));

- params.setCipherSuites(ciphers.toArray(new String[ciphers.size()]));

- </programlisting>

en-US/snippets/Features-TLS-OpenSSL-Connection-Close.xml
file removed
-30
@@ -1,30 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Send the close_notify alert.

- ret = SSL_shutdown(ssl);

- switch (ret) {

- case 1:

-   // A close_notify alert has already been received.

-   break;

- case 0:

-   // Wait for the close_notify alert from the peer.

-   ret = SSL_shutdown(ssl);

-   switch (ret) {

-   case 0:

-     fprintf(stderr, "info: second SSL_shutdown returned zero\n");

-     break;

-   case 1:

-     break;

-   default:

-     ssl_print_error_and_exit(ssl, "SSL_shutdown 2", ret);

-   }

-   break;

- default:

-   ssl_print_error_and_exit(ssl, "SSL_shutdown 1", ret);

- }

- SSL_free(ssl);

- close(sockfd);

- </programlisting>

en-US/snippets/Features-TLS-OpenSSL-Context-Close.xml
file removed
-7
@@ -1,7 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- SSL_CTX_free(ctx);

- </programlisting>

en-US/snippets/Features-TLS-OpenSSL-Errors.xml
file removed
-31
@@ -1,31 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- static void __attribute__((noreturn))

- ssl_print_error_and_exit(SSL *ssl, const char *op, int ret)

- {

-   int subcode = SSL_get_error(ssl, ret);

-   switch (subcode) {

-   case SSL_ERROR_NONE:

-     fprintf(stderr, "error: %s: no error to report\n", op);

-     break;

-   case SSL_ERROR_WANT_READ:

-   case SSL_ERROR_WANT_WRITE:

-   case SSL_ERROR_WANT_X509_LOOKUP:

-   case SSL_ERROR_WANT_CONNECT:

-   case SSL_ERROR_WANT_ACCEPT:

-     fprintf(stderr, "error: %s: invalid blocking state %d\n", op, subcode);

-     break;

-   case SSL_ERROR_SSL:

-     fprintf(stderr, "error: %s: TLS layer problem\n", op);

-   case SSL_ERROR_SYSCALL:

-     fprintf(stderr, "error: %s: system call failed: %s\n", op, strerror(errno));

-     break;

-   case SSL_ERROR_ZERO_RETURN:

-     fprintf(stderr, "error: %s: zero return\n", op);

-   }

-   exit(1);

- }

- </programlisting>

en-US/snippets/Features-TLS-Python-Close.xml
file removed
-7
@@ -1,7 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Python">

- sock.close()

- </programlisting>

en-US/snippets/Features-TLS-Python-Use.xml
file removed
-8
@@ -1,8 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Python">

- sock.write("GET / HTTP/1.1\r\nHost: " + host + "\r\n\r\n")

- print sock.read()

- </programlisting>

en-US/snippets/Go-Error_Handling-IO.xml
file removed
-25
@@ -1,25 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- func IOError(r io.Reader, buf []byte, processor Processor,

- 	handler ErrorHandler) (message string, err error) {

- 	n, err := r.Read(buf)

- 	// First check for available data.

- 	if n &#62; 0 {

- 		message, err = processor.Process(buf[0:n])

- 		// Regular error handling.

- 		if err != nil {

- 			handler.Handle(err)

- 			return "", err

- 		}

- 	}

- 	// Then handle any error.

- 	if err != nil {

- 		handler.Handle(err)

- 		return "", err

- 	}

- 	return

- }

- </programlisting>

en-US/snippets/Go-Error_Handling-Regular.xml
file removed
-23
@@ -1,23 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- type Processor interface {

- 	Process(buf []byte) (message string, err error)

- }

- 

- type ErrorHandler interface {

- 	Handle(err error)

- }

- 

- func RegularError(buf []byte, processor Processor,

- 	handler ErrorHandler) (message string, err error) {

- 	message, err = processor.Process(buf)

- 	if err != nil {

- 		handler.Handle(err)

- 		return "", err

- 	}

- 	return

- }

- </programlisting>

en-US/snippets/Java-Finally.xml
file removed
-12
@@ -1,12 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- InputStream in = new BufferedInputStream(new FileInputStream(path));

- try {

-     readFile(in);

- } finally {

-     in.close();

- }

- </programlisting>

en-US/snippets/Java-JNI-Pointers.xml
file removed
-36
@@ -1,36 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- JNIEXPORT jint JNICALL Java_sum

-   (JNIEnv *jEnv, jclass clazz, jbyteArray buffer, jint offset, jint length)

- {

-   assert(sizeof(jint) == sizeof(unsigned));

-   if (offset &#60; 0 || length &#60; 0) {

-     (*jEnv)-&#62;ThrowNew(jEnv, arrayIndexOutOfBoundsExceptionClass,

- 		      "negative offset/length");

-     return 0;

-   }

-   unsigned uoffset = offset;

-   unsigned ulength = length;

-   // This cannot overflow because of the check above.

-   unsigned totallength = uoffset + ulength;

-   unsigned actuallength = (*jEnv)-&#62;GetArrayLength(jEnv, buffer);

-   if (totallength &#62; actuallength) {

-     (*jEnv)-&#62;ThrowNew(jEnv, arrayIndexOutOfBoundsExceptionClass,

- 		      "offset + length too large");

-     return 0;

-   }

-   unsigned char *ptr = (*jEnv)-&#62;GetPrimitiveArrayCritical(jEnv, buffer, 0);

-   if (ptr == NULL) {

-     return 0;

-   }

-   unsigned long long sum = 0;

-   for (unsigned char *p = ptr + uoffset, *end = p + ulength; p != end; ++p) {

-     sum += *p;

-   }

-   (*jEnv)-&#62;ReleasePrimitiveArrayCritical(jEnv, buffer, ptr, 0);

-   return sum;

- }

- </programlisting>

en-US/snippets/Java-Language-ReadArray.xml
file removed
-39
@@ -1,39 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- static byte[] readBytes(InputStream in, int length) throws IOException {

- 	final int startSize = 65536;

-     byte[] b = new byte[Math.min(length, startSize)];

-     int filled = 0;

-     while (true) {

-         int remaining = b.length - filled;

- 	    readFully(in, b, filled, remaining);

-         if (b.length == length) {

-             break;

-         }

-         filled = b.length;

-         if (length - b.length &#60;= b.length) {

-             // Allocate final length.  Condition avoids overflow.

-             b = Arrays.copyOf(b, length);

-         } else {

-             b = Arrays.copyOf(b, b.length * 2);

-         }

-     }

-     return b;

- }

- 

- static void readFully(InputStream in,byte[] b, int off, int len)

- 	    throws IOException {

- 	int startlen = len;

-     while (len &#62; 0) {

-         int count = in.read(b, off, len);

-         if (count &#60; 0) {

-             throw new EOFException();

-         }

-         off += count;

-         len -= count;

-     }

- }

- </programlisting>

en-US/snippets/Java-SecurityManager-Callback.xml
file removed
-40
@@ -1,40 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- interface Callback&#60;T&#62; {

- 	T call(boolean flag);

- }

- 

- class CallbackInvoker&#60;T&#62; {

- 	private final AccessControlContext context;

- 	Callback&#60;T&#62; callback;

- 

- 	CallbackInvoker(Callback&#60;T&#62; callback) {

- 	    context = AccessController.getContext();

- 	    this.callback = callback;

- 	}

- 

- 	public T invoke() {

- 	    // Obtain increased privileges.

- 	    return AccessController.doPrivileged(new PrivilegedAction&#60;T&#62;() {

- 		    @Override

- 		    public T run() {

- 			// This operation would fail without

- 			// additional privileges.

- 			final boolean flag = Boolean.getBoolean("some.property");

- 

- 			// Restore the original privileges.

- 			return AccessController.doPrivileged(

-                         new PrivilegedAction&#60;T&#62;() {

- 				@Override

- 				public T run() {

- 				    return callback.call(flag);

- 				}

- 			    }, context);

- 		    }

- 		});

- 	}

- }

- </programlisting>

en-US/snippets/Java-SecurityManager-CurrentDirectory.xml
file removed
-8
@@ -1,8 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- permissions.add(new FilePermission(

-             System.getProperty("user.dir") + "/-", "read"));

- </programlisting>

en-US/snippets/Java-SecurityManager-Privileged.xml
file removed
-19
@@ -1,19 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- // This is expected to fail.

- try {

-     System.out.println(System.getProperty("user.home"));

- } catch (SecurityException e) {

-     e.printStackTrace(System.err);

- }

- AccessController.doPrivileged(new PrivilegedAction&#60;Void&#62;() {

-         public Void run() {

-             // This should work.

-             System.out.println(System.getProperty("user.home"));

-             return null;

-         }

-     });

- </programlisting>

en-US/snippets/Java-SecurityManager-Unprivileged.xml
file removed
-28
@@ -1,28 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- Permissions permissions = new Permissions();

-         ProtectionDomain protectionDomain =

-     new ProtectionDomain(null, permissions);

-         AccessControlContext context = new AccessControlContext(

-             new ProtectionDomain[] { protectionDomain });

- 

- // This is expected to succeed.

- try (FileInputStream in = new FileInputStream(path)) {

-     System.out.format("FileInputStream: %s%n", in);

- }

- 

- AccessController.doPrivileged(new PrivilegedExceptionAction&#60;Void&#62;() {

- 	@Override

-         public Void run() throws Exception {

- 	    // This code runs with reduced privileges and is

- 	    // expected to fail.

- 	    try (FileInputStream in = new FileInputStream(path)) {

- 		System.out.format("FileInputStream: %s%n", in);

- 	    }

- 	    return null;

- 	}

-     }, context);

- </programlisting>

en-US/snippets/Java-TryWithResource.xml
file removed
-9
@@ -1,9 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- try (InputStream in = new BufferedInputStream(new FileInputStream(path))) {

-     readFile(in);

- }

- </programlisting>

en-US/snippets/Shell-Input_Validation.xml
file removed
-12
@@ -1,12 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Bash">

- if [[ $value =~ ^-?[0-9]+$ ]] ; then

- 	echo value is an integer

- else

- 	echo "value is not an integer" 1&#62;&#38;2

- 	exit 1

- fi

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-Expat-Create.xml
file removed
-17
@@ -1,17 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- XML_Parser parser = XML_ParserCreate("UTF-8");

- if (parser == NULL) {

-   fprintf(stderr, "XML_ParserCreate failed\n");

-   close(fd);

-   exit(1);

- }

- // EntityDeclHandler needs a reference to the parser to stop

- // parsing.

- XML_SetUserData(parser, parser);

- // Disable entity processing, to inhibit entity expansion.

- XML_SetEntityDeclHandler(parser, EntityDeclHandler);

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-Expat-EntityDeclHandler.xml
file removed
-16
@@ -1,16 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- // Stop the parser when an entity declaration is encountered.

- static void

- EntityDeclHandler(void *userData,

- 		  const XML_Char *entityName, int is_parameter_entity,

- 		  const XML_Char *value, int value_length,

- 		  const XML_Char *base, const XML_Char *systemId,

- 		  const XML_Char *publicId, const XML_Char *notationName)

- {

-   XML_StopParser((XML_Parser)userData, XML_FALSE);

- }

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-OpenJDK-Errors.xml
file removed
-22
@@ -1,22 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- class Errors implements ErrorHandler {

-     @Override

-     public void warning(SAXParseException exception) {

-         exception.printStackTrace();

-     }

-     

-     @Override

-     public void fatalError(SAXParseException exception) {

-         exception.printStackTrace();

-     }

-     

-     @Override

-     public void error(SAXParseException exception) {

-         exception.printStackTrace();

-     }

- }

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-OpenJDK-Imports.xml
file removed
-27
@@ -1,27 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- import javax.xml.XMLConstants;

- import javax.xml.parsers.DocumentBuilder;

- import javax.xml.parsers.DocumentBuilderFactory;

- import javax.xml.parsers.ParserConfigurationException;

- import javax.xml.parsers.SAXParser;

- import javax.xml.parsers.SAXParserFactory;

- import javax.xml.transform.dom.DOMSource;

- import javax.xml.transform.sax.SAXSource;

- import javax.xml.validation.Schema;

- import javax.xml.validation.SchemaFactory;

- import javax.xml.validation.Validator;

- 

- import org.w3c.dom.Document;

- import org.w3c.dom.ls.LSInput;

- import org.w3c.dom.ls.LSResourceResolver;

- import org.xml.sax.EntityResolver;

- import org.xml.sax.ErrorHandler;

- import org.xml.sax.InputSource;

- import org.xml.sax.SAXException;

- import org.xml.sax.SAXParseException;

- import org.xml.sax.XMLReader;

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-OpenJDK-NoEntityResolver.xml
file removed
-15
@@ -1,15 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- class NoEntityResolver implements EntityResolver {

-     @Override

-     public InputSource resolveEntity(String publicId, String systemId)

-             throws SAXException, IOException {

-         // Throwing an exception stops validation.

-         throw new IOException(String.format(

-                 "attempt to resolve \"%s\" \"%s\"", publicId, systemId));

-     }

- }

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-OpenJDK-NoResourceResolver.xml
file removed
-17
@@ -1,17 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- class NoResourceResolver implements LSResourceResolver {

-     @Override

-     public LSInput resolveResource(String type, String namespaceURI,

-             String publicId, String systemId, String baseURI) {

-         // Throwing an exception stops validation.

-         throw new RuntimeException(String.format(

-                 "resolution attempt: type=%s namespace=%s " +

-                 "publicId=%s systemId=%s baseURI=%s",

-                 type, namespaceURI, publicId, systemId, baseURI));

-     }

- }

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-OpenJDK_Parse-DOM.xml
file removed
-19
@@ -1,19 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

- // Impose restrictions on the complexity of the DTD.

- factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

- 

- // Turn on validation.

- // This step can be omitted if validation is not desired.

- factory.setValidating(true);

- 

- // Parse the document.

- DocumentBuilder builder = factory.newDocumentBuilder();

- builder.setEntityResolver(new NoEntityResolver());

- builder.setErrorHandler(new Errors());

- Document document = builder.parse(inputStream);

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_DOM.xml
file removed
-23
@@ -1,23 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- SchemaFactory factory = SchemaFactory.newInstance(

-         XMLConstants.W3C_XML_SCHEMA_NS_URI);

- 

- // This enables restrictions on schema complexity.

- factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

- 

- // The following line prevents resource resolution

- // by the schema itself.

- factory.setResourceResolver(new NoResourceResolver());

- 

- Schema schema = factory.newSchema(schemaFile);

- 

- Validator validator = schema.newValidator();

- 

- // This prevents external resource resolution.

- validator.setResourceResolver(new NoResourceResolver());

- validator.validate(new DOMSource(document));

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_SAX.xml
file removed
-26
@@ -1,26 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="Java">

- SchemaFactory factory = SchemaFactory.newInstance(

-         XMLConstants.W3C_XML_SCHEMA_NS_URI);

- 

- // This enables restrictions on the schema and document

- // complexity.

- factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

- 

- // This prevents resource resolution by the schema itself.

- // If the schema is trusted and references additional files,

- // this line must be omitted, otherwise loading these files

- // will fail.

- factory.setResourceResolver(new NoResourceResolver());

- 

- Schema schema = factory.newSchema(schemaFile);

- Validator validator = schema.newValidator();

- 

- // This prevents external resource resolution.

- validator.setResourceResolver(new NoResourceResolver());

- 

- validator.validate(new SAXSource(new InputSource(inputStream)));

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-Qt-NoEntityHandler.xml
file removed
-42
@@ -1,42 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- class NoEntityHandler : public QXmlDeclHandler {

- public:

-   bool attributeDecl(const QString&#38;, const QString&#38;, const QString&#38;,

- 		       const QString&#38;, const QString&#38;);

-   bool internalEntityDecl(const QString&#38;, const QString&#38;);

-   bool externalEntityDecl(const QString&#38;, const QString&#38;,

- 			    const QString&#38;);

-   QString errorString() const;

- };

- 

-  bool

- NoEntityHandler::attributeDecl

-   (const QString&#38;, const QString&#38;, const QString&#38;, const QString&#38;,

-    const QString&#38;)

- {

-   return false;

- }

- 

- bool

- NoEntityHandler::internalEntityDecl(const QString&#38;, const QString&#38;)

- {

-   return false;

- }

- 

- bool

- NoEntityHandler::externalEntityDecl(const QString&#38;, const QString&#38;, const

- 				      QString&#38;)

- {

-   return false;

- }

- 

- QString

- NoEntityHandler::errorString() const

- {

-   return "XML declaration not permitted";

- }

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-Qt-NoEntityReader.xml
file removed
-25
@@ -1,25 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- class NoEntityReader : public QXmlSimpleReader {

-   NoEntityHandler handler;

- public:

-   NoEntityReader();

-   void setDeclHandler(QXmlDeclHandler *);

- };

- 

-  NoEntityReader::NoEntityReader()

- {

-   QXmlSimpleReader::setDeclHandler(&#38;handler);

-   setFeature("http://xml.org/sax/features/namespaces", true);

-   setFeature("http://xml.org/sax/features/namespace-prefixes", false);

-  }

- 

- void

- NoEntityReader::setDeclHandler(QXmlDeclHandler *)

- {

-   // Ignore the handler which was passed in.

- }

- </programlisting>

en-US/snippets/Tasks-Serialization-XML-Qt-QDomDocument.xml
file removed
-16
@@ -1,16 +0,0 @@

- <?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="C">

- NoEntityReader reader;

- QBuffer buffer(&#38;data);

- buffer.open(QIODevice::ReadOnly);

- QXmlInputSource source(&#38;buffer);

- QDomDocument doc;

- QString errorMsg;

- int errorLine;

- int errorColumn;

- bool okay = doc.setContent

-   (&#38;source, &#38;reader, &#38;errorMsg, &#38;errorLine, &#38;errorColumn);

- </programlisting>

publican.cfg
file removed
-10
@@ -1,10 +0,0 @@

- xml_lang: en-US

- #brand: RedHat-EngServices

- brand: fedora

- chunk_section_depth: 3

- #product: Defensive_Coding

- #mainfile: Defensive_Coding

- #docname: Defensive_Coding

- web_version_label: UNUSED

- version: 1

- #git_branch: eng-docs-rhel-6

schemas.xml
file removed
-6
@@ -1,6 +0,0 @@

- <?xml version="1.0"?>

- <locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">

-   <documentElement localName="book" uri="docbook-schema/docbook.rnc"/>

-   <documentElement localName="chapter" uri="docbook-schema/docbook.rnc"/>

-   <documentElement localName="section" uri="docbook-schema/docbook.rnc"/>

- </locatingRules>

scripts/split-snippets.py
file modified
+5 -13
@@ -1,6 +1,6 @@

  #!/usr/bin/python

  

- # Split source code files into XML snippets for inclusion in the

+ # Split source code files into markdown snippets for inclusion in the

  # documentation.

  #

  # Usage: python split-snippets.py TARGET-ROOT INPUT-FILE...
@@ -23,7 +23,7 @@

  target_root = sys.argv[1]

  

  def output_file_name(dirname, basename):

-     return "{0}/en-US/snippets/{1}-{2}.xml".format(

+     return "{0}/en-US/snippets/{1}-{2}.adoc".format(

          target_root, dirname, basename)

  

  re_open_file = re.compile(
@@ -41,19 +41,11 @@

  def write_single_file(path, contents, language):

      assert not [ch for ch in language if ch in "<>&\""]

      with file(path, "w") as out:

-         out.write('''<?xml version='1.0' encoding='utf-8' ?>

- <!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

- ]>

- <!-- Automatically generated file.  Do not edit. -->

- <programlisting language="''' + language + '''">

- ''')

+         out.write("\n")

          for line in contents:

              for ch in line:

-                 if ch in "<>&":

-                     out.write("&#{0};".format(ord(ch)))

-                 else:

-                     out.write(ch)

-         out.write("</programlisting>\n")

+                  out.write(ch)

+         out.write("\n")

  

  def write_output(output):

      for (outpath, (origpath, contents)) in output.items():

src/HSM-GNUTLS.c
file added
+100
@@ -0,0 +1,100 @@

+ #include <stdio.h>

+ #include <stdlib.h>

+ #include <stdint.h>

+ #include <string.h>

+ #include <gnutls/gnutls.h>

+ #include <gnutls/abstract.h>

+ #include <gnutls/pkcs11.h>

+ 

+ //+ Features HSM-GNUTLS-PIN

+ int pin_function(void *userdata, int attempt, const char *token_url,

+                  const char *token_label, unsigned flags, char *pin, size_t pin_max)

+ {

+   if (flags & GNUTLS_PIN_FINAL_TRY)

+     printf("This is the final try before locking!\n");

+   if (flags & GNUTLS_PIN_COUNT_LOW)

+     printf("Only few tries left before locking!\n");

+   if (flags & GNUTLS_PIN_WRONG)

+     printf("Wrong PIN has been provided in the previous attempt\n");

+ 

+   /* userdata is the second value passed to gnutls_pkcs11_set_pin_function()

+    * in this example we passed the PIN as a null terminated value.

+    */

+   snprintf(pin, pin_max, "%s", (char*)userdata);

+   return 0;

+ }

+ //-

+ 

+ /* This program accepts on the command line:

+  *  1. A PKCS#11 URL specifying a private key

+  *  2. A PIN

+  *  3. A PKCS#11 shared module (optional)

+  *

+  * And signs test data with the provided key.

+  *

+  * Example: ./a.out "pkcs11:object=myobject" 1234 /usr/lib64/pkcs11/opensc-pkcs11.so

+  */

+ int main(int argc, char **argv)

+ {

+   gnutls_privkey_t private_key;

+   char *private_key_name;

+   char *key_pass = NULL;

+   const char *module_path = NULL;

+   gnutls_datum_t testdata = {(void*)"TESTDATA", sizeof("TESTDATA")-1};

+   gnutls_datum_t signature;

+   int ret;

+ 

+   if (argc < 2) {

+     fprintf(stderr, "usage: %s [private key URL] [PIN] [module]\n", argv[0]);

+     fprintf(stderr, "\n");

+     exit(1);

+   }

+ 

+   private_key_name = argv[1];

+   key_pass = argv[2];

+   if (argc >= 3)

+     module_path = argv[3];

+ 

+   //+ Features HSM-GNUTLS

+   if (module_path) {

+     ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);

+     if (ret < 0) {

+       fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+       exit(1);

+     }

+ 

+     ret = gnutls_pkcs11_add_provider(module_path, NULL);

+     if (ret < 0) {

+       fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+       exit(1);

+     }

+   }

+ 

+   if (key_pass)

+     gnutls_pkcs11_set_pin_function(pin_function, key_pass);

+ 

+   ret = gnutls_privkey_init(&private_key);

+   if (ret < 0) {

+     fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+     exit(1);

+   }

+ 

+   ret = gnutls_privkey_import_url(private_key, private_key_name, 0);

+   if (ret < 0) {

+     fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+     exit(1);

+   }

+ 

+   ret = gnutls_privkey_sign_data(private_key, GNUTLS_DIG_SHA256, 0,

+                                  &testdata, &signature);

+   if (ret < 0) {

+     fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+     exit(1);

+   }

+ 

+   gnutls_privkey_deinit(private_key);

+   gnutls_free(signature.data);

+   //-

+ 

+   return 0;

+ }

src/HSM-NSS.c
file added
+158
@@ -0,0 +1,158 @@

+ /* Example code to illustrate PKI crypto ops (encrypt with public key,

+  * decrypt with private key)

+  *

+  * Code assumes that you have set up a NSS database with a certificate

+  * and a private key. 

+  * Here is one way of doing it:

+  *   # create CA cert db, if -f not provided, prompts for passwd

+  *   $ certutil -N -d .

+  *

+  *   # load your hsm (optional) To do so you need to know where your

+  *   # pkcs #11 module lives. replace {path_to_pkcs11_library} with

+  *   # the actual path and library name (example /usr/lib64/libcoolkeypk11.so

+  *   $ modultil -add "HSM Module" -libfile {path_to_pkcs11_library} -dbdir .

+  *

+  *   # create CA cert, self-signed, generates key-pair, prompts for key

+  *   # type, cert type etc

+  *   # {token_name} is the name of your PKCS #11 token. You can find

+  *   #  the token name using 'modutil --list -dbdir .'. If you are using

+  *   #  softoken you can skip the -h {token_name}

+  *   # answers for prompts: 5,9,n,y,-1,n,5,6,7,9,n

+  *   $ certutil -S -s -h {token_name} \

+  *     "CN=Test CA, O=BOGUS Inc, L=Mtn View, ST=CA, C=US"  \

+  *     -n TestCA -t CTu,CTu,CTu -v 60 -x -d . -1 -2 -5

+  *

+  *   Run the program with "{token_name}:TestCA" as the command line argument.

+  *   You will be prompted for the pin.

+  *

+  * There are many ways to setup a public/private key to use - this

+  * example shows one of them.

+  *

+  * This example does not do any padding. It simply encrypts/decrypts a block

+  * of length equal to modulus length of the public/private key.

+  */

+ 

+ #include <stdio.h>

+ #include <unistd.h>

+ #include <prerror.h>

+ #include <nss.h>

+ #include <nssutil.h>

+ #include <cert.h>

+ #include <cryptohi.h>

+ #include <keyhi.h>

+ #include <pk11pub.h>

+ #include <secoidt.h>

+ 

+ static char *pin = NULL;

+ /* this callback is responsible for returning the password to the NSS

+  * key database. for example purposes, this function hardcodes the password.

+  * In a real app, this function should obtain the password using secure means

+  * such as prompting an operator, or retrieving it over a secure communication

+  * channel

+  */

+ char *passwdcb(PK11SlotInfo * info, PRBool retry, void *arg);

+ 

+ int main(int argc, char **argv)

+ {

+   //+ Features HSM-NSS

+   SECStatus rv;

+   CERTCertificate *cert = NULL;

+   SECKEYPrivateKey *pvtkey = NULL;

+   SECItem signature = { siBuffer, NULL, 0 };

+   SECOidTag algTag;

+   int r = 1;

+   unsigned char buf[] = "test data to sign";

+   const char *cert_name;

+   unsigned i;

+ 

+   if (argc < 3) {

+     fprintf(stderr, "usage: %s [cert name] [PIN]\n\n", argv[0]);

+     exit(1);

+   }

+ 

+   cert_name = argv[1];

+   pin = argv[2];

+ 

+   PK11_SetPasswordFunc(passwdcb);

+   NSS_InitializePRErrorTable();

+   rv = NSS_Init(".");

+   if (rv != SECSuccess) {

+     fprintf(stderr, "NSS initialization failed (err %d)\n", PR_GetError());

+     goto cleanup;

+   }

+ 

+   cert = PK11_FindCertFromNickname(cert_name, NULL);

+   if (cert == NULL) {

+     fprintf(stderr, "Couldn't find cert %s in NSS db (err %d: %s)\n",

+ 	    cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));

+     goto cleanup;

+   }

+ 

+   fprintf(stderr, "Buffer being signed = \n%s\n", buf);

+ 

+   pvtkey = PK11_FindKeyByAnyCert(cert, NULL);

+   if (pvtkey == NULL) {

+     fprintf(stderr, "Couldn't find private key for cert %s (err %d: %s)\n",

+ 	    cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));

+     goto cleanup;

+   }

+ 

+   /* get the algtag. Pick the default hash algorithm */

+   algTag = SEC_GetSignatureAlgorithmOidTag(pvtkey->keyType, SEC_OID_UNKNOWN);

+ 

+   fprintf(stderr, "Signing with alg = %s (%d)\n",

+ 	  SECOID_FindOIDTagDescription(algTag), algTag);

+ 

+   rv = SEC_SignData(&signature, buf, sizeof(buf)-1, pvtkey, algTag);

+   if (rv != SECSuccess) {

+     fprintf(stderr, "sign with Private Key failed (err %d: %s)\n",

+ 	    PR_GetError(), PORT_ErrorToString(PR_GetError()));

+     goto cleanup;

+   }

+   //-

+ 

+   fprintf(stderr, "Signature len = %d\n", signature.len);

+   fprintf(stderr, "Signature data = ");

+   /* dump signature.data */

+   for (i = 0; i < signature.len; i++) {

+     if ((i & 0xf) == 0)

+       printf("\n");

+     printf("%02x ", signature.data[i]);

+   }

+   printf("\n");

+ 

+   r = 0;

+ 

+  cleanup:

+   if (cert)

+     CERT_DestroyCertificate(cert);

+   if (pvtkey)

+     SECKEY_DestroyPrivateKey(pvtkey);

+   if (signature.data)

+     SECITEM_FreeItem(&signature, PR_FALSE);

+   exit(r);

+ }

+ 

+ //+ Features HSM-NSS-PIN

+ char *passwdcb(PK11SlotInfo * slot, PRBool retry, void *arg)

+ {

+   if (!isatty(STDIN_FILENO) && retry) {

+     /* we're just reading from a file, and the value is known to be wrong,

+      * don't keep bounding the token with the wrong password. */

+     return NULL;

+   }

+ 

+   if (retry) {

+     printf("Warning: Wrong PIN has been provided in the previous attempt\n");

+     if (PK11_IsHW(slot)) {

+       printf

+ 	  ("  NOTE: multiple pin failures could result in locking your device\n");

+     }

+   }

+ 

+   if (pin == NULL)

+     return pin;

+   else

+     return strdup(pin);

+ }

+ //-

src/HSM-OpenSSL.c
file added
+129
@@ -0,0 +1,129 @@

+ #include <stdio.h>

+ #include <stdlib.h>

+ #include <stdint.h>

+ #include <stdbool.h>

+ #include <string.h>

+ #include <err.h>

+ #include <arpa/inet.h>

+ #include <openssl/bio.h>

+ #include <openssl/evp.h>

+ #include <openssl/pem.h>

+ #include <openssl/err.h>

+ #include <openssl/engine.h>

+ #include <openssl/conf.h>

+ 

+ static void display_openssl_errors(int l)

+ {

+   const char *file;

+   char buf[120];

+   int e, line;

+ 

+   if (ERR_peek_error() == 0)

+     return;

+   fprintf(stderr, "At %s:%d:\n", __FILE__, l);

+ 

+   while ((e = ERR_get_error_line(&file, &line))) {

+     ERR_error_string(e, buf);

+     fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);

+   }

+ }

+ 

+ /* This program accepts on the command line:

+  *  1. A PKCS#11 URL specifying a private key

+  *  2. A PIN

+  *  3. A PKCS#11 shared module (optional)

+  *

+  * And signs test data with the provided key.

+  *

+  * Example: ./a.out "pkcs11:object=myobject" 1234 /usr/lib64/pkcs11/opensc-pkcs11.so

+  */

+ int main(int argc, char **argv)

+ {

+   char *private_key_name;

+   unsigned char buf[4096];

+   const EVP_MD *digest_algo;

+   EVP_PKEY *private_key;

+   char *key_pass = NULL;

+   unsigned n;

+   ENGINE *e;

+   EVP_MD_CTX ctx;

+   const char *module_path = NULL;

+ 

+   if (argc < 2) {

+     fprintf(stderr, "usage: %s [private key URL] [PIN] [module]\n", argv[0]);

+     fprintf(stderr, "\n");

+     exit(1);

+   }

+ 

+   private_key_name = argv[1];

+   key_pass = argv[2];

+   if (argc >= 3)

+     module_path = argv[3];

+ 

+   //+ Features HSM-OpenSSL

+   OpenSSL_add_all_algorithms();

+   ERR_load_crypto_strings();

+   ERR_clear_error();

+   ENGINE_load_builtin_engines();

+ 

+   e = ENGINE_by_id("pkcs11");

+   if (!e) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   if (module_path) {

+     fprintf(stderr, "loading: %s\n", module_path);

+     if (!ENGINE_ctrl_cmd_string(e, "MODULE_PATH", module_path, 0)) {

+       display_openssl_errors(__LINE__);

+       exit(1);

+     }

+   }

+ 

+   if (!ENGINE_init(e)) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   if (key_pass && !ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL);

+   if (!private_key) {

+     fprintf(stderr, "cannot load: %s\n", private_key_name);

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   display_openssl_errors(__LINE__);

+ 

+   digest_algo = EVP_get_digestbyname("sha256");

+ 

+   EVP_MD_CTX_init(&ctx);

+   if (EVP_DigestInit(&ctx, digest_algo) <= 0) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   EVP_SignInit(&ctx, digest_algo);

+ 

+ #define TEST_DATA "test data"

+   if (EVP_SignUpdate(&ctx, TEST_DATA, sizeof(TEST_DATA) - 1) <= 0) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   n = sizeof(buf);

+   if (EVP_SignFinal(&ctx, buf, &n, private_key) <= 0) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   EVP_PKEY_free(private_key);

+   ENGINE_finish(e);

+   //-

+ 

+   return 0;

+ }

src/TLS-Client-GNUTLS.c
file modified
+10 -39
@@ -84,6 +84,8 @@

    }

  

    //+ Features TLS-GNUTLS-Init

+   // This is only necessary if compatibility with GnuTLS prior to

+   // 3.3.0 is required.

    gnutls_global_init();

    //-

  
@@ -96,19 +98,15 @@

  	    gnutls_strerror(ret));

      exit(1);

    }

-   // gnutls_certificate_set_x509_system_trust needs GNUTLS version 3.0

-   // or newer, so we hard-code the path to the certificate store

-   // instead.

-   static const char ca_bundle[] = "/etc/ssl/certs/ca-bundle.crt";

-   ret = gnutls_certificate_set_x509_trust_file

-     (cred, ca_bundle, GNUTLS_X509_FMT_PEM);

+ 

+   ret = gnutls_certificate_set_x509_system_trust(cred);

    if (ret == 0) {

-     fprintf(stderr, "error: no certificates found in: %s\n", ca_bundle);

+     fprintf(stderr, "error: no certificates found in system trust store\n");

      exit(1);

    }

    if (ret < 0) {

-     fprintf(stderr, "error: gnutls_certificate_set_x509_trust_files(%s): %s\n",

- 	    ca_bundle, gnutls_strerror(ret));

+     fprintf(stderr, "error: gnutls_certificate_set_x509_system_trust: %s\n",

+ 	    gnutls_strerror(ret));

      exit(1);

    }

    //-
@@ -162,7 +160,7 @@

  

    // Associate the socket with the session object and set the server

    // name.

-   gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)(uintptr_t)sockfd);

+   gnutls_transport_set_int(session, sockfd);

    ret = gnutls_server_name_set(session, GNUTLS_NAME_DNS,

  			       host, strlen(host));

    if (ret != GNUTLS_E_SUCCESS) {
@@ -193,9 +191,9 @@

  

    // Validate the certificate chain.

    unsigned status = (unsigned)-1;

-   ret = gnutls_certificate_verify_peers2(session, &status);

+   ret = gnutls_certificate_verify_peers3(session, host, &status);

    if (ret != GNUTLS_E_SUCCESS) {

-     fprintf(stderr, "error: gnutls_certificate_verify_peers2: %s\n",

+     fprintf(stderr, "error: gnutls_certificate_verify_peers3: %s\n",

  	    gnutls_strerror(ret));

      exit(1);

    }
@@ -219,33 +217,6 @@

    }

    //-

  

-   //+ Features TLS-Client-GNUTLS-Match

-   // Match the peer certificate against the host name.

-   // We can only obtain a set of DER-encoded certificates from the

-   // session object, so we have to re-parse the peer certificate into

-   // a certificate object.

-   gnutls_x509_crt_t cert;

-   ret = gnutls_x509_crt_init(&cert);

-   if (ret != GNUTLS_E_SUCCESS) {

-     fprintf(stderr, "error: gnutls_x509_crt_init: %s\n",

- 	    gnutls_strerror(ret));

-     exit(1);

-   }

-   // The peer certificate is the first certificate in the list.

-   ret = gnutls_x509_crt_import(cert, certs, GNUTLS_X509_FMT_DER);

-   if (ret != GNUTLS_E_SUCCESS) {

-     fprintf(stderr, "error: gnutls_x509_crt_import: %s\n",

- 	    gnutls_strerror(ret));

-     exit(1);

-   }

-   ret = gnutls_x509_crt_check_hostname(cert, host);

-   if (ret == 0 && !certificate_host_name_override(certs[0], host)) {

-     fprintf(stderr, "error: host name does not match certificate\n");

-     exit(1);

-   }

-   gnutls_x509_crt_deinit(cert);

-   //-

- 

    //+ Features TLS-GNUTLS-Use

    char buf[4096];

    snprintf(buf, sizeof(buf), "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", host);

src/TLS-Client-NSS.c
file modified
+8
@@ -107,6 +107,14 @@

  

    // Ciphers to enable.

    static const PRUint16 good_ciphers[] = {

+     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,

+     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,

+     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,

+     TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,

+     TLS_RSA_WITH_AES_128_GCM_SHA256,

+     TLS_RSA_WITH_AES_256_GCM_SHA384,

+     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,

+     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,

      TLS_RSA_WITH_AES_128_CBC_SHA,

      TLS_RSA_WITH_AES_256_CBC_SHA,

      SSL_RSA_WITH_3DES_EDE_CBC_SHA,

src/src.mk
file modified
+7 -3
@@ -32,13 +32,17 @@

  # List fiels which will be compiled and linked, together with

  # additional dependencies.

  compile_and_link += C-String-Functions

- compile_and_link += TLS-Client-OpenSSL

+ compile_and_link += TLS-Client-OpenSSL HSM-OpenSSL

  LIBS_TLS-Client-OpenSSL = -lssl -lcrypto

- compile_and_link += TLS-Client-GNUTLS

+ LIBS_HSM-OpenSSL = -lssl -lcrypto

+ compile_and_link += TLS-Client-GNUTLS HSM-GNUTLS

  LIBS_TLS-Client-GNUTLS = -lgnutls

- compile_and_link += TLS-Client-NSS

+ LIBS_HSM-GNUTLS = -lgnutls

+ compile_and_link += TLS-Client-NSS HSM-NSS

  CFLAGS_TLS-Client-NSS = -I/usr/include/nspr4 -I/usr/include/nss3

  LIBS_TLS-Client-NSS = -lnss3 -lnspr4 -lssl3

+ CFLAGS_HSM-NSS = -I/usr/include/nss3 -I/usr/include/nspr4 

+ LIBS_HSM-NSS = -lnss3 -lnspr4 -lssl3 -lnssutil3

  compile_and_link += XML-Parser-Expat

  LIBS_XML-Parser-Expat = -lexpat

  compile_and_link += XML-Parser-Qt

no initial comment

Pull-Request has been closed by bex

6 years ago
Metadata
Changes Summary 159
+30
file added
.gitlab-ci.yml
+7
file added
KNOWN-ISSUES.md
+9 -13
file changed
Makefile
-26
file removed
README
+26
file added
README.md
-3
file removed
docbook-schema/README
-164
file removed
docbook-schema/calstblx.rnc
-1549
file removed
docbook-schema/dbhierx.rnc
-85
file removed
docbook-schema/dbnotnx.rnc
-5785
file removed
docbook-schema/dbpoolx.rnc
-499
file removed
docbook-schema/docbook.rnc
-225
file removed
docbook-schema/htmltblx.rnc
+23
file added
en-US/Author_Group.adoc
-17
file removed
en-US/Author_Group.xml
+18
file added
en-US/Book_Info.adoc
+166
file added
en-US/C-Allocators.adoc
-209
file removed
en-US/C-Allocators.xml
+216
file added
en-US/C-Language.adoc
-221
file removed
en-US/C-Language.xml
+287
file added
en-US/C-Libc.adoc
-352
file removed
en-US/C-Libc.xml
+53
file added
en-US/C-Other.adoc
-70
file removed
en-US/C-Other.xml
+13
file added
en-US/C.adoc
-12
file removed
en-US/C.xml
+133
file added
en-US/CXX-Language.adoc
-188
file removed
en-US/CXX-Language.xml
+190
file added
en-US/CXX-Std.adoc
-202
file removed
en-US/CXX-Std.xml
+9
file added
en-US/CXX.adoc
-10
file removed
en-US/CXX.xml
+23
file added
en-US/Common_Content/Legal_Notice.adoc
+61
file added
en-US/Common_Content/images/title_logo.svg
-2
file removed
en-US/Defensive_Coding.ent
-32
file removed
en-US/Defensive_Coding.xml
+151
file added
en-US/Features-Authentication.adoc
-189
file removed
en-US/Features-Authentication.xml
+179
file added
en-US/Features-HSM.adoc
+944
file added
en-US/Features-TLS.adoc
-1013
file removed
en-US/Features-TLS.xml
+110
file added
en-US/Go.adoc
-110
file removed
en-US/Go.xml
+252
file added
en-US/Java-Language.adoc
-291
file removed
en-US/Java-Language.xml
+141
file added
en-US/Java-LowLevel.adoc
-157
file removed
en-US/Java-LowLevel.xml
+256
file added
en-US/Java-SecurityManager.adoc
-292
file removed
en-US/Java-SecurityManager.xml
+11
file added
en-US/Java.adoc
-11
file removed
en-US/Java.xml
+51
file added
en-US/Python.adoc
-74
file removed
en-US/Python.xml
+60
file added
en-US/Revision_History.adoc
-96
file removed
en-US/Revision_History.xml
+395
file added
en-US/Shell.adoc
-454
file removed
en-US/Shell.xml
+132
file added
en-US/Tasks-Cryptography.adoc
-122
file removed
en-US/Tasks-Cryptography.xml
+216
file added
en-US/Tasks-Descriptors.adoc
-267
file removed
en-US/Tasks-Descriptors.xml
+264
file added
en-US/Tasks-File_System.adoc
-339
file removed
en-US/Tasks-File_System.xml
+151
file added
en-US/Tasks-Library_Design.adoc
-195
file removed
en-US/Tasks-Library_Design.xml
-5
file removed
en-US/Tasks-Locking.xml
+180
file added
en-US/Tasks-Packaging.adoc
-175
file removed
en-US/Tasks-Packaging.xml
+377
file added
en-US/Tasks-Processes.adoc
-483
file removed
en-US/Tasks-Processes.xml
+571
file added
en-US/Tasks-Serialization.adoc
-604
file removed
en-US/Tasks-Serialization.xml
+181
file added
en-US/Tasks-Temporary_Files.adoc
-257
file removed
en-US/Tasks-Temporary_Files.xml
+36
file added
en-US/Vala.adoc
-53
file removed
en-US/Vala.xml
-2118
file removed
en-US/Web_Applications.xml.txt
+6
file added
en-US/entities.adoc
-3936
file removed
en-US/images/icon.svg
+6 -22
file renamed
en-US/Book_Info.xml
en-US/master-docinfo.xml
+54
file added
en-US/master.adoc
-4
file removed
en-US/schemas.xml
-21
file removed
en-US/snippets/C-Arithmetic-add.xml
-17
file removed
en-US/snippets/C-Arithmetic-add_unsigned.xml
-14
file removed
en-US/snippets/C-Arithmetic-mult.xml
-12
file removed
en-US/snippets/C-Globals-String_Array.xml
-49
file removed
en-US/snippets/C-Pointers-remaining.xml
-18
file removed
en-US/snippets/C-String-Functions-format.xml
-14
file removed
en-US/snippets/C-String-Functions-snprintf-incremental.xml
-8
file removed
en-US/snippets/C-String-Functions-snprintf.xml
-8
file removed
en-US/snippets/C-String-Functions-strncat-as-strncpy.xml
-9
file removed
en-US/snippets/C-String-Functions-strncat-emulation.xml
-7
file removed
en-US/snippets/C-String-Functions-strncat-merged.xml
-9
file removed
en-US/snippets/C-String-Functions-strncpy.xml
-50
file removed
en-US/snippets/Features-TLS-Client-GNUTLS-Connect.xml
-29
file removed
en-US/snippets/Features-TLS-Client-GNUTLS-Credentials.xml
-30
file removed
en-US/snippets/Features-TLS-Client-GNUTLS-Match.xml
-42
file removed
en-US/snippets/Features-TLS-Client-GNUTLS-Verify.xml
-15
file removed
en-US/snippets/Features-TLS-Client-NSS-Close.xml
-80
file removed
en-US/snippets/Features-TLS-Client-NSS-Connect.xml
-26
file removed
en-US/snippets/Features-TLS-Client-OpenJDK-Connect.xml
-26
file removed
en-US/snippets/Features-TLS-Client-OpenJDK-Context.xml
-22
file removed
en-US/snippets/Features-TLS-Client-OpenJDK-Context_For_Cert.xml
-7
file removed
en-US/snippets/Features-TLS-Client-OpenJDK-Hostname.xml
-18
file removed
en-US/snippets/Features-TLS-Client-OpenJDK-Import.xml
-38
file removed
en-US/snippets/Features-TLS-Client-OpenJDK-MyTrustManager.xml
-11
file removed
en-US/snippets/Features-TLS-Client-OpenJDK-Use.xml
-71
file removed
en-US/snippets/Features-TLS-Client-OpenSSL-CTX.xml
-55
file removed
en-US/snippets/Features-TLS-Client-OpenSSL-Connect.xml
-15
file removed
en-US/snippets/Features-TLS-Client-OpenSSL-Connection-Use.xml
-13
file removed
en-US/snippets/Features-TLS-Client-OpenSSL-Init.xml
-14
file removed
en-US/snippets/Features-TLS-Client-Python-Connect.xml
-29
file removed
en-US/snippets/Features-TLS-Client-Python-check_host_name.xml
-7
file removed
en-US/snippets/Features-TLS-GNUTLS-Credentials-Close.xml
-14
file removed
en-US/snippets/Features-TLS-GNUTLS-Disconnect.xml
-7
file removed
en-US/snippets/Features-TLS-GNUTLS-Init.xml
-18
file removed
en-US/snippets/Features-TLS-GNUTLS-Use.xml
-8
file removed
en-US/snippets/Features-TLS-NSS-Close.xml
-20
file removed
en-US/snippets/Features-TLS-NSS-Includes.xml
-63
file removed
en-US/snippets/Features-TLS-NSS-Init.xml
-22
file removed
en-US/snippets/Features-TLS-NSS-Use.xml
-12
file removed
en-US/snippets/Features-TLS-Nagle.xml
-27
file removed
en-US/snippets/Features-TLS-OpenJDK-Parameters.xml
-30
file removed
en-US/snippets/Features-TLS-OpenSSL-Connection-Close.xml
-7
file removed
en-US/snippets/Features-TLS-OpenSSL-Context-Close.xml
-31
file removed
en-US/snippets/Features-TLS-OpenSSL-Errors.xml
-7
file removed
en-US/snippets/Features-TLS-Python-Close.xml
-8
file removed
en-US/snippets/Features-TLS-Python-Use.xml
-25
file removed
en-US/snippets/Go-Error_Handling-IO.xml
-23
file removed
en-US/snippets/Go-Error_Handling-Regular.xml
-12
file removed
en-US/snippets/Java-Finally.xml
-36
file removed
en-US/snippets/Java-JNI-Pointers.xml
-39
file removed
en-US/snippets/Java-Language-ReadArray.xml
-40
file removed
en-US/snippets/Java-SecurityManager-Callback.xml
-8
file removed
en-US/snippets/Java-SecurityManager-CurrentDirectory.xml
-19
file removed
en-US/snippets/Java-SecurityManager-Privileged.xml
-28
file removed
en-US/snippets/Java-SecurityManager-Unprivileged.xml
-9
file removed
en-US/snippets/Java-TryWithResource.xml
-12
file removed
en-US/snippets/Shell-Input_Validation.xml
-17
file removed
en-US/snippets/Tasks-Serialization-XML-Expat-Create.xml
-16
file removed
en-US/snippets/Tasks-Serialization-XML-Expat-EntityDeclHandler.xml
-22
file removed
en-US/snippets/Tasks-Serialization-XML-OpenJDK-Errors.xml
-27
file removed
en-US/snippets/Tasks-Serialization-XML-OpenJDK-Imports.xml
-15
file removed
en-US/snippets/Tasks-Serialization-XML-OpenJDK-NoEntityResolver.xml
-17
file removed
en-US/snippets/Tasks-Serialization-XML-OpenJDK-NoResourceResolver.xml
-19
file removed
en-US/snippets/Tasks-Serialization-XML-OpenJDK_Parse-DOM.xml
-23
file removed
en-US/snippets/Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_DOM.xml
-26
file removed
en-US/snippets/Tasks-Serialization-XML-OpenJDK_Parse-XMLSchema_SAX.xml
-42
file removed
en-US/snippets/Tasks-Serialization-XML-Qt-NoEntityHandler.xml
-25
file removed
en-US/snippets/Tasks-Serialization-XML-Qt-NoEntityReader.xml
-16
file removed
en-US/snippets/Tasks-Serialization-XML-Qt-QDomDocument.xml
-10
file removed
publican.cfg
-6
file removed
schemas.xml
+5 -13
file changed
scripts/split-snippets.py
+100
file added
src/HSM-GNUTLS.c
+158
file added
src/HSM-NSS.c
+129
file added
src/HSM-OpenSSL.c
+10 -39
file changed
src/TLS-Client-GNUTLS.c
+8 -0
file changed
src/TLS-Client-NSS.c
+7 -3
file changed
src/src.mk